[note] Monorepo with Yarn Workspaces
$ yarn add <pkg> -W # add the dependency to the workspace root
# yarn workspace
$ yarn workspace <workspace_name> add <pkg>
$ yarn workspace <workspace_name> remove <pkg>
# yarn workspace run
$ yarn workspace <workspace_name> start # run start command in the specific workspace
$ yarn workspace <workspace_name> lint # run lint command in the specific workspace
# yarn upgrade
$ yarn upgrade <pkg@version> --scope <@scope>
$ yarn upgrade-interactive
# show workspaces info
$ yarn workspaces info
$ yarn workspaces run test # run the command in each worksapce
Workspaces
workspaces @ yarn
先在 package.json
檔案中:
- 設定
workspaces
讓 yarn 來處理 packages hoisting - 因為 root 的 package 並不是真的會發布到 npm 上的 package,所以需要加上
private: true
+++ package.json
@@ -6,6 +6,7 @@
"license": "MIT",
"devDependencies": {
"husky": "^7.0.4",
+ "lerna": "^4.0.0",
"lint-staged": "^12.1.7",
"prettier": "^2.5.1",
"stylelint": "^14.2.0",
"*.scss": [
"stylelint --fix"
]
+ },
+ "private": true,
+ "workspaces": [
+ "packages/*"
+ ],
}
假設 packages/*
裡包含了 foo 和 bar 兩個資料夾,他們各自是獨立的 package,前者的 package name 是 @pjchender/foo
後者是 @pjchender/bar
:
.
├── package.json
├── packages
│ ├── bar
│ │ ├── index.js
│ │ └── package.json
│ └── foo
│ ├── index.js
│ └── package.json
└── yarn.lock
當我們執行 yarn
來安裝 dependencies 時,yarn 會在 root 的 node_modules
中幫我們建立 symlink 指稱到對應的 package。可以看到下圖中 root package 的 node_modules
裡會分別建立 symlink 來連到本地 packages/foo
和 packages/bar
:
.
├── node_modules
│ └── @pjchender
│ ├── bar -> ../../packages/foo
│ └── foo -> ../../packages/bar
├── package.json
├── packages
│ ├── bar
│ │ ├── index.js
│ │ └── package.json
│ └── foo
│ ├── index.js
│ └── package.json
└── yarn.lock
nohoist
workspaces
後除了可以直接使用陣列放入 monorepo 的資料夾外,如果需要更多的設定,也可以改用物件的方式來設定。例如,針對某些套件如果我們不希望被 hoist 的話,可以使用 nohoist
的選項,這時候的設定檔會像這樣:
// package.json
{
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": [
"**/normalize-scss"
]
}
}
這時候 normalize-scss 這個套件就不會被 hoist 在 root,而是會安裝在各 packages 內的 node_modules 中。