npm与pnpm包安装流程的差异对比
发表于 2024-06-04
更新于 2024-06-04
分类于 技术专栏
阅读量 107
字数统计 4074
这篇文章源于一道面试题:npm install的流程,包冲突怎么处理?pnpm有什么区别?
1、npm的安装
npm安装模式整体进行过两次大升级,如下,原先使用嵌套模式,但是会带来安装包的重复安装,浪费了很多硬盘空间,之后改成扁平模式,稍微解决了一些空间的浪费
- 嵌套模式:
- 扁平模式
1.1、实践一下
我在本地测试一下最新的npm版本(v8.12.1)
,新建了一个项目,引入testnpma
包,和testnpmb
包,二者共同依赖于testnpm
包,但是依赖的版本不一样,testnpmb
依赖的是testnpm
包的2.0.0
版本,testnpma
依赖的是1.0.0
版本。
安装之后生成的package-lock.json文件:
1{ 2 "name": "testnpmc", 3 "version": "1.0.0", 4 "lockfileVersion": 2, 5 "requires": true, 6 "packages": { 7 "": { 8 "name": "testnpmc", 9 "version": "1.0.0", 10 "license": "ISC", 11 "dependencies": { 12 "testnpma": "^1.0.0", 13 "testnpmb": "^1.0.0" 14 } 15 }, 16 "node_modules/testnpm": { 17 "version": "1.0.0", 18 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpm/-/testnpm-1.0.0.tgz", 19 "integrity": "sha512-zhyO/zUkqvGEgt4tuIQcACpMc9ZNiO/u/tUkcqOHQWaUD+H/Jz52gtlNrXUFz9IgrA9wVjOblys4KTQPsj/R5Q==", 20 "license": "ISC" 21 }, 22 "node_modules/testnpma": { 23 "version": "1.0.0", 24 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpma/-/testnpma-1.0.0.tgz", 25 "integrity": "sha512-t+HAnmWna6YlUPrkinmMvYNAl9SYr3WpBdrvIAFeMwdbp1YDVA7soYF7+qwpQBtd4jyGHs8HGANurzEFyMLKkg==", 26 "license": "ISC", 27 "dependencies": { 28 "testnpm": "^1.0.0" 29 } 30 }, 31 "node_modules/testnpmb": { 32 "version": "1.0.0", 33 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpmb/-/testnpmb-1.0.0.tgz", 34 "integrity": "sha512-pieeDuQ4JZaVBfQgkyvXEbjjN2kYek18MGpnxcccQXbcVvvf+AVMf+avj1VBkxo5jm7erfWN96ym0HVeHiAJKw==", 35 "license": "ISC", 36 "dependencies": { 37 "testnpm": "^2.0.0" 38 } 39 }, 40 "node_modules/testnpmb/node_modules/testnpm": { 41 "version": "2.0.0", 42 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpm/-/testnpm-2.0.0.tgz", 43 "integrity": "sha512-+GXGVhkN23cAoy9zLq+tTwqw1RviM18KNyOv0SVnciXbzAiNBDMztu6CIASsmGJ6impbWRWfq8zzhmJSPMtKlw==", 44 "license": "ISC" 45 } 46 }, 47 "dependencies": { 48 "testnpm": { 49 "version": "1.0.0", 50 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpm/-/testnpm-1.0.0.tgz", 51 "integrity": "sha512-zhyO/zUkqvGEgt4tuIQcACpMc9ZNiO/u/tUkcqOHQWaUD+H/Jz52gtlNrXUFz9IgrA9wVjOblys4KTQPsj/R5Q==" 52 }, 53 "testnpma": { 54 "version": "1.0.0", 55 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpma/-/testnpma-1.0.0.tgz", 56 "integrity": "sha512-t+HAnmWna6YlUPrkinmMvYNAl9SYr3WpBdrvIAFeMwdbp1YDVA7soYF7+qwpQBtd4jyGHs8HGANurzEFyMLKkg==", 57 "requires": { 58 "testnpm": "^1.0.0" 59 } 60 }, 61 "testnpmb": { 62 "version": "1.0.0", 63 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpmb/-/testnpmb-1.0.0.tgz", 64 "integrity": "sha512-pieeDuQ4JZaVBfQgkyvXEbjjN2kYek18MGpnxcccQXbcVvvf+AVMf+avj1VBkxo5jm7erfWN96ym0HVeHiAJKw==", 65 "requires": { 66 "testnpm": "^2.0.0" 67 }, 68 "dependencies": { 69 "testnpm": { 70 "version": "2.0.0", 71 "resolved": "http://192.168.3.110:8081/repository/npm-all/testnpm/-/testnpm-2.0.0.tgz", 72 "integrity": "sha512-+GXGVhkN23cAoy9zLq+tTwqw1RviM18KNyOv0SVnciXbzAiNBDMztu6CIASsmGJ6impbWRWfq8zzhmJSPMtKlw==" 73 } 74 } 75 } 76 } 77} 78
虽然硬盘空间浪费的问题得到了缓解,但同时这种扁平化的处理方式自身也存在许多问题,其中最为明显的问题就是”幽灵依赖“。
所谓的幽灵依赖是指我们明明没有在 package.json
的 dependencies 里声明某个依赖,但在代码里却可以 import 进来。原因很简单,因为项目依赖被铺平了,那么依赖的依赖自然也是可以被引入到项目中。
幽灵依赖带来的弊端很明显:我们显式依赖了A,A又依赖了B,这时候我们在项目中直接使用B是可以的,但如果某一天A不再依赖于B,那么我们项目中使用B的地方就会报错。
2、pnpm
的安装
pnpm
的安装模式完全颠覆了npm
留下的大坑,借助于系统的软链接
和硬链接
,以及.pnpm
的扁平模式,彻底解决了上述的所有问题。
还是基于上述的项目结构,我可以看node_modules
目录下的层次如下:
也就是说,所有的依赖都是从全局 store 硬链接到了 node_modules/.pnpm
下,然后之间通过软链接来相互依赖。
公众号关注一波~
网站源码:linxiaowu66 · 豆米的博客
Follow:linxiaowu66 · Github
关于评论和留言
如果对本文 npm与pnpm包安装流程的差异对比 的内容有疑问,请在下面的评论系统中留言,谢谢。