前言
从创建项目开始,由 0 到 1编写一个 ui 组件并且发布到 npm 上。本组件库可以在 npm 中搜索 vue-zeey-ui 搜索到,完整代码可前往我的 GitHub 仓库:zeey-ui 查看。
使用方法:
- 安装组件:
npm install vue-zeey-ui. - 引入组件:
import { ZButton } from 'vue-zeey-ui'. - 使用组件:
<ZButton>按钮</ZButton>. - 如果样式没有生效,需要在
main.ts中引入vue-zeey-ui/css文件。
1. 创建一个 Vue3 项目
pnpm create vite
2. 创建一个 Vue 组件
首先,我们在 src 中新建一个 packages 文件夹,该文件夹用于存放我们自己封装的组件,我这里封装了一个 Button,该文件的目录结构如下:
其中 button.vue 的部分代码(完整代码可前往我的 GitHub 仓库:zeey-ui 查看):
<template>
<div class="z-button-container">
<div class="wave" :class="type" v-if="showWave"></div>
<button class="z-button" type="button" @click="createWave" :class="type">
<slot>button</slot>
</button>
</div>
</template>
向外导出 button:
// index.ts
import type { App } from 'vue'
import ZButton from "./Button.vue"
// 使用install方法,在app.use挂载
ZButton.install = (app: App) => {
app.component(ZButton.__name as string, ZButton) //注册组件
}
export default ZButton
3. 编写入口文件 index.ts
向外导出我们封装的组件
//index.ts
import type { App } from 'vue';
import ZButton from './Button/index';
// 组件列表
const components = [ZButton];
export { ZButton };
export default {
// 定义 install 方法
install(app: App) {
components.forEach((component) =>
app.component(component.__name as string, component),
);
},
};
4. 编写 vite 配置文件
通过 lib 配置项指定了库的入口文件、名称和文件名。
使用 terser 作为代码压缩工具,并配置了 terserOptions 来移除 console 和 debugger 语句,以及删除注释。。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
base:'/',
build:{
lib:{
entry: path.resolve(__dirname, './src/packages/index.ts'), //指定组件编译入口文件
name: 'vueZeeyUI',
fileName: 'vue-zeey-ui'
},//库编译模式配置
rollupOptions: {
external: ['vue', 'swiper', '@vuepic/vue-datepicker', 'qrcode'],
output: {
// format: 'es', // 默认es,可选 'amd' 'cjs' 'es' 'iife' 'umd' 'system'
exports: 'named',
globals: { //在UMD构建模式下为这些外部化的依赖提供一个全局变量
vue:'Vue',
// 'vue-router': 'VueRouter', // 引入vue-router全局变量,否则router.push将无法使用
swiper: 'Swiper',
'@vuepic/vue-datepicker': 'VueDatePicker',
qrcode: 'qrcode'
}
}
},
/** 设置为 false 可以禁用最小化混淆,或是用来指定使用哪种混淆器。
默认为 Esbuild,它比 terser 快 20-40 倍,压缩率只差 1%-2%。
注意,在 lib 模式下使用 'es' 时,build.minify 选项不会缩减空格,因为会移除掉 pure 标注,导致破坏 tree-shaking。
当设置为 'terser' 时必须先安装 Terser。(yarn add terser -D)
*/
minify: 'terser', // Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效
terserOptions: { // 在打包代码时移除 console、debugger 和 注释
compress: {
/* (default: false) -- Pass true to discard calls to console.* functions.
If you wish to drop a specific function call such as console.info and/or
retain side effects from function arguments after dropping the function
call then use pure_funcs instead
*/
drop_console: true, // 生产环境时移除console
drop_debugger: true
},
format: {
comments: false // 删除注释comments
}
}
}
})
5. 编写 package.json 文件
各部分释义:
"type": 指定模块类型。
"module" 表示使用 ES 模块。
"license": 项目的许可证类型。
"files": 指定发布到 npm 时包含的文件或目录。
"main": 指定包的入口文件,适用于 CommonJS。
"module": 指定包的入口文件,适用于 ES 模块。
"exports": 定义包的导出路径,支持不同的模块格式。
{
"name": "vue-zeey-ui",
"private": false,
"version": "0.2.2",
"author": "Zeey",
"description": "组件发布npm练习",
"type": "module",
"license": "MIT",
"files": [
"dist"
],
"main": "./dist/vue-zeey-ui.umd.cjs",
"module": "./dist/vue-zeey-ui.js",
"exports": {
"./dist/style.css": "./dist/style.css",
"./css": "./dist/style.css",
".": {
"import": "./dist/vue-zeey-ui.js",
"require": "./dist/vue-zeey-ui.umd.cjs"
}
},
"scripts": {
"start": "vite",
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"dayjs": "^1.11.9",
"lodash-es": "^4.17.21",
"vue": "^3.5.12"
},
"devDependencies": {
"@types/node": "^22.8.5",
"@vitejs/plugin-vue": "^5.1.4",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"@vueuse/core": "^11.2.0",
"@vueuse/nuxt": "^11.2.0",
"sass": "^1.64.1",
"terser": "^5.36.0",
"typescript": "~5.6.2",
"vite": "^5.4.10",
"vue-tsc": "^2.1.8"
}
}
6. 本地测试
在这里我们使用软链来进行测试,查看 npm-link 的更多信息。
使用 npm link创建一个全局软链接,接着在其他项目中使用npm link vue-zeey-ui进行使用。需要注意的是vue-zeey-ui对应的是 package.json 中的 name。
在当前项目的根目录下执行:
npm link
在其他项目中执行:
npm link vue-zeey-ui
然后在 main.ts 中引入 css
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import 'vue-zeey-ui/css'
createApp(App).mount('#app')
最后在 vue 文件中使用:
<script setup lang="ts">
import { ZButton } from 'vue-zeey-ui';
</script>
<template>
<div class="button-container">
<strong>Zeey-UI 按钮组件预览:</strong>
<ZButton>Default</ZButton>
<ZButton type="primary">Primary</ZButton>
<ZButton type="tertiary">Tertiary</ZButton>
<ZButton type="info">Info</ZButton>
<ZButton type="success">Success</ZButton>
<ZButton type="warning">Warning</ZButton>
<ZButton type="error">Error</ZButton>
</div>
</template>
运行结果:
7. 打包
命令:pnpm bulid
如果执行 pnpm build 报错,请先执行 yarn add terser -D 安装 Terser。
打包完成后将在根目录下生成dist目录:
8. 发布
首先登录 npm 官网:npm login.
然后发布组件:npm publish.
注意:在每次发布之前需要先切换版本号:npm version x.x.x.
9. 更多
完整代码可前往我的 GitHub 仓库查看。