跳至主要内容

工作区

什么是工作区?

工作区是属于同一项目且 Yarn 将安装并链接在一起以简化交叉引用的各个包的名称。

当与存储库结合使用时,这种模式通常称为单一存储库。工作区最初由 Lerna 等项目推广,但 Yarn 是第一个为其提供本机支持的包管理器 - 随着我们在其周围构建更多功能,这种支持从未停止改进。

信息

我们始终尝试使用我们提供的功能,工作区就是一个很好的例子:Yarn 由几十个包组成,如果需要,每个包都可以独立部署!

我应该在什么时候使用工作区?

工作区在许多情况下都表现出色,主要情况包括

  • 当一个项目有一个核心包,周围有各种附加组件时;例如 Babel 就是这种情况。

  • 当您需要发布多个包并且希望避免贡献者在每次想要进行更改时都必须在许多单独的存储库上打开 PR 时。例如 Jest 就是这种情况。

  • 或者当项目希望在其代码中保持严格的边界并避免变成纠缠的整体时。例如 Yarn 本身或许多企业代码库就是这种情况。

关于单一存储库的好坏已经有过大量的讨论,双方都有合理的论据。我们的团队在这一点上已经使用单一存储库很多年了,并且借助 Yarn 提供的工具,其价值始终远远大于缺点。如果您需要为您的项目创建另一个包,请考虑将它们组合在一起是否有意义。

提示

您不必将代码拆分为多个工作区才能使它们变得有用。例如,Clipanion 存储库仅使用两个工作区,一个用于库,另一个用于其网站。此模式避免混合依赖项,同时还使编写影响代码和文档的 PR 变得容易。

工作区是如何声明的?

要声明工作区,您只需向根 package.json 文件添加一个 workspaces 数组,并列出指向工作区文件夹的相对 glob 模式。在以下示例中,packages 文件夹中的所有子目录都将成为工作区。

{
"workspaces": [
"packages/*"
]
}

约束

约束对于单一仓库来说就像 Eslint 对于您的源代码一样。它们允许您声明必须应用于项目中特定工作区的规则。例如,您可以使用约束来强制同步项目中的所有依赖项,以防止使用某些依赖项,或强制某些字段(例如 licenseengines.node)在所有地方都正确设置。

有关约束的更多信息和示例,请查看 专门文章

交叉引用

来自单一仓库的软件包通常需要相互依赖 - 例如,当您有一个依赖于单独库的应用程序软件包时。Yarn 得益于特殊的 workspace: 协议,这使得它非常容易,该协议允许您指示 Yarn 使用项目中同名工作区来解决依赖项。例如

{
"dependencies": {
"@my-org/utils": "workspace:^"
}
}

workspace: 协议接受常规 semver 范围或特殊 ^ / ~ / * 令牌。无论值是什么,都不会改变 Yarn 解决依赖项的方式(它只会关心依赖项名称),但它会影响软件包通过 yarn npm publish 发布后的外观。例如,如果针对 version 字段设置为 3.2.1 的工作区使用以下范围

初始范围发布后的范围
workspace:^3.0.0^3.0.0
workspace:^^3.2.1
workspace:~~3.2.1
workspace:*=3.2.1

重点安装

在发现工作区时,一个常见的问题是,无论何时希望处理其中一个工作区,都需要安装其所有依赖项。Yarn 通过 yarn workspaces focus 提供了解决方案。

此命令获取工作区列表,将列表扩展为包括传递依赖项,并从安装中排除所有其他内容。例如,以下内容将允许您仅安装构建和部署主应用程序所需的依赖项

yarn workspaces focus @my-org/app

如果您还希望跳过安装 devDependencies,请设置 --production 标志。在以下示例中,Yarn 将安装所有工作区的依赖项,但仅安装生产依赖项

yarn workspaces focus -A --production

全局脚本

package.json 文件的 scripts 字段中定义的脚本可以使用 yarn run name 运行,但仅当您从声明它们的 workspace 中运行命令时。也就是说,除非它们是全局脚本。

全局脚本的特点是在脚本名称中至少有一个冒号 (:)。只要没有重复项(如果两个工作区定义了具有相同名称的脚本,它们将不会升级为全局脚本),就可以在项目中的任何位置运行它们。

并行执行

如果脚本共享相同的名称,则可以使用 yarn workspaces foreach 并行运行来自多个工作区的脚本。以下示例展示了如何并行发布项目中的所有软件包,但遵循拓扑顺序(因此,只有当某个工作区依赖的所有其他工作区都发布后,该工作区才会发布)

yarn workspaces foreach --all -pt npm publish

--all 标志将在项目中的每个工作区上运行提供的命令,但可以对其进行调整。在此示例中,我们使用 --since 标志来仅选择与 主分支 相比在当前分支中已修改的工作区

yarn workspaces foreach --since run lint

类似地,--from pattern 标志将选择与提供的 glob 模式匹配的所有工作区。对于所有其他 Yarn 命令,此标志将应用于工作区名称和相对于当前工作目录的路径。例如,此命令将在当前工作区及其依赖的所有其他工作区上运行 build 脚本

yarn workspaces foreach --from . -R run build