工作区

工作区是设置你的软件包体系结构的一种新方式,默认情况下从 Yarn 1.0 开始使用。它允许你可以使用这种方式安装多个软件包, 就是只需要运行一次 ` yarn install ` 便可将所有依赖包全部安装。

你为什么要这么做?

  • 你的依赖包可以链接在一起,这意味着你的工作区可以相互依赖,同时始终使用最新的可用代码。 这也是一个比 ` yarn link ` 更好的机制,因为它只影响你工作区的依赖树,而不会影响整个系统。

  • 你所有的项目依赖将被安装在一起,这样可以让 Yarn 来更好地优化它们。

  • Yarn 将使用一个单一的 lock 文件,而不是每个项目多有一个,这意味着更少的冲突和更容易进行代码检查。

如何使用它?

在 ` package. json ` 文件中添加以下内容,从现在开始,我们将此目录称为 “工作区根目录”:

package.json

{
  "private": true,
  "workspaces": ["workspace-a", "workspace-b"]
}

Note that the private: true is required! Workspaces are not meant to be published, so we’ve added this safety measure to make sure that nothing can accidentally expose them.

创建这个文件后,再创建两个名为 ` workspace-a ` 和 ` workspace-b ` 的子文件夹。 在每个文件夹里面,创建一个具有以下内容的 ` package. json ` 文件:

workspace-a/package.json:

{
  "name": "workspace-a",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5"
  }
}

workspace-b/package.json:

{
  "name": "workspace-b",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5",
    "workspace-a": "1.0.0"
  }
}

最后,在某个地方运行 ` yarn install ` ,当然最好是在工作区根目录里面。如果一切正常,你现在应该有一个类似这样的文件层次结构:

/package.json
/yarn.lock

/node_modules
/node_modules/cross-env
/node_modules/workspace-a -> /workspace-a

/workspace-a/package.json
/workspace-b/package.json

就是这样 ! ` workspace-b 需要一个在 workspace-a 中的文件,现在将直接使用当前项目内部的文件,而不是直接去从 Github 上面取。 cross-env ` 包已正确去重并放在项目的根目录下,让 ` workspace-a ` 和 ` workspace-b `可以一起使用这个包。

它与 Lerna 的对比怎么样?

Yarn 的 workspaces 是 Lerna 这样的工具 (和 do ) 的低级实现。 它们将永远不会试图提供像 Lerna 那么高级的功能,但通过实现该解决方案的核心逻辑和 Yarn 内部的连接步骤,我们希望能够提供新的用法并提高性能。

提示和技巧

  • workspaces 字段是一个数组,其中包含到每个工作区的路径。 如果用这种方式来跟踪每个工作区可能是比较乏味的,所以这个字段也接受了通配符模式! 例如,Babel 通过这个 ` packages/* ` 指令引用他们的所有包。

  • 工作区的稳定性足以在 large-scale 应用程序中使用,并且不应改变常规安装的运行方式,但如果你认为它们正在破坏某些东西,则可以通过将以下内容添加到你的 Yarnrc 文件中来禁用它们:

      workspaces-experimental false
    

限制和警告

  • 包层级在你的工作区和用户得到的内容之间将有所不同(工作区依赖将提升到文件系统层次结构中)。 对这个层级的假设已经是危险的,因为提升过程不是标准化的,所以理论上没有什么新东西。

  • 在上面的示例中,如果 ` workspace-b ` 依赖于 ` workspace-a ` 的包,但是引用的是不同的版本,那么依赖包将从 Github 安装,而不是从本地文件系统链接。 这是因为一些软件包实际上需要使用以前的版本,以建立新的版本(Babel 是其中之一)。

  • Be careful when publishing packages in a workspace. If you are preparing your next release and you decided to use a new dependency but forgot to declare it in the package.json file, your tests might still pass locally if another package already downloaded that dependency into the workspace root. However, it will be broken for consumers that pull it from a registry, since the dependency list is now incomplete so they have no way to download the new dependency. Currently there is no way to throw a warning in this scenario.

  • Workspaces must be children of the workspace root in term of folder hierarchy. You cannot and must not reference a workspace that is located outside of this filesystem hierarchy.

  • Nested workspaces are not supported at this time.