Yarn Workspace 使用指南
arn 从 1.0 版开始支持 Workspace (工作区)。Workspace 能更好的统一管理有多个项目的仓库,既可在每个项目下使用独立的 package.json 管理依赖,又可便利的享受一条 yarn 命令安装或者升级所有依赖等。更重要的是可以使多个项目共享同一个 node_modules 目录,提升开发效率和降低磁盘空间占用。一句话总结就是可以大大简化对多个项目的统一管理。很多知名的开
arn 从 1.0 版开始支持 Workspace (工作区)。
Workspace 能更好的统一管理有多个项目的仓库,既可在每个项目下使用独立的 package.json 管理依赖,又可便利的享受一条 yarn 命令安装或者升级所有依赖等。更重要的是可以使多个项目共享同一个 node_modules
目录,提升开发效率和降低磁盘空间占用。
一句话总结就是可以大大简化对多个项目的统一管理。
很多知名的开源项目也使用了 Yarn Workspace,如 vue、react、jest 等。
1. Yarn Workspace 共享 node_modules
依赖详解
回看下面的带两个子项目的经典 Node.js 项目:
projects/
|--project1/
| |--package.json
| |--node_modules/
| | |--a/
|--project2
| |--package.json
| |--node_modules/
| | |--a/
| | |--project1/
project1/package.json:
{
"name": "project1",
"version": "1.0.0",
"dependencies": {
"a": "1.0.0"
}
}
project2/package.json:
{
"name": "project2",
"version": "1.0.0",
"dependencies": {
"a": "1.0.0",
"project1": "1.0.0"
}
}
没有使用 Yarn Workspace 前,需要分别在 project1
和 project2
目录下分别执行 yarn|npm install
来安装依赖包到各自的 node_modules
目录下。或者使用 yarn|npm upgrade
来升级依赖的包。
这会产生很多不良的问题:
-
如果 project1 和 project2 有相同的依赖项目 a,a 都会各自下载一次,这不仅耗时降低开发效率,还额外占用重复的磁盘空间;当 project 项目比较多的时候,此类问题就会显得十分严重。
-
如果 project2 依赖 project1,而 project1 并没有发布到 npm 仓库,只是一个本地项目,有两种方式配置依赖:
- 使用相对路径(如 file: 协议)在 project2 中指定 project1 的依赖。
- 使用
yarn|npm link
来配置依赖。
第 1 种方式缺少版本号的具体指定,每次发布版本时都需要相应的依赖版本的修改;第 2 种方式需要自行手工操作,配置复杂易出错。
需要 npm-2.0.0+ 才支持模块间的相对路径依赖,详见 npm 官方文档 package.json/Local Paths
-
没有一个统一的地方对全部项目进行统一构建等,需要到各个项目内执行
yarn|npm build
来构架项目。
使用 Yarn Workspace 之后,上述问题都能得到很好的解决。而且这是 Yarn 内置的功能,并不需要安装什么其他的包,只需要简单的在 projects 目录(Yarn 称之为 workspace-root)下增加如下内容的 package.json 文件即可。
projects/package.json:
{
"private": true,
"workspaces": ["project1", "project2"] // 也可以使用通配符设置为 ["project*"]
}
开源社区则都基本上使用
"workspaces": ["packages/*"]
的目录结构,这与 Lerna 的目录结构一致。
在 workspace-root 目录下执行 yarn install
:
$ cd projects
$ rm -r project1/node_modules
$ rm -r project2/node_modules
$ yarn install
yarn install v1.22.0
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
✨ Done in 0.56s.
此时查看目录结构如下:
projects/
|--package.json
|--project1/
| |--package.json
|--project2
| |--package.json
|--node_modules/
| |--a/
| |--project1/ -> ./project1/
说明:
-
projects 是各个子项目的上级目录,术语上称之为 workspace-root,而 project1 和 project2 术语上称之为 workspace。
-
yarn install
命令既可以在 workspace-root 目录下执行,也可以在任何一个 workspace 目录下执行,效果是一样的。 -
如果需要某个特殊的 workspace 不受
Yarn Workspace
管理,只需在此 workspace 目录下添加
.yarnrc
文件,并添加如下内容禁用即可:
workspaces-experimental false
-
在 project1 和 project2 目录下并没有 node_modules 目录(特殊情况下才会有,如当 project1 和 project2 依赖了不同版本的 a 时)。
-
/node_modules/project1
是/project1
的软链接,软链接的名称使用的是/project1/package.json#name
属性的值。 -
如果只是修改单个 workspace,可以使用
--focus
参数来快速安装相邻的依赖配置从而避免全部安装一次。
2. 可用的 Yarn Workspace 命令
2.1. yarn workspace
针对特定的 workspace 执行指定的 <command>
,如:
$ yarn workspace project1 add vue --dev 《 往 project1 添加 vue 开发依赖
$ yarn workspace project1 remove vue 《 从 project1 移除 vue 依赖
在 {workspace}/package.json#scripts
中定义的脚本命令,也可以作为 <command>
来执行。
下面是一个利用这个特点创建统一构建命令的例子:
projects/package.json:
{
"scripts": {
"build": "yarn workspaces run build"
}
}
project1|project2/package.json:
{
"scripts": {
"build": "rollup -i index.js -f esm -o dist/bundle.js"
}
}
执行 yarn build
的结果:
$ yarn build
yarn run v1.22.0
$ yarn workspaces run build
> project1
$ rollup -i index.js -f esm -o dist/bundle.js
index.js → dist/bundle.js...
created dist/bundle.js in 70ms
> project2
$ rollup -i index.js -f esm -e project1 -o dist/bundle.js
index.js → dist/bundle.js...
created dist/bundle.js in 80ms
✨ Done in 2.45s.
2.2. yarn workspaces
2.2.1. yarn workspaces run <command>
在每个 workspace 下执行 <command>
。如:
yarn workspaces run test
将会执行各个 workspace 的 test script。
2.2.2. yarn workspaces info [--json]
显示当前各 workspace 之间的依赖关系树。
$ yarn workspaces info
yarn workspaces v1.21.1
{
"project1": {
"location": "project1",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
},
"project2": {
"location": "project2",
"workspaceDependencies": [
"project1"
],
"mismatchedWorkspaceDependencies": []
}
}
✨ Done in 0.12s.
相关源代码已放在 Github 上,详见这里。
作者:RJ_Hwang
链接:https://www.jianshu.com/p/990afa30b6fe
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
更多推荐
所有评论(0)