推荐组合是 pnpm workspace + Lerna(仅用于发布):pnpm 负责依赖管理与本地开发,Lerna 专注语义化版本发布与 changelog 生成,二者协同兼顾效率与规范。

在大型前端项目中,Lerna 和 pnpm workspace 都是管理多包(monorepo)的有效工具,但它们定位不同、适用场景有别。Lerna 更侧重于版本发布与跨包脚本协调,而 pnpm workspace 是包管理器原生支持的 workspace 机制,聚焦依赖安装、符号链接与 hoisting。实践中二者可以共存,也可以单独使用——关键看团队对发布流程、依赖隔离、CI/CD 集成的真实需求。
pnpm workspace:轻量、高效、开箱即用
pnpm 从 v7 开始原生支持 workspace,通过 pnpm-workspace.yaml 声明子包路径,自动创建软链、复用 node_modules、避免重复安装。它不强制约定包名前缀或版本策略,也不内置 publish 流程,但足够稳定、速度快、磁盘占用低。
- 配置简单:只需在根目录放 pnpm-workspace.yaml,写明 packages 路径即可
- 依赖解析准确:基于符号链接 + strict peer resolution,避免“幽灵依赖”
- 支持 pnpm run --recursive 批量执行脚本,如 pnpm build 或 pnpm test
- 与 VS Code、TypeScript、ESLint 等工具天然兼容,无需额外适配
Lerna:适合强发布管控与语义化版本演进
Lerna 的核心价值在于它对 版本管理 和 发布编排 的深度支持。当你的 monorepo 中多个包对外独立发布(比如 UI 组件库、工具函数包、CLI 工具),且需要遵循 semantic versioning、changelog 自动生成、发布前校验、tag 推送等规范时,Lerna 仍是成熟选择。
- 支持 lerna version 自动计算变动包、更新版本号、生成 changelog、提交并打 tag
- 支持 lerna publish 按需发布(canary / fixed / independent 模式)
- 可与 pnpm 共用:把 pnpm 作为 Lerna 的 client(--use-workspaces),由 pnpm 管理依赖,Lerna 专注发布
- 提供 lerna exec 和 lerna run,比原生命令更灵活(如过滤特定包、传参)
推荐组合:pnpm workspace + Lerna(仅用于发布)
这是当前较平衡的实践方式:用 pnpm 管理本地开发体验(安装、链接、构建),用 Lerna 处理对外发布的复杂逻辑。既避免了 Lerna 自带 bootstrap 带来的冗余和性能问题,又保留了语义发布能力。
立即学习“Java免费学习笔记(深入)”;
- 在 lerna.json 中启用 "useWorkspaces": true,让 Lerna 读取 pnpm-workspace.yaml
- 删除 lerna bootstrap,改用 pnpm install 完成依赖链接
- CI 中先运行 pnpm build,再调用 lerna publish --conventional-commits
- 所有包的 package.json 中保持 "private": false(需发布)或 true(仅内部使用)
替代思路:纯 pnpm + 自定义发布脚本
若发布频率低、包间耦合紧、或只部署内部私有 registry,完全可以不用 Lerna。借助 pnpm script + conventional-changelog-cli + jq + npm publish,也能实现自动化发布,代码更透明、维护成本更低。
- 用 pnpm run --recursive --if-present prepack 触发各包构建准备
- 用 conventional-changelog 生成 changelog 并提取最新版本号
- 用 jq 解析各包 package.json,筛选出需发布的包并更新 version
- 逐个 cd packages/x && npm publish(配合 .npmrc 设置 registry)










