前言
开发工作流是 Monorepo 项目中的关键环节。如何高效地进行本地开发,如何调试跨包代码,如何管理代码规范,如何发布包到 npm,是每个 Monorepo 项目必须解决的问题。
本文以 Vue Ace Admin 项目为例,详细介绍 Monorepo 中的开发工作流实践。
如果你还不熟悉 Monorepo 基础配置,建议先阅读:
本地开发流程
workspace 协议的工作原理
在本地开发时,主应用通过 workspace:* 直接使用源码:
// package.json
{
"dependencies": {
"@codexlin/ace-admin-hooks": "workspace:*",
"@codexlin/ace-admin-ui": "workspace:*"
}
}
pnpm 自动创建符号链接:
node_modules/@codexlin/ace-admin-hooks -> packages/hooks
node_modules/@codexlin/ace-admin-ui -> packages/ui
优势:
- ✅ 直接使用源码,修改立即生效
- ✅ 无需构建,开发效率高
- ✅ 完整的 TypeScript 类型支持
- ✅ Vite HMR 自动热更新
开发工作流示例
场景:修改 ProTable 组件
-
修改包代码
typescript// packages/ui/src/pro-table/ProTable.vue // 添加新功能或修复 bug -
主应用自动更新
- Vite HMR 检测到文件变更
- 自动重新编译
- 浏览器自动刷新
- 无需手动操作
-
类型检查
- TypeScript 直接从源码读取类型
- IDE 提供完整的类型提示
- 类型错误立即显示
开发命令
# 启动主应用开发服务器
pnpm dev
# 开发 UI 包(watch 模式)
pnpm dev:ui
# 开发文档站点
pnpm dev:docs
并行开发:
# 终端 1:开发主应用
pnpm dev
# 终端 2:开发 UI 包
pnpm dev:ui
# 修改 UI 包代码,主应用自动更新
调试技巧
1. 查看包链接状态
# 查看 workspace 包链接
pnpm list @codexlin/ace-admin-ui
# 输出示例:
# @codexlin/ace-admin-ui 0.3.0
# └── workspace:packages/ui
2. 重新链接包
如果包链接出现问题:
# 重新安装依赖
pnpm install
# 或删除 node_modules 重新安装
rm -rf node_modules
pnpm install
3. 调试包代码
使用 VS Code 调试:
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Debug Vue App",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/src",
"sourceMaps": true
}
]
}
在包代码中打断点:
- 直接在
packages/ui/src/中打断点 - 调试器会自动映射到源码
- 支持单步调试和变量查看
4. 类型检查
# 检查所有包的类型
pnpm type-check
# 检查特定包
cd packages/ui
pnpm type-check
代码规范管理
ESLint 配置
根目录 ESLint 配置:
// eslint.config.ts
import { defineConfig } from 'eslint-define-config'
export default defineConfig({
root: true,
extends: [
'plugin:vue/vue3-recommended',
'@vue/typescript/recommended'
],
rules: {
// 统一规则
}
})
所有包共享配置:
- 统一的代码风格
- 统一的错误检查
- 统一的格式化规则
Prettier 配置
.prettierrc.json:
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
格式化命令:
# 格式化所有代码
pnpm format
# 格式化特定包
pnpm -C packages/ui format
Git Hooks
使用 simple-git-hooks:
{
"simple-git-hooks": {
"pre-commit": "npx lint-staged",
"commit-msg": "npx commitlint -e $1"
}
}
lint-staged 配置:
{
"lint-staged": {
"src/**/*.{ts,vue}": [
"eslint --fix",
"prettier --write"
]
}
}
工作流程:
- 提交代码前自动运行 lint-staged
- 只检查暂存的文件
- 自动修复可修复的问题
- 提交信息必须符合规范
Git 工作流
分支策略
主分支:
main:生产环境代码develop:开发环境代码
功能分支:
feat/xxx:新功能fix/xxx:bug 修复refactor/xxx:重构
提交规范
使用 Conventional Commits:
# 新功能
git commit -m "feat(ui): 添加 ProTable 排序功能"
# Bug 修复
git commit -m "fix(hooks): 修复 useList 分页问题"
# 文档更新
git commit -m "docs: 更新 README"
# 重构
git commit -m "refactor(ui): 重构 ProButton 组件"
提交格式:
<type>(<scope>): <subject>
<body>
<footer>
类型说明:
feat:新功能fix:bug 修复docs:文档更新style:代码格式refactor:重构test:测试chore:构建/工具
代码审查流程
-
创建功能分支
bashgit checkout -b feat/new-feature -
开发并提交
bashgit add . git commit -m "feat: 新功能" git push origin feat/new-feature -
创建 Pull Request
- 描述变更内容
- 关联相关 Issue
- 等待代码审查
-
合并到主分支
- 通过审查后合并
- 自动触发 CI/CD
npm 发布流程
发布前准备
1. 更新版本号
# 使用 npm version
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.0
2. 构建包
# 构建 hooks 包
pnpm build:hooks
# 构建 UI 包
pnpm build:ui
3. 检查构建产物
# 检查 dist 目录
ls packages/ui/dist/
# 应该包含:
# - ace-admin-ui.es.js
# - ace-admin-ui.umd.js
# - ace-admin-ui.css
# - types/
发布到 npm
1. 登录 npm
npm login
2. 发布包
# 发布 hooks 包
cd packages/hooks
pnpm publish
# 发布 UI 包
cd packages/ui
pnpm publish
3. 验证发布
# 检查 npm 上的包
npm view @codexlin/ace-admin-ui
# 安装测试
pnpm add @codexlin/ace-admin-ui@latest
自动化发布脚本
发布脚本示例:
// scripts/publish.js
import { execSync } from 'child_process'
const packages = ['hooks', 'ui']
packages.forEach(pkg => {
console.log(`Building ${pkg}...`)
execSync(`pnpm -C packages/${pkg} build`, { stdio: 'inherit' })
console.log(`Publishing ${pkg}...`)
execSync(`pnpm -C packages/${pkg} publish`, { stdio: 'inherit' })
})
使用方式:
node scripts/publish.js
实际开发场景
场景一:添加新 Hook
步骤:
-
创建 Hook 文件
typescript// packages/hooks/src/useNewHook.ts export function useNewHook() { // 实现逻辑 } -
导出 Hook
typescript// packages/hooks/src/index.ts export { useNewHook } from './useNewHook' -
在主应用中使用
typescript// src/views/SomeView.vue import { useNewHook } from '@codexlin/ace-admin-hooks' const { ... } = useNewHook() -
立即生效
- Vite HMR 自动更新
- 无需重新构建
场景二:修改 UI 组件
步骤:
-
修改组件代码
vue<!-- packages/ui/src/pro-table/ProTable.vue --> <template> <!-- 修改模板 --> </template> -
更新类型定义
typescript// packages/ui/src/pro-table/type.ts export interface ProTableProps { // 更新类型 } -
主应用自动更新
- 组件变更立即反映
- 类型错误立即显示
场景三:跨包调试
问题: UI 包使用 hooks 包,如何调试?
解决方案:
-
在 hooks 包打断点
typescript// packages/hooks/src/useList.ts export function useList() { debugger // 断点 // ... } -
在 UI 包调用
typescript// packages/ui/src/pro-table/ProTable.vue import { useList } from '@codexlin/ace-admin-hooks' const { ... } = useList() // 会触发 hooks 包的断点 -
调试器自动映射
- 支持跨包调试
- 完整的调用栈
CI/CD 集成
GitHub Actions 示例
.github/workflows/ci.yml:
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 10.14.0
- uses: actions/setup-node@v3
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm type-check
- run: pnpm lint
- run: pnpm build
自动发布流程
name: Publish
on:
push:
tags:
- 'packages/ui/v*'
- 'packages/hooks/v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
- run: pnpm install
- run: pnpm build
- run: pnpm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
最佳实践总结
1. 开发流程
- ✅ 使用
workspace:*进行本地开发 - ✅ 利用 Vite HMR 实现热更新
- ✅ 使用 TypeScript 进行类型检查
- ✅ 定期运行 lint 和 format
2. 调试技巧
- ✅ 使用 VS Code 调试器
- ✅ 在源码中打断点
- ✅ 利用浏览器 DevTools
- ✅ 查看包链接状态
3. 代码规范
- ✅ 统一的 ESLint 配置
- ✅ 统一的 Prettier 配置
- ✅ 使用 Git Hooks 自动检查
- ✅ 遵循提交规范
4. 发布流程
- ✅ 更新版本号
- ✅ 构建包
- ✅ 检查构建产物
- ✅ 发布到 npm
- ✅ 验证发布结果
常见问题与解决方案
Q1: 修改包代码后主应用不更新
问题: 修改了包代码,但主应用没有更新
解决方案:
-
检查包链接
bashpnpm list @codexlin/ace-admin-ui -
重启开发服务器
bash# 停止当前服务器 # 重新启动 pnpm dev -
清除缓存
bashrm -rf node_modules/.vite pnpm dev
Q2: 类型错误但代码能运行
问题: TypeScript 报错,但代码能正常运行
解决方案:
- 检查 tsconfig.json 配置
- 确保类型文件已生成
bash
pnpm build:hooks pnpm build:ui - 重启 TypeScript 服务器(VS Code)
Q3: 发布失败
问题: npm publish 失败
解决方案:
-
检查登录状态
bashnpm whoami -
检查包名是否已存在
bashnpm view @codexlin/ace-admin-ui -
检查版本号
bash# 确保版本号递增 npm version patch
总结
Monorepo 的开发工作流需要综合考虑多个方面:
- 本地开发:利用 workspace 协议实现源码链接
- 调试技巧:使用现代工具进行跨包调试
- 代码规范:统一的工具链和规范
- 发布流程:标准化的发布流程和自动化
通过合理的工作流配置,可以实现:
- ✅ 高效的开发体验
- ✅ 快速的调试流程
- ✅ 统一的代码质量
- ✅ 自动化的发布流程
如果你对 Vue 3 企业级工程实践 感兴趣,可以查看我们的 架构实践分类 下的其他文章。