无需发布至NPM Registry,如何在Node.js Monorepo中共享代码?
不发布至NPM Registry的Node.js跨项目代码共享方案
针对你的多包结构(/packages/shared、/api-server、/cool-cli),下面给出几种无需发布shared模块的可行方案,分别适配服务端部署和CLI发布的场景:
一、Monorepo工作区管理(最推荐)
利用pnpm/npm的内置workspace功能,能自动管理跨包依赖,避免手动处理相对路径的麻烦。
1. 初始化工作区
在项目根目录创建package.json,标记为私有工作区:
{ "name": "my-monorepo", "private": true, "workspaces": ["packages/*"] }
2. 配置跨包依赖
在api-server/package.json和cool-cli/package.json中,直接将shared声明为工作区依赖:
"dependencies": { "shared": "workspace:*" }
执行pnpm install或npm install后,工具会自动在内部关联shared模块,开发阶段直接引用即可。
3. api-server的部署
部署服务端时,可使用pnpm的deploy命令快速打包所需文件:
pnpm deploy --filter api-server ./deploy-dir
该命令会将api-server及其依赖(包括shared的编译产物)打包到指定目录,直接上传到服务器运行即可。
4. cool-cli的发布(关键处理)
由于NPM不支持workspace依赖的发布,需要将shared的代码整合到cool-cli的发布包中,两种方式可选:
方式1:复制shared编译产物到CLI包
- 先编译shared模块:
cd packages/shared && pnpm build - 将shared的dist目录复制到cool-cli目录下:
cp -r packages/shared/dist packages/cool-cli/shared - 修改cool-cli的
package.json:
发布时,shared的代码会随cool-cli一起上传到NPM,用户安装后可直接使用。"files": ["dist", "shared"], // 确保shared被包含在发布包内 "dependencies": { // 移除workspace依赖,直接通过相对路径引用本地的shared }
方式2:用打包工具合并shared代码
如果cool-cli使用webpack、rollup或esbuild构建,可将shared作为内部依赖打包进CLI产物:
- 配置打包工具的
external选项,仅排除Node.js内置模块(如node:fs),让shared的代码被合并到最终产物中 - 例如rollup配置示例:
构建后,cool-cli的dist文件已包含shared的代码,发布时无需额外处理shared目录。export default { input: 'src/index.js', output: { file: 'dist/cli.js', format: 'cjs' }, external: ['node:fs', 'node:path'] }
二、非Monorepo场景的替代方案
如果不想用workspace,可通过本地链接+发布前替换依赖的方式实现:
1. api-server的开发与部署
- 开发阶段:执行
npm link ../shared或pnpm link --global ../shared,实现本地模块关联 - 部署阶段:在部署脚本中添加
npm install ../shared,直接将shared安装到api-server的node_modules中,或手动复制shared目录到node_modules
2. cool-cli的发布
- 发布前,将shared的编译产物复制到cool-cli目录下
- 修改cool-cli的
package.json,将shared依赖改为本地路径:
发布后,用户安装cool-cli时,NPM会自动处理本地路径的依赖,将shared的代码一并安装。"dependencies": { "shared": "./shared" }, "files": ["dist", "shared"]
三、注意事项
- 若shared包含自身依赖:对于服务端的api-server,只需确保monorepo依赖安装完整即可;对于cool-cli,需将shared的依赖也添加到cool-cli的
package.json中(避免用户安装时缺失),或在打包shared时将依赖一并打包(仅适用于纯JS模块) - 对于无法打包的依赖(如二进制文件、Native模块),必须在cool-cli的
package.json中单独声明这些依赖,确保用户安装时能正常获取 - 使用monorepo时,根目录的
package.json必须设置private: true,防止误发布整个工作区
内容的提问来源于stack exchange,提问作者suguan Yang
相关产品推荐
相关产品推荐

