跳到主内容
Version: Next

工作空间

pnpm 内置了对单一存储库(也称为多包存储库、 多项目存储库或单体存储库)的支持。 您可以创建一个 工作区以将多个项目合并到一个存储库中。

工作空间的 根目录中必须有 pnpm-workspace.yaml 文件。 工作空间的根目录中也可能有 .npmrc

工作空间协议 (workspace:)#

Added in: v3.7.0.

默认情况下,如果可用的软件包 与已声明的范围相匹配,pnpm 将从工作区链接包。 例如,如果 bar中有 "foo":"^1.0" 的依赖关系,则 [email protected] 链接到 bar 。 但是,如果 bar 在依赖项中有 "foo": "2.0.0" ,而[email protected] 不在工作区中,则 [email protected] 将从注册表安装。 这种行为带来了一些不确定性。

幸运的是,pnpm 支持 workspace: 协议。 当使用 此协议时,pnpm 将拒绝解析为 本地工作区包以外的任何内容。 因此,如果您设置 "foo": "workspace:2.0.0",这次 安装将失败,因为 "[email protected]" 不存在于工作区中。

link-workspace-packages 选项 设置为 false时,这个协议就格外有用。 在这种情况下,如果使用 workspace: 协议,那么 pnpm 将仅从工作空间软连接包。

通过别名引用工作空间包#

添加于:v5.12.0

假设您在工作区有一个名为 foo 的包。 通常你会像这样引用: "foo": "workspace:*"

如果要使用其他别名,那么以下语法也将起作用: "bar": "workspace:[email protected]*"

在发布之前,别名被转换为常规别名依赖项。 上面的 示例将变为: "bar": "npm:[email protected]"

通过相对路径引用工作区包#

添加于:v5.12.0

工作区内有两个软件包:

+ packages    + foo    + bar

bar 可能有 foo 其依赖项声明为这样"foo": "workspace:../foo"。 在发布之前,这些规范将转换为所有软件包管理器支持的 常规版本规范。

发布工作空间包#

当工作空间包打包到归档(无论它是通过 pnpm pack 还是 pnpm 发布之类的发布命令之一)时,我们动态 替换任何 工作空间: 依赖关系:

  • 目标工作空间中的对应版本(如果使用 workspace:*, workspace:~, or workspace:^
  • 相关的 semver 范围(对于任何其他范围类型)

例如,如果我们 foobarqarzoo并且它们的版本都是 1.5.0,则如下:

{    "dependencies": {        "foo": "workspace:*",        "bar": "workspace:~",        "qar": "workspace:^",        "zoo": "workspace:^1.5.0"    }}

将转化为:

{    "dependencies": {        "foo": "1.5.0",        "bar": "~1.5.0",        "qar": "^1.5.0",        "zoo": "^1.5.0"    }}

This feature allows you to depend on your local workspace packages while still being able to publish the resulting packages to the remote registry without needing intermediary publish steps - your consumers will be able to use your published workspaces as any other package, still benefitting from the guarantees semver offers.

Release workflow#

Versioning packages inside a workspace is a complex task and pnpm currently does not provide a built-in solution for it. However, there are 2 well tested tools that handle versioning and support pnpm:

For how to set up a repository using Rush, read this page.

For using Changesets with pnpm, read this guide.

Options#

link-workspace-packages#

Added in: v2.14.0

  • 默认值: true
  • Type: true, false, deep

If this is enabled, locally available packages are linked to node_modules instead of being downloaded from the registry. This is very convenient in a monorepo. If you need local packages to also be linked to subdependencies, you can use the deep setting (since v5).

Else, packages are downloaded and installed from the registry. However, workspace packages can still be linked by using the workspace: range protocol.

prefer-workspace-packages#

Added in: v5.13.0

  • Default: false
  • Type: Boolean

If this is enabled, local packages from the workspace are preferred over packages from the registry, even if there is a newer version of the package in the registry.

This setting is only useful if the workspace doesn't use save-workspace-protocol.

shared-workspace-lockfile#

Added in: v2.17.0 as shared-workspace-shrinkwrap

  • 默认值: true
  • Type: Boolean

If this is enabled, pnpm creates a single pnpm-lock.yaml file in the root of the workspace. This also means that all dependencies of workspace packages will be in a single node_modules (and get symlinked to their package node_modules folder for Node's module resolution).

Advantages of this option:

  • every dependency is a singleton
  • faster installations in a monorepo
  • fewer changes in code reviews as they are all in one file
note

Even though all the dependencies will be hard linked into the root node_modules, packages will have access only to those dependencies that are declared in their package.json, so pnpm's strictness is preserved. This is a result of the aforementioned symbolic linking.

save-workspace-protocol#

  • 默认值: true
  • Type: Boolean

If this is enabled, new dependencies will be added with the workspace protocol IF (and only if) they are present in the workspace.

You might want to change this setting to false if the tooling in your repository does not understand the workspace protocol (and ideally submit a PR to your tooling to get it added in the future).

故障排查#

pnpm cannot guarantee that scripts will be run in topological order if there are cycles between workspace dependencies. If pnpm detects cyclic dependencies during installation, it will produce a warning. If pnpm is able to find out which dependencies are causing the cycles, it will display them too.

If you see the message There are cyclic workspace dependencies, please inspect workspace dependencies declared in dependencies, optionalDependencies and devDependencies.

Usage examples#

Here are a few open source projects that use the workspace feature of pnpm:

  • Cycle.js (as of 9/21/2021, commit f2187ab6688368edb904b649bd371a658f6a8637)
  • Prisma (as of 9/21/2021, commit c4c83e788aa16d61bae7a6d00adc8a58b3789a06)
  • Verdaccio (as of 9/21/2021, commit 9dbf73e955fcb70b0a623c5ab89649b95146c744)
  • Rollup plugins (as of 9/21/2021, commit 53fb18c0c2852598200c547a0b1d745d15b5b487)