管理依赖项
- 外部依赖项来自 npm 注册表,允许您利用生态系统中宝贵的代码来更快地构建应用程序和库。
- 内部依赖项允许您在存储库中共享功能,从而显著提高共享代码的可发现性和可用性。我们将在下一篇指南中讨论如何构建内部包。
依赖项安装的最佳实践
在依赖项使用的地方安装它们
当您在存储库中安装依赖项时,您应该直接在使用的包中安装它。该包的 package.json
将包含该包所需的所有依赖项。这对于外部依赖项和内部依赖项都是如此。
了解一下
请注意,您的包管理器可能会选择使用与包不同的 node_modules 位置。
要在多个包中快速安装依赖项,您可以使用您的包管理器
这种做法有几个好处
- 提高清晰度:当一个包的依赖项列在其
package.json
中时,更容易理解该包依赖于什么。在存储库中工作的开发人员可以一目了然地看到该包中使用了哪些依赖项。 - 增强灵活性:在大型单体存储库中,期望每个包都使用相同版本的外部依赖项是不现实的。当许多团队在同一代码库中工作时,由于大规模运营的现实情况,会有不同的优先级、时间线和需求。通过在使用的包中安装依赖项,您可以使您的
ui
团队升级到最新版本的 TypeScript,而您的web
团队可以优先发布新功能并在稍后升级 TypeScript。此外,如果您仍然希望保持依赖项版本同步,您也可以这样做。 - 更好的缓存能力:如果您在存储库的根目录中安装了过多的依赖项,则每次添加、更新或删除依赖项时都会更改工作区根目录,从而导致不必要的缓存未命中。
- 删除未使用的依赖项:对于 Docker 用户,Turborepo 的删除功能可以从 Docker 镜像中删除未使用的依赖项,以创建更轻的镜像。当依赖项安装在它们应该用于的包中时,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 生态系统的约定来访问依赖模块。
保持依赖项版本相同
一些单体存储库维护人员更喜欢通过规则保持所有包的依赖项版本相同。有几种方法可以实现此目的
使用专门构建的工具
可以使用 syncpack
、manypkg
和 sherif
等工具来实现此特定目的。
使用您的包管理器
您可以使用包管理器在一个命令中更新依赖项版本。
使用 IDE
您的 IDE 的重构工具可以一次在存储库中的所有 package.json
文件中查找并替换依赖项的版本。尝试在 package.json
文件上使用类似 "next": ".*"
的正则表达式,以查找 next
包的所有实例,并将它们替换为您想要的版本。完成后,请务必运行包管理器的安装命令以更新您的 lockfile。
下一步
现在您知道如何在工作区中有效地管理依赖项了,让我们创建一个内部包,将其用作单体存储库中的依赖项。
这有帮助吗?