仅个人遇见问题记录
在 Monorepo 项目中,Yarn Workspaces 和 Lerna 通常一起使用来简化多包管理,统一版本控制和依赖管理。本文将详细分析在使用这些工具时常见的问题,包括如何正确配置工作区、如何使用本地库、如何避免依赖冲突,以及如何强制 Yarn 使用特定版本的依赖。
1. Yarn Workspaces 和 Lerna 基本配置
配置 lerna.json
首先,我们需要配置 Lerna 来管理 Monorepo 中的多个包,并控制版本和发布策略。lerna.json
是 Lerna 的主要配置文件,必须包括一个 packages
字段来指定所有包的位置。
例如,假设你的项目结构如下:
root/ packages/ dva/ utils/ examples/ test-fn/ package.json lerna.json
你的 lerna.json
文件应该如下配置:
json
{
"packages": [
"packages/*",
"examples/*"
],
"version": "independent", // 每个包独立管理版本
"npmClient": "yarn", // 使用 Yarn 作为包管理工具
"command": {
"version": {
"exact": true // 发布版本时,版本号保持一致
}
}
}
配置根目录的 package.json
在根目录的 package.json
中,我们需要设置 workspaces
字段来告诉 Yarn 这是一个使用 Workspaces 的项目,并指定哪些文件夹是工作区。
json
{
"private": true, // 确保根目录不是一个独立的包
"workspaces": [
"packages/*", // 工作区目录
"examples/*"
]
}
根目录的 package.json
配置了 workspaces
,这将使得 Yarn 知道它需要管理工作区中的所有依赖。
2. 使用 workspace:*
语法引用本地包
Yarn Workspaces 的核心优势之一是它可以让你在 Monorepo 中的不同包之间共享依赖。在某个工作区中,你可以通过 workspace:*
语法来引用其他工作区的包。
例如,在 test-fn
的 package.json
中:
json
{
"dependencies": {
"dva": "workspace:*"
}
}
这样做的目的是让 test-fn
使用 packages/dva
目录中的 dva
包,而无需手动指定路径。Yarn 会自动将依赖解析为工作区中的包。
问题:
- Yarn 忽略本地的
beta
版本,选择线上版本 。如果你的dva
包是一个beta
版本(如2.6.0-beta.22
),但在根目录中已经安装了线上稳定版本,Yarn 可能会忽略本地的beta
版本,直接选择稳定的线上版本。
解决方案:
-
确保本地版本优先 :如果你希望强制使用本地的
beta
版本,可以在根目录的package.json
中使用resolutions
来锁定本地版本:json"resolutions": { "dva": "2.6.0-beta.22" }
-
显式指定版本 :在
test-fn
的package.json
中,显式指定本地的beta
版本,避免 Yarn 自动选择稳定的线上版本:json"dva": "workspace:2.6.0-beta.22"
-
清理和重新安装依赖:在遇到 Yarn 安装冲突或版本选择问题时,删除现有的依赖并重新安装:
bashrm -rf node_modules rm -f yarn.lock yarn install
3. 工作区依赖无法正确解析
在 test-fn
中明确声明了依赖,对于一些外部依赖可能仍然会遇到依赖无法正确解析的问题。如可能在工作区中无法找到babel
问题:
- 在根目录的
node_modules
中已正确安装,但在工作区中找不到依赖。
解决方案:
-
确保依赖声明完整 :即使某个依赖在根目录已经安装,工作区中的
package.json
仍需要显式声明依赖:json{ "dependencies": { "babel-runtime": "^6.9.2" } }
-
使用
yarn list
检查依赖:查看是否所有依赖都已安装,并且版本一致:bashyarn list babel
-
清理并重新安装依赖:确保依赖正确安装并解析:
bashrm -rf node_modules rm -f yarn.lock yarn install
4. 依赖提升问题
在 Monorepo 中,Yarn 会根据需要将一些依赖提升到根目录的 node_modules
中。这通常会导致在某些工作区中找不到本地依赖。
问题:
- 某些依赖被提升到根目录,导致工作区中找不到这些依赖。
解决方案:
-
避免依赖提升 :使用
nohoist
配置来避免依赖提升,确保每个工作区都有自己的依赖副本。json"nohoist": [ "**/*" ]
-
检查依赖树 :通过
yarn list
查看依赖树,确保所有工作区都可以访问到所需的依赖。