管理依赖
- 外部依赖 来自 npm 仓库,使你能够利用生态系统中宝贵的代码,更快地构建你的应用程序和库。
- 内部依赖 使你能够在你的仓库内共享功能,显著提高共享代码的可发现性和可用性。我们将在下一篇指南中讨论如何构建内部包。
依赖安装的最佳实践
在依赖项使用的地方安装它们
当你在仓库中安装依赖项时,你应该直接在**使用**它的包中安装它。包的 package.json
将包含该包所需的所有依赖项。这对于外部和内部依赖项都是如此。
须知:
请注意,你的包管理器可能会选择使用与包不同的 node_modules 位置。
为了在多个包中快速安装依赖项,你可以使用你的包管理器
这种做法有几个好处
- 提高清晰度:当包的依赖项列在其
package.json
中时,更容易理解包依赖于什么。在仓库中工作的开发人员可以一目了然地看到包中使用了哪些依赖项。 - 增强灵活性:在大型的 Monorepo 中,期望每个包都使用相同版本的外部依赖项可能是不现实的。当许多团队在同一代码库中工作时,由于大规模运营的现实情况,将会出现不同的优先级、时间表和需求。通过在**使用**依赖项的包中安装依赖项,你可以让你的
ui
团队升级到最新版本的 TypeScript,而你的web
团队可以优先交付新功能并在稍后升级 TypeScript。此外,如果你仍然希望保持依赖项版本同步,你也可以这样做。 - 更好的缓存能力:如果你在仓库的根目录中安装了过多的依赖项,那么每当你添加、更新或删除依赖项时,你都会更改工作区根目录,从而导致不必要的缓存未命中。
- 剪除未使用的依赖项:对于 Docker 用户,Turborepo 的剪除功能可以从 Docker 镜像中删除未使用的依赖项,以创建更轻量的镜像。当依赖项安装在它们 intended for 的包中时,Turborepo 可以读取你的 lockfile 并删除在你需要的包中未使用的依赖项。
根目录中很少的依赖项
遵循上面的第一个原则,即在依赖项使用的包中安装它们,你会发现你自然而然地会在工作区的根目录中留下很少的依赖项。
工作区根目录中唯一应该存在的依赖项是用于管理仓库的工具,而用于构建应用程序和库的依赖项则安装在它们各自的包中。一些适合安装在根目录中的依赖项示例包括 turbo
、husky
或 lint-staged
。
管理依赖
Turborepo 不管理依赖项
请注意,Turborepo 在管理你的依赖项方面不扮演任何角色,这项工作留给您选择的包管理器来完成。
包管理器负责处理诸如下载正确的外部依赖项版本、符号链接和解析模块等事情。此页面上的建议是工作区中管理依赖项的最佳实践,Turborepo 不会强制执行这些实践。
模块解析在包管理器之间有所不同
包管理器具有不同的模块解析算法,这会导致行为上的差异,这些差异可能难以预测。
在 Turborepo 文档中,我们根据包管理器的预期行为提出了许多建议。我们关于如何处理依赖项的覆盖范围是尽力而为的,你可能需要根据你的包管理器或仓库的需求来调整文档中描述的行为。
但是,如果你发现文档中存在对于所有包管理器或特定包管理器普遍不正确的问题,请通过 GitHub Issue 告知我们,以便我们改进。
node_modules 位置
根据你选择的包管理器、版本、设置以及依赖项在工作区中的安装位置,你可能会在工作区内的不同位置看到 node_modules
及其内部的依赖项。依赖项可能位于根目录 node_modules
、包的 node_modules
或两者中。
只要你的脚本和任务能够找到它们需要的依赖项,你的包管理器就可以正常工作。
在你的代码中引用 `node_modules`
工作区内 node_modules
的具体位置不是包管理器的公共 API 的一部分。这意味着直接引用 node_modules
(例如 node ./node_modules/a-package/dist/index.js
)可能是脆弱的,因为磁盘上依赖项的位置可能会随着工作区周围的其他依赖项更改而更改。
相反,在可能的情况下,请依赖 Node.js 生态系统的约定来访问依赖模块。
保持依赖项版本相同
一些 Monorepo 维护者倾向于通过规则保持所有包中的依赖项版本相同。有几种方法可以实现这一点
使用专用工具
诸如 syncpack
、manypkg
和 sherif
之类的工具可以用于此特定目的。
使用你的包管理器
你可以使用你的包管理器在一个命令中更新依赖项版本。
使用 IDE
你的 IDE 的重构工具可以在你的仓库中一次性查找和替换所有 package.json
文件中的依赖项版本。尝试在 package.json
文件上使用类似 "next": ".*"
的正则表达式,以查找 next
包的所有实例,并将它们替换为你想要的版本。完成后,请务必运行包管理器的安装命令以更新你的 lockfile。
下一步
现在你已经了解了如何在工作区中有效地管理依赖项,让我们创建一个内部包,以便在你的 Monorepo 中用作依赖项。