如何让Yarn Workspace引用JavaScript Monorepo根目录的可执行文件?
Monorepo中子包调用根目录共享依赖命令的问题
场景说明
我的Monorepo结构如下:
root/ package.json packages/ packageA/ package.json packageB/ package.json ... packageZ/ package.json
根目录package.json中定义了所有子包共享的依赖:
{ ... "private": true, "workspaces": [ "packages/*" ], "devDependencies": { "typescript": "^4.0.0", "vitest": "^1.0.0" }, "dependencies": { "lodash": "^4.0.0" } }
子包代码可以正常访问根目录的依赖(比如lodash),但在packageA/package.json中定义脚本后:
{ "scripts": { "test": "vitest $*", "build": "tsc --build" } }
执行yarn workspace packageA test或yarn workspace packageA build时,会报错command not found: vitest/tsc。希望仅在根目录定义一次依赖来保证版本一致性,如何解决?
解决方案
方法1:使用yarn exec调用根目录二进制命令
yarn的exec命令会在整个workspace的依赖链中查找对应的二进制可执行文件,直接修改子包的脚本:
{ "scripts": { "test": "yarn exec vitest $*", "build": "yarn exec tsc --build" } }
执行yarn workspace packageA test时,yarn会自动定位到根目录安装的vitest,无需在子包重复安装依赖。
方法2:直接指定根目录bin路径
如果不想用yarn exec,可以直接引用根目录node_modules/.bin下的命令文件,适合固定结构的Monorepo:
{ "scripts": { "test": "../node_modules/.bin/vitest $*", "build": "../node_modules/.bin/tsc --build" } }
注意:这种方式依赖子包在packages/目录下的层级,若目录结构调整需要同步修改路径。
方法3:根目录定义统一脚本,子包调用
在根目录package.json中定义通用脚本(需确保根package有name字段,比如"name": "root"):
{ ... "scripts": { "workspace:test": "vitest $*", "workspace:build": "tsc --build" } }
然后子包脚本改为调用根目录的脚本:
{ "scripts": { "test": "yarn workspace root workspace:test", "build": "yarn workspace root workspace:build" } }
这种方式适合需要统一管控所有子包脚本参数的场景。
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

