如何设计一个 Vue 组件库的发布流程,包括版本管理、ChangeLog 自动化生成和 NPM 发布?

各位观众老爷,大家好!欢迎来到今天的“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/*: 预发布分支,用于准备发布版本。

版本发布的流程:

  1. develop 分支上开发新功能。
  2. 合并 developrelease/* 分支。
  3. release/* 分支上进行最后的测试和调整。
  4. 合并 release/*maindevelop 分支。
  5. main 分支上打 tag,例如 v1.0.0
  6. 发布到 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 规范。

  1. 安装 Commitlint:
npm install --save-dev @commitlint/cli @commitlint/config-conventional
  1. 配置 Commitlint (commitlint.config.js):
module.exports = {
  extends: ['@commitlint/config-conventional']
};
  1. 配置 Husky (Git hooks):
npm install --save-dev husky
  1. 启用 Husky 和 Commitlint:
npx husky install
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'

现在,每次提交代码时,Commitlint 都会检查 commit message 是否符合规范,如果不符合,会阻止提交。

ChangeLog 生成工具:

咱们用 conventional-changelog 来自动生成 ChangeLog。

  1. 安装 conventional-changelog:
npm install --save-dev conventional-changelog-cli
  1. 生成 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。

  1. 安装 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
  1. 配置 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(),
  ],
};
  1. 修改 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:确保你的包是公开的。
  1. 运行 npm run build 打包组件。打包后的文件会输出到 packages 目录。

2. 发布到 NPM:

  1. 确保你已经注册了 NPM 账号,并且在命令行中登录了 NPM:
npm login
  1. 运行 npm run publish 发布组件。

恭喜你,你的组件库已经成功发布到 NPM 了!

第五部分:持续集成与自动化部署

为了让咱们的发布流程更加自动化,可以集成 CI/CD 工具,例如 GitHub Actions。

  1. 在项目根目录下创建 .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 }}
  1. 在 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 组件库。记住,代码的优雅不仅在于它的实现,也在于它的发布方式。

下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注