你有构建完组件库后,因为不知道如何发布到 npm 的烦恼吗?本教程手把手教你用 Vite 构建组件库发布到 npm

使用 vue-cli 创建 vue3+vite 项目

1
2
3
4
5
6
## 安装或升级脚手架
yarn install -g @vue/cli
## 确保 vue-cli 版本在 4.5.0 以上
vue -V
## 创建项目
vue create Hellow-World

这里以我的项目 vue3-xmw-table 为例

调整目录结构

  1. 首先需要创建一个 packages 目录,用来存放组件

  2. 将 src 目录改为 examples 用作示例

  3. 启动项目的时候,默认入口文件是 src/main.js,将 src 目录改为 examples 之后,就需要重新配置入口文件,在根目录下创建一个 vue.config.js 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // vue.config.js
    module.exports = {
    // 将 examples 目录添加为新的页面
    pages: {
    index: {
    // page 的入口
    entry: 'examples/main.ts',
    // 模板来源
    template: 'public/index.html',
    // 输出文件名
    filename: 'index.html'
    }
    }
    }
  4. 修改根目录入口文件 index.html 中的 main.ts 引入路劲

    1
    <script type="module" src="/examples/main.ts"></script>
  5. 完整的目录结构如下:

1655194911229.jpg

组件开发

  1. 之前我们创建的 packages 目录,用来存放组件

  2. 该目录下存放每个组件单独的开发目录,和一个 index.js 整合所有组件,并对外导出

  3. 每个组件都应该归类于单独的目录下,包含其组件源码目录 src,和 index.js 便于外部引用

  4. 这里以组件 xmwTable 为例,完整的 packages 目录结构如下:

1655193853485.jpg

  1. xmwTable/src/main.vue 就是组件的入口文件,这里有一点要非常注意:

需要注意的是,组件必须声明 name,这个 name 就是组件的标签

1
2
3
4
5
<script lang="ts">
export default {
name: "vue3-xmw-table", //这个⾮常重要,就是未来你放到其他项⽬中,组件标签的名字,⽐如:<vue3-xmw-table></vue3-xmw-table>
};
</script>

整合并导出组件

  1. 编辑 packages/xmwTable/index.ts,实现组件的导出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 导入组件,组件必须声明 name
    import XmwTable from './src/main.vue'

    // 为组件添加 install 方法,用于按需引入
    XmwTable.install = function (Vue: any) {
    Vue.component(XmwTable.name, XmwTable)
    }

    export default XmwTable
  2. 编辑 packages/index.Ts 文件,实现组件的全局注册

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // packages / index.js

    // 导入单个组件
    import XmwTable from './xmwTable/index'

    // 以数组的结构保存组件,便于遍历
    const components = [
    XmwTable
    ]

    // 定义 install 方法
    const install = function (Vue: any) {
    if (install.installed) return
    install.installed = true
    // 遍历并注册全局组件
    components.map(component => {
    Vue.component(component.name, component)
    })
    }

    if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
    }

    export default {
    // 导出的对象必须具备一个 install 方法
    install,
    // 组件列表
    ...components
    }

编写 package.json 文件

  1. package.json 文件里面有很多字段要填写,否则不能正确发布。最重要的是以下几个:

    • name: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。
    • version: 版本号,不能和历史版本号相同。
    • files: 配置需要发布的文件。
    • main: 入口文件,默认为 index.js,这里改为 dist/vue3-xmw-table.umd.js。
    • module: 模块入口,这里改为 dist/vue3-xmw-table.es.js。
  2. 完整的 package.json 如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    {
    "name": "vue3-xmw-table",
    "version": "1.1.2",
    "main": "dist/vue3-xmw-table.umd.js",
    "module": "dist/vue3-xmw-table.es.js",
    "types": "vue3-xmw-table.d.ts",
    "files": [
    "dist/*",
    "vue3-xmw-table.d.ts"
    ],
    "private": false,
    "author": {
    "name": "Cyan",
    "email": "843348394@qq.com"
    },
    "license": "ISC",
    "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
    },
    "dependencies": {
    "@types/node": "^17.0.6",
    "element-plus": "^1.3.0-beta.1",
    "vue": "^3.2.26",
    "vue-router": "^4.0.12"
    },
    "devDependencies": {
    "@vitejs/plugin-vue": "^2.0.0",
    "@vitejs/plugin-vue-jsx": "^1.3.10",
    "@vue/compiler-sfc": "^3.1.4",
    "eslint": "^8.6.0",
    "eslint-plugin-vue": "^8.2.0",
    "sass": "^1.45.2",
    "sass-loader": "^12.4.0",
    "typescript": "^4.4.4",
    "vite": "^2.7.2",
    "vue-tsc": "^0.29.8"
    }
    }

vite 打包配置

  1. 因为组件库一般都是 jsx 语法编写,所以要加上 @vitejs/plugin-vue-jsx,打包成 lib,编辑 vite.config.ts:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // filename: vite.config.ts
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'

    // https://vitejs.dev/config/
    export default defineConfig({
    plugins: [vue(), vueJsx({})],
    build: {
    rollupOptions: {
    // 请确保外部化那些你的库中不需要的依赖
    external: ['vue'],
    output: {
    // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
    globals: {
    vue: 'Vue',
    },
    },
    },
    lib: {
    entry: './packages/index.ts',
    name: 'vue3-table',
    },
    },
    })
  2. 执行 yarn run build 会生成 dist 文件夹,里面有以下几个文件:

1655194792674.jpg

本地模拟

  1. 修改文件 main.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    - import XmwTable from '../packages/index'; // 全局挂在table组件
    + import XmwTable from '../dist/vue3-xmw-table.es.js'

    createApp(App).use(router).use(ElementPlus).use(XmwTable).mount('#app')
  2. 若 vue3-xmw-table 组件能成功显示在页面,则证明组件的打包是没问题的。

发布到 npm

  1. 先查看 npm 的 registry

    1
    npm config get registry
  2. 设置 npm 的 registry 为官方源

    1
    npm config set registry https://registry.npmjs.org
  3. 执行命令 npm login 登录到 npm

    1
    npm login

1655195963153.jpg

  1. 执行命令 npm publish 发布到 npm
    1
    npm publish

如出现以下信息,则证明包发布成功:

1655195989695.jpg

注:上传的 npm 包,在 72小时 后不可删除,如果是测试用的包,记得 72小时 内删除。

安装验证

  1. 执行 npm i vue3-xmw-table 命令

    1
    npm i vue3-xmw-table
  2. 在 main.ts 引入并注册

    1
    2
    3
    4
    5
    6
    7
    8
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import Xmwtable from 'vue3-xmw-table'

    createApp(App).use(router).use(ElementPlus).use(Xmwtable).mount('#app')
  3. 页面中引用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!-- 数据表格 -->
    <vue3-xmw-table
    stripe
    border
    show-summary
    :summary-method="getSummaries"
    :tableData="state.tableData"
    :loading="state.loading"
    :columns="state.firstLoad ? firstColumns : state.tableColumns"
    :tableConfig="tableConfig"
    :showPagination="false"
    style="margin-top: 20px"
    :span-method="objectSpanMethod"
    >
    <template v-slot:handler="{ scope }">
    <el-button
    size="small"
    type="primary"
    @click="
    scope.$index == state.tableData.length - 1
    ? hanglerEditSpending(scope)
    : handlerEdit(scope)
    "
    >编辑</el-button
    >
    <el-button
    type="danger"
    size="small"
    @click="handlerDelect(scope)"
    :disabled="scope.$index == state.tableData.length - 1"
    >删除</el-button
    >
    </template>
    </vue3-xmw-table>
  4. 组件正常显示,恭喜💐你,你的包已经发布成功拉,赶紧去使用吧🎉🎉