惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

win or mac clash 无 TUN 让 Antigravity、Chrome 强制 proxy(解决 Antigravity 无法加载选择 model、自动更新无法登录、跳转) 【大杂烩】在 pnpm 中直接修改 node_modules(.pnpm) 中的依赖项,项目中持久化 - pnpm 中的依赖处理、幽灵依赖、寻址规则等 在 html 中直接使用 Esm、Jsx 脚本快速调试和使用 React@19 和 Vue@3 源码,解决 React19 UMD 构建等问题 一键在本地批量检测并升级更新 package.json 中的模块依赖,ncu(npm-check-updates)在 npm、pnpm 或 workspace 项目中的使用教程 解决 Mac Docker Desktop 中启动出现的问题合集 通过阿里云、腾讯云无服务器搭建自定义的企业域名邮箱,实现在 QQ邮箱 收发等功能(附腾讯 SMTP 和 IMAP) 解决使用代理(clash 等)进行 SSH 连接(如 Github ssh key clone/push)出现 kex_exchange_identification 错误 静态文件资源 cdnjs, jsdelivr 抖音字节国内快速 CDN 镜像推荐【2025】- 仍在使用 bootcdn 和 staticfile CDN 请注意验证资源的完整性(SRI) Web 安全中的 Secure Contexts(安全上下文)- 解决在本地中使用 clipboard 或 Crypto 等 API 限制或关闭上下文限制 使用 serve 配合 openssl 或 mkcert 创建本地自签名可信任的证书 - 创建本地 TLS\SSL https 协议服务 利用 Github Actions 和 Acme 自动申请、更新和部署至阿里云、腾讯云 CDN Lets Encrypt SSl\TLS ECC RSA 双证书 【CSS】解决在 flex 容器中使用 align-content 或 justify-content 属性 center 居中时的溢出滚动和截断问题 - 理解 safe 关键字 在线工具 - 一键获取下载抖音无水印视频、抖音去水印解析工具、下载抖音无水印高清图集【2025 最新】 【React Router】v6 data router 在非组件(或工具方法)中如何优雅的跳转路由 【React】为什么路由跳转时页面滚动高度不会被重置(保留上个页面高度)?理解 history scrollRestoration 的场景与使用,以及如何使用 React Router 重置和跳转前保留滚动高度
pnpm monorepo 中管理依赖的最佳实践,与 Catalogs(目录)协议的使用(monorepo 中统一版本管理)
kshao · 2024-09-11 · via

monorepo 的优势在 repo 之间的共享复用、规范统一管理等方面,而随着项目的规模增长,repo 的依赖处理逻辑也会随着迭代而复杂

monorepo 中如何管理依赖呢?是将 repo 中的共同依赖安装至根目录的 package.json 中?还是将依赖安装至各 repopackage.json 中?

在需要的 repo 中安装依赖

对于大部分 monorepo 项目来说,直接在需要依赖项的 repo 中的 package.json 显示声明,无论是外部依赖还是内部的 repo 之间的依赖,即便 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 的迭代优先级不一致,比如 webui 需要升级 react 版本,而 web 可能仍在功能迭代中,ui 则可以提前发布相关变更。

简洁的根目录依赖

按上述策略安装依赖时,将会减少 workspace 根目录中的依赖。根目录中需要的依赖项是用于管理项目的工具,而用于构建的依赖项则安装在各自的包中。

一些适合安装在 workspace 很目录中的依赖:turbohuskylint-staged

依赖管理参考

https://github.com/vercel/turborepo/tree/main
https://github.com/vuejs/core/tree/main

幽灵依赖

如果你使用的是 npmyarn@v1 时,安装依赖会默认提升至根目录中的 node_modules 中,此时若 mobile 依赖了 lodash 且未声明时,lodash 将成为 mobile幽灵依赖,若后续迭代中,web 取消了对 lodash 的依赖,那么在开发或运行 mobile 时将会遇到错误。

├── apps
│   ├── mobile (dependencies: {axios: '^1.7.7'})
│   └── web (dependencies: {lodash: '4.17.21'})
└── package.json

如何统一依赖版本?

Catalogs

Catalogs 起初是在 Vite Conf 2023 中提出,于今年 7.8 号发布: pnpm@9.5,所以使用 Catalogs 协议请保持你的 pnpm 版本 >= 9.5.0

Catalogs 工作于 workspace,用于将依赖版本的范围定义为可重用的变量,在 pnpm-workspace.yaml 中定义,package.json 中使用。

优势

workspace 中,不同的包之间会使用相同的依赖项,使用 Catalogs 协议可有效减少重复工作

  • 统一版本: 在一个 workspace 中,通常希望包之间的依赖可以使用同一个版本,使用 Catalogs 可以更方便的维护版本统一性
  • 减少升级工作量和代码合并冲突: 在升级或降级依赖项时,只需要操作 pnpm-workspace.yaml 而不是每个包的 package.json,可有效减少冲突的发生。

使用

Catalogspnpm-workspace.yaml 中定义,有两种定义 Catalogs 的方法。通过 catalog:namepackage.json 中进行引用。

支持协议的字段

  • dependencies
  • devDependencies
  • optionalDependencies
  • pnpm.overrides

默认 Catalog

对于默认 Catalog 可以通过 catalog:default 进行引用,也可以简写为 catalog:

catalog: 协议可理解为直接编写版本范围 ^18.3.1

pnpm-workspace.yaml

packages: - 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.yaml 顶层中不仅可以定义默认的 catalog 也可以定义具名的 catalogs

pnpm-workspace.yaml

catalog: 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 协议

workspace 的根目录下运行此命令,可快速将项目中 package.json 的版本协议替换为 默认 catalog:,并在 pnpm-workspace.yaml 修改或添加 catalog

pnpx codemod pnpm/catalog

需要注意!该命令会将 workspace 中的所有依赖都转换为 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.yaml

catalog: react-dom: ^18.3.1

A package.json

{ "name": "@example/A", "dependencies": { "react": "^16.14.0", "react-dom": "catalog:" } }

参考链接

ViteConf 2024

https://viteconf.org/