各位观众老爷,大家好!欢迎来到今天的“Vue 组件库发布一条龙服务”讲座。今天咱们不整虚的,直接上干货,手把手教你如何优雅地发布一个自己的 Vue 组件库,让你的代码也能被千家万户使用。
咱们的目标是:版本管理清晰明了,ChangeLog 自动生成,NPM 发布顺畅无阻。
第一部分:磨刀不误砍柴工 – 项目初始化与结构设计
首先,咱们得有个像样的项目架子。可以用 Vue CLI 或者 Vite 来初始化一个项目,这里为了演示方便,咱们就用 Vue CLI 吧。
vue create my-component-lib
选择 Manually select features,然后选择 Babel, TypeScript, Router, Vuex, CSS Pre-processors, Linter / Formatter 这些选项,或者根据你的实际需求选择。
项目结构建议如下:
my-component-lib/
├── src/
│ ├── components/ # 组件目录
│ │ ├── MyButton/
│ │ │ ├── MyButton.vue
│ │ │ ├── index.ts # 组件导出
│ ├── index.ts # 全局导出
├── packages/ # 打包后的组件
├── examples/ # 组件示例 (可选)
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
├── tsconfig.json
├── vue.config.js
组件示例 (src/components/MyButton/MyButton.vue):
<template>
<button :class="['my-button', type]" @click="$emit('click')">
{{ label }}
</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'MyButton',
props: {
label: {
type: String,
default: 'Button',
},
type: {
type: String,
default: 'default',
validator: (value: string) => ['default', 'primary', 'success', 'warning', 'danger'].includes(value),
},
},
emits: ['click'],
});
</script>
<style scoped>
.my-button {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.default {
background-color: #eee;
color: #333;
}
.primary {
background-color: #409EFF;
color: white;
}
.success {
background-color: #67C23A;
color: white;
}
.warning {
background-color: #E6A23C;
color: white;
}
.danger {
background-color: #F56C6C;
color: white;
}
</style>
组件导出 (src/components/MyButton/index.ts):
import MyButton from './MyButton.vue';
export default MyButton;
全局导出 (src/index.ts):
import MyButton from './components/MyButton';
const components = [
MyButton
];
const install = (app: any) => {
components.forEach(component => {
app.component(component.name, component);
});
};
export {
MyButton
};
export default {
install
};
第二部分:版本控制的艺术 – Git 与 Semantic Versioning
版本控制是咱们发布流程的基石。Git 是咱们的利器,Semantic Versioning (语义化版本) 是咱们的规范。
Semantic Versioning (SemVer) 规则:
版本号 | 含义 |
---|---|
MAJOR | 不兼容的 API 修改,升级后之前的代码可能无法直接运行。 |
MINOR | 添加了新功能,但保持了向后兼容性。 |
PATCH | 修复了 bug,没有改变 API。 |
Git 分支策略:
main
(或master
): 主分支,永远是可发布状态。develop
: 开发分支,用于集成新功能和 bug 修复。feature/*
: 功能分支,用于开发新功能。fix/*
: 修复分支,用于修复 bug。release/*
: 预发布分支,用于准备发布版本。
版本发布的流程:
- 在
develop
分支上开发新功能。 - 合并
develop
到release/*
分支。 - 在
release/*
分支上进行最后的测试和调整。 - 合并
release/*
到main
和develop
分支。 - 在
main
分支上打 tag,例如v1.0.0
。 - 发布到 NPM。
第三部分:ChangeLog 自动化生成 – Conventional Commits 与 Commitlint
手动编写 ChangeLog 简直是噩梦!咱们要用工具来自动化这个过程。Conventional Commits 规范能帮咱们实现这个目标。
Conventional Commits 规范:
<type>(<scope>): <subject>
<body>
<footer>
type
: 提交类型,例如feat
(新功能),fix
(bug 修复),docs
(文档),style
(代码格式),refactor
(重构),perf
(性能优化),test
(测试),build
(构建),ci
(持续集成),chore
(杂项)。scope
: 影响范围,例如MyButton
,core
。subject
: 提交的简短描述。body
: 提交的详细描述。footer
: 例如BREAKING CHANGE
(不兼容的修改)。
示例:
feat(MyButton): 添加了 size 属性
允许用户自定义按钮的大小。
BREAKING CHANGE: 移除旧的按钮样式。
Commitlint:
Commitlint 用于检查 commit message 是否符合 Conventional Commits 规范。
- 安装 Commitlint:
npm install --save-dev @commitlint/cli @commitlint/config-conventional
- 配置 Commitlint (commitlint.config.js):
module.exports = {
extends: ['@commitlint/config-conventional']
};
- 配置 Husky (Git hooks):
npm install --save-dev husky
- 启用 Husky 和 Commitlint:
npx husky install
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'
现在,每次提交代码时,Commitlint 都会检查 commit message 是否符合规范,如果不符合,会阻止提交。
ChangeLog 生成工具:
咱们用 conventional-changelog
来自动生成 ChangeLog。
- 安装
conventional-changelog
:
npm install --save-dev conventional-changelog-cli
- 生成 ChangeLog:
npx conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0
这个命令会根据 Git commit history 生成 CHANGELOG.md
文件。-p conventionalcommits
指定使用 Conventional Commits 预设。-i CHANGELOG.md
指定 ChangeLog 文件名。-s
表示不要在 ChangeLog 头部生成标题。-r 0
表示从头开始生成所有历史记录的ChangeLog。
可以在 package.json
中添加一个脚本来简化 ChangeLog 生成:
{
"scripts": {
"changelog": "conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0"
}
}
然后运行 npm run changelog
即可生成 ChangeLog。
第四部分:NPM 发布 – 打包、配置与发布
终于到了激动人心的发布环节了!
1. 打包组件:
咱们用 Rollup 或者 Webpack 来打包组件。这里咱们用 Rollup。
- 安装 Rollup 及其插件:
npm install --save-dev rollup rollup-plugin-vue rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-node-resolve rollup-plugin-terser vue-template-compiler
- 配置 Rollup (rollup.config.js):
import vue from 'rollup-plugin-vue';
import typescript from 'rollup-plugin-typescript2';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import { compilerOptions } from './tsconfig.json';
import pkg from './package.json';
const banner = `/*!
* ${pkg.name} v${pkg.version}
* (c) 2023-${new Date().getFullYear()} Your Name
* @license MIT
*/`;
export default {
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs',
banner,
exports: 'named',
},
{
file: pkg.module,
format: 'es',
banner,
},
{
file: pkg.unpkg,
format: 'umd',
name: 'MyComponentLib',
globals: {
vue: 'Vue',
},
banner,
},
],
external: ['vue'],
plugins: [
resolve(),
commonjs(),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: true,
},
exclude: ['tests/**/*.ts', 'tests/**/*.tsx'],
},
abortOnError: false,
}),
vue({
css: true,
compileTemplate: true,
}),
terser(),
],
};
- 修改
package.json
:
{
"name": "my-component-lib",
"version": "1.0.0",
"description": "A Vue component library",
"main": "packages/my-component-lib.cjs.js",
"module": "packages/my-component-lib.es.js",
"unpkg": "packages/my-component-lib.umd.js",
"files": [
"packages",
"src/index.ts" // 确保包含声明文件
],
"scripts": {
"build": "rollup -c",
"changelog": "conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0",
"publish": "npm run build && npm publish --access public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/your-username/my-component-lib.git"
},
"keywords": [
"vue",
"component",
"library"
],
"author": "Your Name",
"license": "MIT",
"bugs": {
"url": "https://github.com/your-username/my-component-lib/issues"
},
"homepage": "https://github.com/your-username/my-component-lib#readme",
"peerDependencies": {
"vue": "^3.0.0"
},
"devDependencies": {
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.1.0",
"conventional-changelog-cli": "^3.0.0",
"husky": "^8.0.0",
"rollup": "^2.75.6",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.34.1",
"rollup-plugin-vue": "^6.0.0",
"typescript": "^4.7.3",
"vue": "^3.0.0",
"vue-template-compiler": "^2.6.14"
}
}
main
: CommonJS 格式的入口文件。module
: ES Module 格式的入口文件。unpkg
: UMD 格式的入口文件,用于 CDN 引入。files
: 指定发布到 NPM 的文件。peerDependencies
: 指定组件库依赖的 Vue 版本。scripts.build
: 运行 Rollup 打包。scripts.publish
: 先打包,然后发布到 NPM。--access public
:确保你的包是公开的。
- 运行
npm run build
打包组件。打包后的文件会输出到packages
目录。
2. 发布到 NPM:
- 确保你已经注册了 NPM 账号,并且在命令行中登录了 NPM:
npm login
- 运行
npm run publish
发布组件。
恭喜你,你的组件库已经成功发布到 NPM 了!
第五部分:持续集成与自动化部署
为了让咱们的发布流程更加自动化,可以集成 CI/CD 工具,例如 GitHub Actions。
- 在项目根目录下创建
.github/workflows/release.yml
文件:
name: Release
on:
push:
tags:
- 'v*.*.*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Generate Changelog
run: npm run changelog
- name: Publish to NPM
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- 在 GitHub 项目的 Settings -> Secrets 中添加
NPM_TOKEN
环境变量,值为你的 NPM token。
现在,每次你 push 一个 tag 到 GitHub,例如 v1.0.0
,GitHub Actions 就会自动构建、生成 ChangeLog 并发布到 NPM。
总结
咱们今天学习了如何设计一个 Vue 组件库的发布流程,包括版本管理、ChangeLog 自动化生成和 NPM 发布。
步骤 | 工具/规范 | 作用 |
---|---|---|
项目初始化 | Vue CLI / Vite | 创建项目骨架 |
版本控制 | Git, SemVer | 管理代码版本,保持版本号的语义化 |
ChangeLog 自动化生成 | Conventional Commits, Commitlint, conventional-changelog | 规范 commit message,自动生成 ChangeLog |
NPM 发布 | Rollup / Webpack | 打包组件,发布到 NPM |
持续集成 | GitHub Actions | 自动化构建、测试和发布 |
希望今天的讲座能帮助你更好地管理和发布你的 Vue 组件库。记住,代码的优雅不仅在于它的实现,也在于它的发布方式。
下次再见!