用Vite从零搭建Vue3组件库并发布到npm的完整流程。

阿乐
阿乐 管理员 黑卡会员
发布于 2026-09-10 05:40 ·11 浏览 ·0 回复

当你想做个组件库,而不是又写一遍业务代码

前端干久了,总有一种冲动:把常用的按钮、弹窗、表单封装成自己的组件库,放到 npm 上,下次开新项目直接 `npm install` 一把梭。但真到动手时,很多人卡在「怎么搭工程」「怎么出类型」「怎么发布」这三座大山前。Vite 的出现让这件事变得简单得不像话——今天就带你从零到一,走一遍完整流程。

初始化工程,选对构建配置

别用 `vite create` 那种标准模板,因为我们是组件库,不是应用。手动建个目录,`npm init -y` 后装依赖:

npm install vue@3
npm install -D vite @vitejs/plugin-vue vite-plugin-dts

重点是 Vite 的构建配置。组件的入口不能是 `index.html`,而是我们的组件源码。在 `vite.config.ts` 里用 `build.lib` 模式:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'

export default defineConfig({
  plugins: [vue(), dts({ include: ['src'], outDir: 'dist/types' })],
  build: {
    lib: {
      entry: 'src/index.ts',
      name: 'MyUI',
      formats: ['es', 'umd'],
      fileName: (format) => `my-ui.${format}.js`
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: { vue: 'Vue' }
      }
    }
  }
})

把 `vue` 设为 external 至关重要,否则会把整个 Vue 打包进组件库,导致使用方重复加载。`vite-plugin-dts` 负责自动生成 `.d.ts` 类型声明,这才是 Vue3 组件库的硬通货。

组件写得好,但别把样式锁死

组件库的核心不是把代码塞进 `src/components` 就完事。推荐目录结构:

src/
  index.ts       // 统一导出
  button/
    Button.vue
    index.ts
  modal/
    Modal.vue
    index.ts

每个组件的 `index.ts` 里加上 `withInstall` 方法——这是组件库的惯例,让用户既可以用 `<MyButton>`,也可以 `app.use(MyButton)` 全局注册:

import type { App } from 'vue'
import Button from './Button.vue'

Button.install = (app: App) => {
  app.component(Button.name, Button)
}

export default Button as typeof Button & { install: (app: App) => void }

样式方面,建议用 SCSS 变量 + CSS 自定义属性(CSS Variables)双轨制。CSS 变量可以避免用户覆写样式时被深层的 scoped 选择器卡住。不要用 scoped,而是用统一的 BEM 类名前缀,比如 `my-button`、`my-button--primary`。

发布前最后的魔鬼细节

打包完成后,`dist` 目录会生成 ESM 和 UMD 文件,但真正的考验在 `package.json`:

{
  "name": "@yourname/my-ui",
  "version": "0.1.0",
  "main": "dist/my-ui.umd.js",
  "module": "dist/my-ui.es.js",
  "types": "dist/types/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/my-ui.es.js",
      "require": "./dist/my-ui.umd.js",
      "types": "./dist/types/index.d.ts"
    },
    "./style.css": "./dist/my-ui.css"
  },
  "files": ["dist"],
  "peerDependencies": {
    "vue": "^3.2.0"
  }
}

注意 `peerDependencies` 声明 Vue 为同行依赖,`files` 只打包 `dist`,别把源码和 node_modules 一起推上去。`exports` 字段是 Node12+ 和现代打包器解析的入口,写不好会让人无法 import 样式。

样式文件怎么出?Vite 默认会把所有被引用的 CSS 抽成一个 `style.css`。但组件库更讲究「按需加载」,建议在组件内部直接 `import './Button.css'`,再用 `build.cssCodeSplit` 开启代码分割。不过对新手而言,一个全量 CSS 先跑通流程更重要。

验证打包,然后发布

发布前必须做本地验证。在 `dist` 目录同级开个测试项目,用 `npm link` 把组件库链过去,写个 `App.vue` 测试按需注册、全局注册、样式引入。这一步能避免发到 npm 上才发现组件根本渲染不出来——别问我怎么知道的。

一切就绪后,执行:

npm login
npm publish --access public

如果你用的是私有 npm 包名,比如 `@mycompany/ui`,不需要 `--access public`,但公共包必须加。

维护比构建更值得关注

流程跑通了,你会发现自己陷入另一个循环:每次改组件代码都要重新打包、更新版本号、再发布。建议用 `changesets` 管理版本更新,或者在 commit 信息里带 `fix:`, `feat:` 前缀配合 semantic-release 自动发版。组件库不是一次性的任务,而是需要长期维护的工程。

最后提醒一句:component library is easy, component design is hard。别本末倒置,先在业务里沉淀几个反复使用组件,把它们抽出来打磨成真正解决痛点的工具,然后才用上面这套流程交给全世界。Vite 帮你扫清了工具链的障碍,剩下的就看你的审美和对场景的理解了。

本文转载自 阿乐技术社区,原文地址:https://www.leleweb.cn/thread-194.html
转载请注明出处,版权归原作者所有。

全部回复 0

还没有回复,来抢沙发~