workspaces
前言
从npm 7.0 开始已经支持workspace
了。另外,yarn和pnpm也拥有workspaces的能力。从用法上来说,几乎是一模一样的。学会了yarn workspaces
,自然而然也就学会了npm和pnpm的了。
声明 worktree
worktree是通过传统package.json文件定义的。它们的特别之处在于它们具有以下属性:
- 他们必须声明一个
workspaces
字段,该字段应该是一个全局模式数组,用于定位组成工作树的工作空间。例如,如果您希望packages
文件夹内的所有文件夹都是工作区,只需添加packages/*
到此数组即可 - 它们必须以某种方式连接到项目级
package.json
文件。这在典型的工作区设置中并不重要,因为通常在项目级别定义一个工作树package.json
,但如果您尝试设置嵌套工作区,则必须确保嵌套工作树被定义为其父工作树的有效工作区(否则 Yarn 将无法找到其正确的父文件夹)
请注意,由于工作树是使用其他常规package.json
文件定义的,因此它们本身也是有效的工作区。如果它们被命名,其他工作区将能够正确地交叉引用它们。
WARNING
工作树过去被要求是私有的(即"private": true
在其 package.json 中列出)。此要求在 2.0 版本中被删除,以帮助独立项目逐步采用工作区(例如,将其文档网站列为单独的工作区)
workspace 意味着什么
workspace有两个重要的属性:
-
只能访问工作空间所依赖的依赖项。换句话说,我们严格执行您的工作区依赖性。这样做使我们能够干净地将项目彼此解耦,因为您不必将它们的所有依赖项合并到一个巨大的不可维护的列表中。我们仍然提供同时管理来自多个工作区的依赖项的工具,但需要显式使用它们并提供更好的集成(例如:
yarn add
可以根据其他工作区使用的内容为您的新依赖项提出建议,但您可以覆盖它们)。 -
如果包管理器要解析工作空间可以满足的范围,则在可能的情况下,它会优先选择工作空间分辨率而不是远程分辨率。这是
monorepo
方法的支柱:您的项目包将互连并使用存储在存储库中的代码,而不是使用注册表中的远程包。
workspace 范围(workspace:
)
虽然 Yarn 在匹配时自动选择工作区分辨率,但有时您绝对不想冒险使用远程注册表中的包,即使版本不匹配(例如,如果您的项目实际上并不意味着已发布,您只想使用工作区来更好地划分代码)。
对于这些用例,Yarn 现在支持从 v2: 开始的新解析协议workspace:
。使用此协议时,Yarn 将拒绝解析本地工作区以外的任何内容。这个范围协议有两种风格:
- 如果是 semver 范围,它将选择与指定版本匹配的工作区。
- 如果是项目相对路径,它将选择与该路径匹配的工作空间(实验)。
请注意,第二种风格是实验性的,我们建议暂时不要使用它,因为某些细节将来可能会发生变化。我们当前的建议是使用workspace:*
,它几乎总是能达到您的期望。
发布 workspaces
当工作区打包到存档中时(无论是通过yarn pack
还是像这样的发布命令之一yarn npm publish
),我们workspace:
通过以下方式动态替换任何依赖项:
- 目标工作区中的相应版本(如果您使用*、^、~或项目相对路径)
- 关联的 semver 范围(对于任何其他范围类型)
例如,如果我们假设有以下工作区,其当前版本为1.5.0
,则如下:
- {
- "dependencies": {
- "star": "workspace:*",
- "caret": "workspace:^",
- "tilde": "workspace:~",
- "range": "workspace:^1.2.3",
- "path": "workspace:path/to/baz"
- }
- }
将转化为:
- {
- "dependencies": {
- "star": "1.5.0",
- "caret": "^1.5.0",
- "tilde": "~1.5.0",
- "range": "^1.2.3",
- "path": "1.5.0"
- }
- }