
本文介绍如何在 yarn workspace + lerna(或 lerna-lite)项目中,不修改源码导入路径的前提下,将多个本地包(如 main-pack 和 sub-pack)以 @myorg/xxx 形式独立发布到 npm,同时确保包间引用始终指向本地 fork 版本而非官方版本。
本文介绍如何在 yarn workspace + lerna(或 lerna-lite)项目中,不修改源码导入路径的前提下,将多个本地包(如 main-pack 和 sub-pack)以 @myorg/xxx 形式独立发布到 npm,同时确保包间引用始终指向本地 fork 版本而非官方版本。
在现代前端单体仓库(monorepo)实践中,Yarn Workspace 与 Lerna(或轻量替代品 Lerna-Lite)的组合常用于管理多包协作。但当需要 Fork 官方仓库并以自有组织命名空间(如 @myorg/main-pack)发布补丁时,一个典型痛点浮现:既要保持 main-pack 中 import { ... } from 'sub-pack' 的原始写法不变,又要确保构建/发布时它解析并打包的是你 fork 后的 @myorg/sub-pack,而非上游 sub-pack 的 npm 版本。
直接将 dependencies 中的 "sub-pack": "*" 替换为 "sub-pack": "npm:@myorg/sub-pack@^1.2.3" 是不可行的——Yarn Workspace 会优先匹配本地 workspace 协议,而 npm: 前缀会绕过 workspace 解析,导致类型检查失败、TS 编译报错,甚至运行时模块缺失。
✅ 正确解法:使用 workspace:* 协议(Yarn v3.1+ / pnpm 原生支持,Lerna-Lite v4+ 及新版 Lerna 均兼容)
该协议明确告诉包管理器:“此处依赖应严格从当前 workspace 中解析,忽略 npm registry”,既保留了本地开发的无缝链接,又为后续发布铺平道路。只需两步:
1. 统一更新 workspace 引用协议
在 main-pack/package.json 的 dependencies(或 devDependencies)中,将原:
"sub-pack": "*"
替换为:
"sub-pack": "workspace:*"
✅ 效果:TypeScript 仍能正常解析 sub-pack 模块(因 tsc 通过 node_modules/sub-pack 软链指向本地源码),yarn build 也基于本地代码编译;且 yarn install 不再尝试拉取远端 sub-pack。
2. 配置 Lerna/Lerna-Lite 发布策略
确保 lerna.json 或 lerna-lite.config.json 中启用 --publish-registry 并设置组织前缀:
{
"version": "independent",
"npmClient": "yarn",
"publish": {
"registry": "https://registry.npmjs.org/",
"access": "public",
"conventionalCommits": true
},
"packages": ["packages/*"]
}执行发布命令时,显式指定组织命名空间:
# 使用 Lerna-Lite(推荐,更轻量、对 workspace:* 支持更完善) npx lerna-lite publish --yes --registry https://registry.npmjs.org/ --no-git-tag-version # 或使用新版 Lerna(v7.0+) npx lerna publish --yes --registry https://registry.npmjs.org/
Lerna-Lite 会自动识别 workspace:* 依赖,并在发布 @myorg/main-pack 前,先发布 @myorg/sub-pack,同时将 main-pack 的 package.json 中 "sub-pack": "workspace:*" 重写为 "sub-pack": "^1.0.1"(对应发布的 @myorg/sub-pack 精确版本),确保消费者安装时获取正确依赖。
⚠️ 关键注意事项
- 不要手动修改 main-pack 中的 import 语句:import { foo } from 'sub-pack' 必须保留原样。workspace:* + TypeScript 的 paths 或 references 配合 composite: true(若启用)可保障类型推导无误。
- 验证发布后结构:发布完成后,前往 https://www.npmjs.com/package/@myorg/main-pack 查看其 dependencies 字段,确认已变为 "sub-pack": "^x.y.z"(而非 workspace:* 或 *)。
- CI/CD 环境需授权:确保 CI 流水线中配置了 NPM_TOKEN 并登录 npm login --scope=@myorg --registry=https://registry.npmjs.org/。
- 避免混用协议:切勿在同一个 workspace 中对同一包同时使用 *、workspace:* 和 npm:@myorg/xxx,易引发解析冲突。
通过 workspace:* 协议,你无需侵入式修改业务代码、不破坏本地开发体验,即可实现「零感知 Fork + 组织级发布」。这是 Yarn/pnpm 生态为 monorepo 场景设计的标准实践,也是 Lerna-Lite 明确推荐的工作流。









