如何配置npm Workspaces以链接Angular库的dist目录而非源码?
项目结构
workspace/ ├─ package.json <-- 配置有npm workspaces(见下文) ├─ packages/ │ ├─ angular/ <-- Angular工作区 │ │ ├─ projects/ │ │ │ ├─ a/ <-- Angular库A源码 │ │ │ │ ├─ package.json │ │ │ ├─ b/ <-- Angular库B源码 │ │ │ │ ├─ package.json │ │ ├─ dist/ │ │ │ ├─ a/ <-- 构建后的Angular库A │ │ │ ├─ b/ <-- 构建后的Angular库B │ ├─ webcomponents/ <-- Stencil.js Web组件 │ │ ├─ package.json │ │ ├─ dist/ │ ├─ demo-app/ <-- 依赖上述所有包的演示应用 │ │ ├─ package.json
当前npm Workspaces配置
根目录package.json中的workspaces配置:
"workspaces": [ "packages/*", "packages/angular/projects/*" ]
遇到的问题
所有工作区依赖安装正常,但demo-app本地链接依赖时:
webcomponents可正常工作,因为其dist目录直接在配置的工作区内;- Angular库则被链接到
projects/[a,b]源码目录而非dist构建产物目录,导致demo-app构建失败。
此前使用Lerna管理时,会遵循package.json中的publishConfig.directory配置来链接构建产物,但npm Workspaces无此机制。若将workspaces配置改为指向dist目录:
"workspaces": [ "packages/*", "packages/angular/dist/*" ]
虽能解决链接问题,但会破坏Lerna对源码package.json的自动版本管理,不可行。
请问该如何正确配置此场景?是否有可行方案?
方案一:使用npm overrides强制指定依赖路径
在demo-app/package.json中添加overrides字段,直接将Angular库的依赖指向构建后的dist目录:
"overrides": { "@your-org/a": "../angular/dist/a", "@your-org/b": "../angular/dist/b" }
此方式下,npm会优先使用指定的dist路径加载依赖,而根目录的workspaces仍保留源码目录配置,不影响Lerna的版本管理功能。每次构建Angular库后,demo-app会自动使用最新的构建产物。
方案二:修改Angular库源码的package.json入口字段
在packages/angular/projects/a/package.json和packages/angular/projects/b/package.json中,将main、module、types等入口字段指向构建后的产物路径(相对于源码目录):
{ "name": "@your-org/a", "main": "../../dist/a/bundles/a.umd.js", "module": "../../dist/a/fesm2022/a.mjs", "types": "../../dist/a/index.d.ts" }
确保Angular库构建后,dist目录下的产物路径与上述配置一致。这样npm Workspaces链接源码目录时,会通过这些入口字段自动加载dist中的构建产物,无需修改workspaces配置,同时Lerna仍可正常管理源码的package.json版本。
方案三:手动使用npm link链接构建产物
在开发阶段,可绕过npm Workspaces的自动链接,手动链接构建后的产物:
- 进入Angular库的
dist目录(如packages/angular/dist/a),执行:npm link - 进入
demo-app目录,执行:npm link @your-org/a
此方式适合临时调试,但需要手动操作,每次构建后若产物有变更,需重新执行链接步骤。
方案四:通过脚本同步源码与dist的package.json
编写构建脚本,在Angular库构建完成后,将源码目录的package.json复制到对应dist目录,并调整其中的路径字段(如移除相对路径前缀)。之后可在根目录workspaces中同时配置源码和dist目录:
"workspaces": [ "packages/*", "packages/angular/projects/*", "packages/angular/dist/*" ]
但需注意避免版本冲突,可通过脚本确保dist目录的package.json版本与源码保持一致。此方案相对复杂,适合需要同时维护源码和构建产物工作区的场景。
内容的提问来源于stack exchange,提问作者nioe

