1

PnP

可能没用过 php 的不知到 composer(php的包管理器) 其实 yarn2 的 pnp 其实就是借鉴了 composer 的对加载模块时候的处理方法。yarn 会创建一个静态映射表包含了以下的信息:

  • 当前依赖树中包含了哪些依赖包的哪些版本
  • 这些依赖包是如何互相关联的
  • 这些依赖包在文件系统中的具体位置

然后就能将以前安装包的方式:

  1. 将依赖包的版本区间解析为某个具体的版本号
  2. 下载对应版本依赖的压缩包到本地离线镜像
  3. 将依赖从离线镜像解压到本地缓存
  4. 将依赖从缓存拷贝到当前目录的 node_modules 目录
  5. ...

如果换成 pnp

  1. 没有变化,下载对应版本依赖的压缩包到本地离线镜像
  2. 没有变化,依然离线镜像解压到本地缓存
  3. 生成 .pnp.js 文件

如果再加上 yarn2 的 Zip loading

  1. 从网络上下载对应版本的压缩包,(镜像和缓存之间没有更多区别-它们是相同的,都是压缩包)
  2. 生成 .pnp.js 文件

可见对我们新安装包的过程的操作已将压缩到了极限,然后对于 ci 环境更有帮助,如果在 .gitignore 中没有加入 .yarn/ceche 文件夹的话,我们甚至不需要 yarn install,而且保证了开发环境与测试环境依赖包的绝对一致

Zip Loading

当然你可能会有疑问依赖都还在 zip 压缩包中,那运行时候怎么办

PnP运行时 (.pnp.js) 会自动对 nodejs 的 fs 模块进行补丁,以增加对压缩文件内部文件访问的支持。

怎么做的:(只是猜测)

const {readFileSync} = require(`fs`);

// Looks similar to `/path/to/.yarn/cache/lodash-npm-4.17.11-1c592398b2-8b49646c65.zip/node_modules/lodash/ceil.js`
const lodashCeilPath = require.resolve(`lodash/ceil`);

console.log(readFileSync(lodashCeilPath));

更多

当然 yarn2(.1) 除了 pnp 和 zip loading 之外还有其他的升级

  • 插件支持:(比如安装的时候自动安装上 @types/xxx 的定义文件)也可以自己去写
  • 更好 workspaces  的支持:可以在一个 repo 中管理多个包
  • Windows 上对 bash 常规操作的支持 再也不用安装 cross-env rimraf(这个还是要装,最高效删除 node_modules 的方法)
  • 新协议的支持 file/patch(patch-package)/portal(能解决依赖的 link)/git
  • 如果文件中有 package-lock.json 将会使用 npm 来安装
  • ......

在 vscode 中使用 https://yarnpkg.com/advanced/editor-sdks#vscode  并且安装 https://marketplace.visualstudio.com/items?itemName=arcanis.vscode-zipfs 这个插件

WebStorm 直接就可以用,但是对 TS 的支持还有问题,(必须要先打开那个TS文件才有提示)

参考


skywalker512
23 声望0 粉丝