Skip to content

组件库打包和上架

  • 我这里是新创建了一个项目,没用之前的项目

1.创建项目

bash
npm create vite@latest

项目架构

  • 删除多余 比如 App.vue,main.ts,public,assets 之类的
bash

├── src
   ├── button
   ├── index.ts
   ├── index.vue
   ├── styles
      ├── index.scss
      ├── index.ts
      ├── index.ts
   ├── components
   ├── index.ts
   ├── style.ts
├── .editorconfig
├── .eslintrc.ts
├── .gitignore
├── .prettierrc.cjs
├── env.d.ts
├── index.html
├── package.json
├── pnpm-lock.yaml
├── README.md
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.js

src 目录

src/button/index.vue

vue
<script setup lang="ts">
defineOptions({
  name: "LButton",
});
const handleClick = () => {
  window.alert("button clicked");
};
</script>

<template>
  <button @click="handleClick">惦记我</button>
</template>

<style scoped></style>

src/button/index.ts

ts
import Button from "./index.vue";

import type { App, Plugin } from "vue";

// 按需引入

Button.install = (app: App) => {
  app.component(Button.name as string, Button);
  return app;
};

export default Button as typeof Button & Plugin;

src/components.ts

  • 这里面YJButton 是我自定义的组件名称 也就是以后你要引入的组件名称
ts
export { default as YJButton } from "./button";

src/index.ts

ts
import type { App } from "vue";
import * as components from "./components";

export * from "./components";

export default {
  install(app: App) {
    for (const component in components) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-expect-error
      const Comp = components[component];
      if (Comp.install) app.use(Comp);
    }
    return app;
  },
};

src/style.ts

ts
import "./button/style";

vite.config.ts

  • 这里一定安装vite-plugin-dts@1.4.1版本
ts
pnpm add vite-plugin-dts@1.4.1 -D
  • vite.config.ts 代码
ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
export default defineConfig({
  build: {
    // 不压缩
    minify: false,
    rollupOptions: {
      //忽略打包vue文件
      external: ["vue"],
      // 入口文件
      input: ["./src/index.ts"],
      output: [
        {
          //打包格式
          format: "es",
          //打包后文件名
          entryFileNames: "[name].mjs",
          //让打包目录和我们目录对应
          preserveModules: true,
          exports: "named",
          //配置打包根目录
          dir: "./dist/es",
        },
        {
          //打包格式
          format: "cjs",
          //打包后文件名
          entryFileNames: "[name].js",
          //让打包目录和我们目录对应
          preserveModules: true,
          exports: "named",
          //配置打包根目录
          dir: "./dist/lib",
        },
      ],
    },
    lib: {
      entry: "./src/index.ts", // 你的入口文件
    },
  },
  plugins: [
    vue(),
    dts({
      entryRoot: "src",
      outputDir: ["./dist/es", "./dist/lib"],
      //指定使用的tsconfig.json为我们整个项目根目录下,如果不配置,你也可以在components下新建tsconfig.json
      tsConfigFilePath: "./tsconfig.json",
    }),
  ],
});

package.json

json
{
  "name": "yjtest_component_button_3",
  "version": "0.0.0",
  "types": "dist/lib/index.d.ts",
  "main": "dist/lib/index.js",
  "module": "dist/es/index.mjs",
  "files": ["dist/es", "dist/lib"],
  "keywords": ["测试打包组件库"],
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.24"
  },
  "devDependencies": {
    "@types/node": "^24.10.1",
    "@vitejs/plugin-vue": "^6.0.1",
    "@vue/tsconfig": "^0.8.1",
    "typescript": "~5.9.3",
    "unplugin-vue-define-options": "^3.1.2",
    "vite": "^7.2.4",
    "vite-plugin-dts": "1.4.1",
    "vue-tsc": "^3.1.4"
  }
}

上架

  • 切换到正常的npm 源
bash

npm config set registry https://registry.npmjs.org/
  • 这里我使用的是 npm
bash
npm login
  • 这里我使用的是 npm
bash
npm publish

使用

bash
npm i yjtest_component_button_3
  • 导入引用
vue
<script setup lang="ts">
import { YJButton } from "yjtest_component_button_3";
</script>

<template>
  <YJButton />
</template>

<style scoped></style>