JS包管理
npm&yarn的基本原理
- 解析依赖包,解析为具体的一个版本号
- 下载解析好的依赖包 .tar到本地离线镜像
- 将tar从离线镜像解压到本地缓存(这个主要看系统的缓存路径 Mac的路径在/Library/Caches/Yarn/v6/下)
- 从缓存里拷贝到项目node_modules文件夹下
在npm1、2版本的时候,node_modules结构是这样的
//node_modules
└─ pkg1
├─ index.js
├─ package.json
└─ node_modules
└─ pkg2
├─ index.js
└─ package.json
// 存粹是嵌套的
// 而且每个嵌套包里面可能有相同的依赖,这样就存在依赖重复安装的问题
// 在4步骤时大量的I/O导致安装缓慢
从npm3开始使用 {扁平化依赖}
//node_modules
├─ pkg1
| ├─ index.js
| └─ package.json
└─ pkg2
├─ index.js
└─ package.json
//这就是把依赖包拍平了,解决了相同包的重新安装问题,但是带来几个问题
- a和b依赖不同版本的相同依赖npm怎么去处理?结构不确定
- npm的处理方式就是哪个包先在package中声明,哪个包相同依赖享受扁平化待遇,后声明的会被写到自身目录中的node_modules中
- 在npm5.x引入package-lock.json或yarn.lock来确定安装包结构的确定性
- webpack找到包的机制会导致项目中package.json中未声明的包,也可以被项目直接访问到
- 扁平化算法复杂性很高,耗时长
综上:npm或yarn当前还存在大量I/O、package非法访问、扁平算法复杂耗时较高
额外的: node_modules/.bin目录,集合了当前项目依赖中可执行脚本,创建软连接到.bin目录下,作为前缀添加给pkg.scripts
Yarn的PnP(Plug’n’Play)
去除了npm和yarn第四步操作,在实际项目中使用比较繁琐
目录
└─ .pnp
├─ externals
├─ package.json
└─ node_modules
└─ pkg2
├─ index.js
└─ package.json
//在项目中使用
yarn --pnp
//启用了pnp特性之后
{
"installConfig": {
"pnp": true
}
}
package 非法引用
就是访问未在package.json中声明的包
pnpm
node_modules目录结构
这是Mac上的软连接,类似windows上面的快捷方式,pkg不是一个真正的文件,只是引用
打开.pnpm,里面是这种结构
▾ node_modules
▾ .pnpm
▸ accepts@1.3.7
▸ array-flatten@1.1.1
...
▾ express@4.17.1
▾ node_modules
▸ accepts
▸ array-flatten
▸ body-parser
▸ content-disposition
...
▸ etag
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
// 这才是真正的依赖目录,跟npm1. 、2.的结构是一样的,是node原生支持的嵌套结构,避免了耗时的扁平化算法
//.pnpm中使用的是文件硬链接形式,减少磁盘的存储量,多个项目同样依赖可以使用同样的硬链接,不会重复安装同一个包
- pnpm的依赖和包本身放在同一个node_modules下面,完全兼容Node。
- 这种依赖管理方式还避免了依赖在扁平化话的时候,将package提升到node_modules的第一层目录,避免了项目中__非法引用__的问题
- 采用硬链接的形式,避免重复储存
- 在机器上有众多项目时(比如__打包机__上),使用pnpm能大幅提升安装以来时间,从而减少项目打包部署时间
相关链接:
https://loveky.github.io/2019/02/11/yarn-pnp/ PnP特性
https://blog.csdn.net/weixin_33738578/article/details/91412163 PnP的集成
https://github.com/arcanis/pnp-webpack-plugin pnp在webpack中的使用
https://github.com/pnpm/pnpm pnpm仓库及性能对比
https://juejin.cn/post/6932046455733485575 pnpm掘金文章
https://cloud.tencent.com/developer/article/1555982 npm解析文章