pnpm vs纱线:monorepo node_modules

pnpm(自v2.17起)和Yarn(自v1.12起)都支持在monorepos中进行快速并发安装。 但是,它们在monorepos中存储依赖项的方式之间存在很大差异。 Yarn尝试将所有工作空间软件包中的所有依赖关系提升到node_modules的根node_modules中,这意味着软件包可以访问工作空间中其他软件包的依赖关系。 这在Yarn文档中进行了描述:

在工作空间中发布程序包时要小心。 如果您正在准备下一个版本,并且决定使用新的依赖项,但是忘记在package.json文件中声明它,那么如果另一个软件包已经将该依赖项下载到工作区根目录中,则测试可能仍会在本地通过。 但是,对于将其从注册表中拉出的用户而言,它会被破坏,因为依赖项列表现在不完整,因此他们无法下载新的依赖项。 当前,在这种情况下无法发出警告。

像Yarn一样,pnpm将所有软件包都吊起。 但是,pnpm将所有依赖项存储在一个隐藏的文件夹中,并且仅将每个包的直接依赖node_modules接到它们的node_modules

让我们来看一个简单的例子中Yarn和pnpm的工作方式:

  • 有一个带有两个软件包的小型monorepo: foobar
  • foo具有is-negative@1.0.0作为依赖项
  • bar具有is-positive@1.0.0作为依赖项

要使此仓库与Yarn一起使用,应在package.json的根目录中包含package.json ,其中应包含以下内容:

 { "private": true, "workspaces": ["foo", "bar"] } 

要安装所有工作空间软件包的所有依赖项,您应该运行yarn install

在这里 查看结果

在这种情况下,Yarn将在node_modules的根目录中创建一个具有is-negativeis-positive的单个node_modules 。 这意味着foobar都可以访问彼此的依赖项。

要在此存储库中使pnpm安装依赖项,您需要在存储库的根目录(可以为空)中创建一个pnpm-workspace.yaml ,并创建一个具有以下内容的.npmrc文件:

 shared-workspace-shrinkwrap = true link-workspace-packages = true 

要使用pnpm安装所有工作区软件包的所有依赖项,应运行pnpm multi install (或仅运行pnpm mi )。

在这里 查看结果

像Yarn一样, node_modules在回购的根目录中创建一个node_modules 。 但是,如果打开该文件夹,则会看到所有目录和文件都隐藏在该文件夹中:

 node_modules + .registry.npmjs.org + .modules.yaml + .shrinkwrap.yaml 

node_modules存储所有依赖项,但它们隐藏在.registry.npmjs.org 。 Node的解析算法将找不到它们。

现在,如果您检查bar的目录,您node_modules在其中看到一个node_modules ,其中有一个名为is-negative符号链接。 此符号链接指向../../node_modules/.registry.npmjs.org/is-negative/1.0.0/node_modules/is-negative 。 同样,在foonode_modules目录中也有一个指向is-positive的符号链接。 所以foo只能解析is-positivebar只能解析is-negative 🎉😊


如您所见,pnpm不仅在与单个package.json一起使用时很严格,而且在多软件包存储库中也很严格。