pnpm monorepo 中管理依赖的最佳实践,与 Catalogs(目录)协议的使用(monorepo 中统一版本管理)
monorepo 中如何管理依赖?
在需要的 repo 中安装依赖
在多个 repo 中安装相同依赖,可以使用以下命令:
npm install jest --workspace=web --workspace=mobile --save-devyarn@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 --devpnpm 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,可有效减少冲突的发生。
使用
支持协议的字段
dependenciesdevDependenciesoptionalDependenciespnpm.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-前端知识记录!
评论









