npm-workspace & yarn-workspace
Workspace 多用于在 Monorepo 的工程架构中,而 npm(7) 和 yarn 都支持 workspace 的配置
npm-workspace
上手很简单,直接根据 npm workspace 文档 的教程就行了,这里不再赘述。下面我基于一个简单的 monorepo 结构,说明下在不同的业务场景中去使用 npm 的 workspace 功能。
项目目录结构:
.
├── lib
│ └── index.js
├── node_modules
│ ├── a -> ../packages/a
│ └── b -> ../packages/b
├── package-lock.json
├── package.json
└── packages
├── a
│ ├── index.js
│ └── package.json
└── b
├── index.js
└── package.json
可以看到在 node_module 里面的 a 和 b 依赖,都是一个软链接的形式,链接到源文件的路径。
安装依赖,添加 workspace
通过 workspace 指令安装的依赖,依赖都只会安装在项目根路径上的 node_modules 上
npm init -w ./packages/a
这里会初始化一个 npm 项目,并在根 package.json 配置 workspaces
:
{
"workspaces": [
"packages/a",
"packages/b"
]
}
给某个子包添加依赖:
npm install vue -w a
给多个包添加依赖:
npm i vue -w a -w b
给所有配置的包添加依赖:
npm i vue -ws
重新安装依赖:
npm i -ws
某个子包需要不同版本的依赖,如何安装?
比如先执行了以下的命令:
npm i -ws vue@latest
所有的包都安装了最新版本的 vue,但是 a 项目需要改成 2.0 版本的,则再执行:
npm i vue@2 -w a
npm 会在 node_modules/a/node_modules
安装 2.0 版本的 vue 依赖
批量执行命令
为 a 和 b 包分别添加下面的命令:
{
"scripts": {
"test": "echo 1", // a
"test": "echo 2", // b
}
}
执行所有包的 test
命令:
npm run test -ws
单独执行 a 和 b 包的 test 命令:
npm run test -w a -w b
发布
配置 .npmrc,这里我发到私有的 npm 源上:
echo "registry=http://my.com" >> .npmrc
发布所有的包:
npm publish -ws
发布单独的包:
npm publish -w a
yarn-workspace
我们根据上面的 npm 例子,使用 yarn 来实现一遍,先构建一个项目,项目结构如下:
.
├── lib
│ └── index.js
├── node_modules
│ ├── a -> ../packages/a
│ └── b -> ../packages/b
├── package-lock.json
├── package.json
└── packages
├── a
│ ├── index.js
│ └── package.json
└── b
├── index.js
└── package.json
安装依赖,添加 workspace
// 建议用 npm init 命令,更方便,可以直接生成文件夹和文件
npm init -w ./packages/a
在根 package.json 配置 workspaces
:
{
"workspaces": [
"packages/a",
"packages/b"
]
}
给某个子包添加依赖:
yarn workspace a add lodash -D
给多个包添加依赖:
在 yarn 的文档没找到相关的方法....
给所有配置的包添加依赖:
同上
重新安装依赖:
yarn
某个子包需要不同版本的依赖,如何安装?
a 包需要安装指定版本的 lodash
yarn workspace a add lodash@4.16.0 -D
Yarn 会在 packages/a/node_modules
安装对应版本的 lodash 依赖
批量执行命令
为 a 和 b 包分别添加下面的命令:
{
"scripts": {
"test": "echo 1", // a
"test": "echo 2", // b
}
}
执行所有包的 test
命令:
yarn workspaces run test
单独执行 a 包的 test 命令:
yarn workspace a run test
不支持多个指定包执行命令...
发布
配置 .npmrc,这里我发到私有的 npm 源上:
echo "registry=http://my.com" >> .npmrc
发布所有的包:
不支持...
发布单独的包:
yarn workspace a publish
总结
从上面的对比来说,yarn 的功能比 npm 差不少,但我上面用的是 yarn@1 的版本,而我看了下 yarn@2 workspace 提供的 cli 会多点,和 npm 类似,所以建议还是使用 npm 或 yarn@2 版本的 workspace 功能
总的来说,npm 和 yarn 提供的 workspace 功能,提供的是底层的功能,比如文件的链接,包的依赖安装和命令执行等,那这和 lerna 有什么区别?
- 默认情况下,文件的链接是 lerna 自己实现的,同时它也可以支持 lerna 和 npm/yarn 的 workspace 共同使用
- lerna 提供更多的命令使用,例如发布(生成 tag)、内置的根据 git commit 生成 changelog、子包的版本号管理
相对于来说,lerna 的功能更加自动化,但现在 lerna 已经不维护了(该记录是在 2022-04-18 写的),所以对于我个人来说,应该不会再在新项目使用 lerna