pnpm monorepo 中管理依赖的最佳实践,与 Catalogs(目录)协议的使用(monorepo 中统一版本管理)
monorepo 中如何管理依赖?
在需要的 repo
中安装依赖
在多个 repo
中安装相同依赖,可以使用以下命令:
npm install jest --workspace=web --workspace=mobile --save-dev
yarn@v1:
yarn workspace web add jest --dev
yarn workspace mobile add jest --dev
yarn@v2
yarn workspaces foreach -R --from '{web,@repo/ui}' add jest --dev
pnpm install jest --save-dev --recursive --filter=web --filter=mobile
需要注意的是:不同的
包管理器
在选择依赖安装的node_modules
的位置不同(依赖提升
)
优势
- 可维护性: 每个
repo
中的package.json
都会声明需要的依赖,开发者可以更容易地理解和处理依赖。 - 灵活性: 在大型、复杂的
monorepo
中,保持相同版本的依赖是比较困难的。不同的repo
的迭代优先级不一致,比如web
和ui
需要升级react
版本,而web
可能仍在功能迭代中,ui
则可以提前发布相关变更。
简洁的根目录依赖
依赖管理参考
https://github.com/vercel/turborepo/tree/main
https://github.com/vuejs/core/tree/main
幽灵依赖
├── apps
│ ├── mobile (dependencies: {axios: '^1.7.7'})
│ └── web (dependencies: {lodash: '4.17.21'})
└── package.json
如何统一依赖版本?
- 使用 syncpack 、 manypkg 和 sherif 等工具
- 使用 pnpm Catalogs 协议
Catalogs
Catalogs 起初是在 Vite Conf 2023 中提出,于今年
7.8
号发布: pnpm@9.5,所以使用Catalogs
协议请保持你的pnpm
版本 >=9.5.0
优势
- 统一版本: 在一个
workspace
中,通常希望包之间的依赖可以使用同一个版本,使用Catalogs
可以更方便的维护版本统一性 - 减少升级工作量和代码合并冲突: 在升级或降级依赖项时,只需要操作
pnpm-workspace.yaml
而不是每个包的package.json
,可有效减少冲突的发生。
使用
支持协议的字段
dependencies
devDependencies
optionalDependencies
pnpm.overrides
默认 Catalog
pnpm-workspace.yamlpackages: - packages/* # Define a catalog of version ranges. catalog: react: ^18.3.1 react-dom: ^18.3.1
package.json{ "name": "@example/app", "dependencies": { "react": "catalog:", // 或者 "react-dom": "catalog:default" } }
可命名的 Catalogs
pnpm-workspace.yamlcatalog: react: ^16.14.0 react-dom: ^16.14.0 catalogs: # Can be referenced through "catalog:react17" react17: react: ^17.0.2 react-dom: ^17.0.2 # Can be referenced through "catalog:react18" react18: react: ^18.3.1 react-dom: ^18.3.1
package.json{ "name": "@example/components", "dependencies": { // 使用 默认配置 "react": "catalog:", // 使用 具名配置 "react-dom": "catalog:react18" } }
发布后将变为以下内容:
package.json{ "name": "@example/components", "dependencies": { "react": "^16.14.0", "react-dom": "^18.3.1" } }
使用 codemod
快速重构项目为 Catalogs
协议
pnpx codemod pnpm/catalog
A package.json{ "name": "@example/A", "dependencies": { "react": "^16.14.0", "react-dom": "^18.3.1" } }
b package.json{ "name": "@example/B", "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1" } }
执行完命令后:
pnpm-workspace.yamlcatalog: react-dom: ^18.3.1
A package.json{ "name": "@example/A", "dependencies": { "react": "^16.14.0", "react-dom": "catalog:" } }
参考链接
- pnpm Catalogs
- Turbo - Best practices for dependency installation
- vue 是如何使用 catalogs 协议
- ViteConf 2023 | pnpm Catalogs — A New Tool to Manage Dependencies in monorepos
ViteConf 2024
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 kshao-blog-前端知识记录!
评论