pnpm 简介

本文引用自 摸鱼wiki

1. 与npm,yarn性能比较

action cache lockfile node_modules npm pnpm Yarn Yarn PnP
install 33.8s 20.1s 20.3s 40.7s
install 2.1s 1.4s 2.6s n/a
install 9.1s 5.3s 7.8s 1.7s
install 13.5s 9.3s 14.1s 7.7s
install 15s 17.2s 14.2s 33.4s
install 2.5s 3s 8.8s n/a
install 2s 1.4s 8.7s n/a
install 2.5s 11.2s 14.7s n/a
update n/a n/a n/a 8.9s 12s 6.9s 14.9s

2. 基于符号链接的node_modules文件组织架构

下图摘自官网,基本说明了 pnpm 的文件组织以及运行方式。

pnpm 简介_第1张图片

pnpm 会统一管理整个系统安装的项目包,并将其统一保存在名为 .pnpm-store 的文件夹内。对于一个新项目来说,项目的 node_modules 由多个依赖库 + .pnpm 组成。pnpm 会将项目依赖包以 包名@版本号 命名的文件夹的形式平铺在项目的 .pnpm 文件夹内,而每个文件夹内部的 node_modules 则会存储库自身及其依赖库。其中,库自身以硬链接的方式指向 .pnpm-store 文件夹内的同名同版本库(图中的红色虚线),并在项目的 node_modules 下创建同名同版本的软链接(图中的绿色实线);库的前置依赖则会以软链接的方式指向当前项目的 .pnpm 文件夹下的同名同版本库(图中的黄色实线)。

图中的实例为了展示库的版本号,可能与实际的目录结构有所偏差。实际上对于项目的 node_modules 的库,为了保持兼容性,是没有版本号的后缀的。最后的目录结构可以参考下面的代码:

node_modules
├── bar -> ./.pnpm/[email protected]/node_modules/bar
└── .pnpm
    ├── [email protected]
    │   └── node_modules
    │       └── foo -> /foo
    └── [email protected]
        └── node_modules
            ├── bar -> /bar
            └── foo -> ../../[email protected]/node_modules/foo

3. 解决 peers

那这时候有个问题,如果项目中多个库有相同的前置依赖库,但各自依赖的版本不一样,会怎么样?

这个问题npm曾经解决过,他的解决方法是先安装的依赖库版本平铺在项目的 node_modules 文件夹内,后续安装的写在依赖该库的 node_modules 文件夹内,形如:

// bar
{
  "dependencies": {
    "baz": "2.0.0"
  }
}

// foo
{
  "dependencies": {
    "baz": "1.0.0"
  }
}

node_modules
├── bar
│   └── node_modules
│       └── [email protected]
├── foo
└── [email protected]

但这样存在一个问题,如果后续有个库quz依赖 [email protected],这种情况下 [email protected] 会在quz目录下重新再次安装,浪费磁盘空间。而在pnpm下,所有的依赖库都是以硬链接 + 软链接的方式组织,全局只保留一份代码,因此不会有这个问题。

node_modules
├── bar -> ./.pnpm/[email protected]/node_modules/bar
├── foo -> ./.pnpm/[email protected]/node_modules/foo
└── .pnpm
    ├── [email protected]
    │   └── node_modules
    │       ├── foo -> /foo
    │       └── baz -> ../../[email protected]/node_modules/baz
    ├── [email protected]
    │   └── node_modules
    │       ├── bar -> /bar
    │       └── baz -> ../../[email protected]/node_modules/baz
    ├── [email protected]
    └── [email protected]

更多例子可以查看 how-peers-are-resolved

4. yarn,npm迁移到pnpm

官网有对应的解决方法,使用 pnpm import  从另一个软件包管理器的 lock 文件生成 pnpm-lock.yaml。支持源文件:

  • package-lock.json
  • yarn.lock
  • npm-shrinkwrap.json

你可能感兴趣的:(前端,javascript,pnpm)