管理依赖项
- 外部依赖项来自 npm 注册表,让你可以利用生态系统中宝贵的代码,更快地构建你的应用程序和库。
- 内部依赖项让你可以在仓库内共享功能,极大地提高共享代码的可发现性和可用性。我们将在下一篇指南中讨论如何构建内部包。
依赖项安装的最佳实践
在依赖项使用的地方安装它们
当你在仓库中安装依赖项时,你应该直接在 使用它的包中安装它。包的 package.json
将包含该包所需的所有依赖项。这对于外部和内部依赖项都是如此。
须知:
请注意,你的包管理器可能会选择使用与包不同的 node_modules 位置。
为了在多个包中快速安装依赖项,你可以使用你的包管理器
这种做法有几个好处
- 提高清晰度:当包的依赖项列在其
package.json
中时,更容易理解包依赖于什么。在仓库中工作的开发人员可以一目了然地看到包中使用了哪些依赖项。 - 增强灵活性:在大型 monorepo 中,期望每个包都使用相同版本的外部依赖项可能是不现实的。当许多团队在同一个代码库中工作时,由于大规模运营的现实情况,会存在不同的优先级、时间表和需求。通过在 使用它们的包中安装依赖项,你可以让你的
ui
团队升级到最新版本的 TypeScript,而你的web
团队可以优先交付新功能并在稍后升级 TypeScript。此外,如果你仍然希望保持依赖项版本同步,你也可以这样做。 - 更好的缓存能力:如果你在仓库的根目录中安装了太多依赖项,那么每当你添加、更新或删除依赖项时,你都会更改工作区根目录,从而导致不必要的缓存未命中。
- 修剪未使用的依赖项:对于 Docker 用户,Turborepo 的修剪功能可以从 Docker 镜像中删除未使用的依赖项,以创建更轻量的镜像。当依赖项安装在它们 intended 的包中时,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 中的依赖项。