如何让下游应用通过分支获取Lerna Monorepo组件无需发布至npm
背景场景
我维护一个基于Lerna的Monorepo可视化组件库(包含20个组件),被外部应用通过package.json引入。当前使用Yarn 2+特性,直接从Git分支拉取单个组件:
"@author/component-a": "git+ssh://git@github.server.com:Author/component-lib.git#head=feature/updated-component&workspace=@author/component-a",
我们希望将组件变更推送到GitHub分支即可完成迭代,无需每次发布至npm;同时因为需要 staging 环境基于分支构建,所以不采用yarn link方案。
组件库结构如下:
packages component-a package.json component-b package.json package.json
原component-a/package.json中依赖component-b的配置为版本号:
{ "name": "@author/component-a", "version": "1.1.0-alpha.1", "main": "dist/index.js", "files": ["dist"], "dependencies": { "@author/component-b": "1.1.0-alpha.1" } }
尝试改为本地路径file:../component-b后,组件库本地构建正常,但下游应用从分支拉取时构建失效。
可行解决方案
方案1:使用Git工作空间依赖语法直接指定分支
将component-a/package.json中component-b的依赖改为指向同仓库的目标分支+工作空间,而非版本号或本地路径:
"dependencies": { "@author/component-b": "git+ssh://git@github.server.com:Author/component-lib.git#head=feature/updated-component&workspace=@author/component-b" }
下游应用拉取component-a时,Yarn会自动从指定分支拉取对应的component-b工作空间,无需发布至npm。注意保持分支一致,所有关联组件的变更需推送到同一个分支。
方案2:利用Yarn工作空间协议(推荐)
- 确保组件库根目录的
package.json正确配置工作空间:
{ "workspaces": [ "packages/*" ] }
- 在
component-a/package.json中,使用workspace:*协议引用component-b:
"dependencies": { "@author/component-b": "workspace:*" }
当下游应用通过Yarn的Git工作空间语法拉取component-a时,Yarn会自动解析同仓库内的工作空间依赖,直接从指定分支拉取对应版本的component-b。这种方式无需手动维护Git地址,只需保证分支一致即可同步所有内部依赖。
方案3:预构建并提交dist目录到分支
若上述Yarn特性存在兼容性问题,可在组件库的feature分支中预构建所有组件的dist目录并提交到分支。下游应用拉取时直接获取已构建完成的文件,无需在构建阶段处理依赖。此方案需确保每次代码变更后重新构建并提交dist,适合对构建流程有严格管控的场景。
注意事项
- 下游应用必须使用Yarn 2+版本,因为Git工作空间语法是Yarn 2+的专属特性。
- 所有内部组件的变更需推送到同一个目标分支,避免出现依赖版本不一致的问题。
- 使用
workspace:*协议时,组件库根目录的package.json必须正确配置workspaces字段,否则Yarn无法解析内部依赖。
内容的提问来源于stack exchange,提问作者Richard Fernandez

