Vue3 + Vite 構(gòu)建組件庫(kù)發(fā)布到 npm

你有構(gòu)建完組件庫(kù)后,因?yàn)椴恢廊绾伟l(fā)布到 npm 的煩惱嗎?本教程手把手教你用 Vite 構(gòu)建組件庫(kù)發(fā)布到 npm

搭建項(xiàng)目

  1. 這里我們使用 Vite 初始化項(xiàng)目,執(zhí)行命令:
pnpm create vite my-vue-app --template vue
  1. 這里以我的項(xiàng)目 vue3-xmw-table 為例

調(diào)整目錄結(jié)構(gòu)

  1. 首先需要?jiǎng)?chuàng)建一個(gè) packages 目錄,用來存放組件
  2. src 目錄改為 examples 用作示例
  3. 啟動(dòng)項(xiàng)目的時(shí)候,默認(rèn)入口文件是 src/main.js,將 src 目錄改為 examples 之后,就需要重新配置入口文件,在根目錄下創(chuàng)建一個(gè) vue.config.js 文件
  // vue.config.js
  module.exports = {
    // 將 examples 目錄添加為新的頁(yè)面
    pages: {
      index: {
        // page 的入口
        entry: 'examples/main.ts',
        // 模板來源
        template: 'public/index.html',
        // 輸出文件名
        filename: 'index.html'
      }
    }
  }
  1. 修改根目錄入口文件 index.html 中的 main.ts 引入路勁
  <script type="module" src="/examples/main.ts"></script>
  1. 完整的目錄結(jié)構(gòu)如下:


    fb65f3be7be65554193683aa9b3d71c8.jpg

組件開發(fā)

  1. 之前我們創(chuàng)建的 packages 目錄,用來存放組件

  2. 該目錄下存放每個(gè)組件單獨(dú)的開發(fā)目錄,和一個(gè) index.js 整合所有組件,并對(duì)外導(dǎo)出

  3. 每個(gè)組件都應(yīng)該歸類于單獨(dú)的目錄下,包含其組件源碼目錄 src,和 index.js 便于外部引用

  4. 這里以組件 xmwTable 為例,完整的 packages 目錄結(jié)構(gòu)如下:

    e0dcc2c950b9b76e523f4340e1515c92.jpg

  5. xmwTable/src/main.vue 就是組件的入口文件,這里有一點(diǎn)要非常注意:

需要注意的是,組件必須聲明 name,這個(gè) name 就是組件的標(biāo)簽

<script lang="ts">
  export default {
    name: "vue3-xmw-table", //這個(gè)?常重要,就是未來你放到其他項(xiàng)?中,組件標(biāo)簽的名字,?如:<vue3-xmw-table></vue3-xmw-table>
  };
</script>

整合并導(dǎo)出組件

  1. 編輯 packages/xmwTable/index.ts,實(shí)現(xiàn)組件的導(dǎo)出
// 導(dǎo)入組件,組件必須聲明 name
import XmwTable from './src/main.vue'

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

export default XmwTable
  1. 編輯 packages/index.ts 文件,實(shí)現(xiàn)組件的全局注冊(cè)
// packages / index.js

// 導(dǎo)入單個(gè)組件
import XmwTable from './xmwTable/index'

// 以數(shù)組的結(jié)構(gòu)保存組件,便于遍歷
const components = [
   XmwTable
]

// 定義 install 方法
const install = function (Vue: any) {
   if (install.installed) return
   install.installed = true
   // 遍歷并注冊(cè)全局組件
   components.map(component => {
       Vue.component(component.name, component)
   })
}

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

export default {
   // 導(dǎo)出的對(duì)象必須具備一個(gè) install 方法
   install,
   // 組件列表
   ...components
}

編寫 package.json 文件

  1. package.json 文件里面有很多字段要填寫,否則不能正確發(fā)布。最重要的是以下幾個(gè):
    • name: 包名,該名字是唯一的??稍?npm 官網(wǎng)搜索名字,如果存在則需換個(gè)名字。
    • version: 版本號(hào),不能和歷史版本號(hào)相同。
    • files: 配置需要發(fā)布的文件。
    • main: 入口文件,默認(rèn)為 index.js,這里改為 dist/vue3-xmw-table.umd.js。
    • module: 模塊入口,這里改為 dist/vue3-xmw-table.es.js。
  2. 完整的 package.json 如下:
{
 "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": "baiwumm",
   "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. 因?yàn)榻M件庫(kù)一般都是 jsx 語(yǔ)法編寫,所以要加上 @vitejs/plugin-vue-jsx,打包成 lib,編輯 vite.config.ts
// 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: {
     // 請(qǐng)確保外部化那些你的庫(kù)中不需要的依賴
     external: ['vue'],
     output: {
       // 在 UMD 構(gòu)建模式下為這些外部化的依賴提供一個(gè)全局變量
       globals: {
         vue: 'Vue',
       },
     },
   },
   lib: {
     entry: './packages/index.ts',
     name: 'vue3-table',
   },
 },
})
  1. 執(zhí)行 yarn run build 會(huì)生成 dist 文件夾,里面有以下幾個(gè)文件:
    d9c5e4e2b33342180dd0886418f9c9a3.jpg

本地模擬

  1. 修改文件 main.ts
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 '../dist/vue3-xmw-table.es.js'

createApp(App).use(router).use(ElementPlus).use(XmwTable).mount('#app')
  1. vue3-xmw-table 組件能成功顯示在頁(yè)面,則證明組件的打包是沒問題的。

發(fā)布到 npm

  1. 先查看 npmregistry
npm config get registry
  1. 設(shè)置 npmregistry 為官方源
npm config set registry https://registry.npmjs.org
  1. 執(zhí)行命令 npm login 登錄到 npm
npm login
  1. 執(zhí)行命令 npm publish 發(fā)布到 npm
npm publish

如出現(xiàn)以下信息,則證明包發(fā)布成功:


63450d55b9b35cbb61b824d9f272b293.jpg

注:上傳的 npm 包,在 72小時(shí) 后不可刪除,如果是測(cè)試用的包,記得 72小時(shí) 內(nèi)刪除。

安裝驗(yàn)證

  1. 執(zhí)行命令
npm i vue3-xmw-table
  1. main.ts 引入并注冊(cè)
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')
  1. 頁(yè)面中引用
<!-- 數(shù)據(jù)表格 -->
 <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>

組件正常顯示,恭喜??你,你的包已經(jīng)發(fā)布成功拉,趕緊去使用吧????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容