PnP
可能没用过 php 的不知到 composer(php的包管理器) 其实 yarn2 的 pnp 其实就是借鉴了 composer 的对加载模块时候的处理方法。yarn 会创建一个静态映射表包含了以下的信息:
- 当前依赖树中包含了哪些依赖包的哪些版本
- 这些依赖包是如何互相关联的
- 这些依赖包在文件系统中的具体位置
然后就能将以前安装包的方式:
- 将依赖包的版本区间解析为某个具体的版本号
- 下载对应版本依赖的压缩包到本地离线镜像
- 将依赖从离线镜像解压到本地缓存
- 将依赖从缓存拷贝到当前目录的
node_modules
目录 - ...
如果换成 pnp
- 没有变化,下载对应版本依赖的压缩包到本地离线镜像
- 没有变化,依然离线镜像解压到本地缓存
- 生成
.pnp.js
文件
如果再加上 yarn2 的 Zip loading
- 从网络上下载对应版本的压缩包,(镜像和缓存之间没有更多区别-它们是相同的,都是压缩包)
- 生成
.pnp.js
文件
可见对我们新安装包的过程的操作已将压缩到了极限,然后对于 ci 环境更有帮助,如果在 .gitignore 中没有加入 .yarn/ceche 文件夹的话,我们甚至不需要 yarn install,而且保证了开发环境与测试环境依赖包的绝对一致
Zip Loading
当然你可能会有疑问依赖都还在 zip 压缩包中,那运行时候怎么办
PnP运行时 (.pnp.js
) 会自动对 nodejs 的 fs 模块进行补丁,以增加对压缩文件内部文件访问的支持。
怎么做的:(只是猜测)
- 对 zip 文件从新实现了一套 fs 接口
- 创建了一个编译到 WebAssembly 的 zlib+libzip 绑定的库
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文件才有提示)
参考
- https://yarnpkg.com/getting-started/install#per-project-install
- https://yarnpkg.com/advanced/editor-sdks
- https://dev.to/arcanis/yarn-2-1-git-workspaces-focused-installs-loose-mode-live-playground-4kfc
- https://dev.to/arcanis/introducing-yarn-2-4eh1
- https://dev.to/arcanis/plugin-systems-when-why-58pp
- https://dev.to/arcanis/plugnplay-and-tink-4684
- https://stackoverflow.com/questions/60184159/yarn-v2-gitignore
- https://stackoverflow.com/questions/53135221/what-does-yarn-pnp
- https://stackoverflow.com/questions/34295675/read-zip-file-in-node-js
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。