npm3扁平化
比如,我们有以下需要安装的模块,安装顺序从上到下:
// npm 2
node_modules
├─┬ A
| └── C1
└─┬ B
| └── C2
└── C3
安装过程:
npm i A时,查找顶层依赖里有没有C,没有C就将C1放入顶层依赖里npm i B时,查找顶层依赖里有没有C,这时有C1,判断C1是否兼容B中C的版本声明,如果不兼容,将C2放入B自己的node_modules里- 如果兼容,保持顶层
C1不变
- 如果兼容,保持顶层
npm i C3时,直接将C3放入顶层依赖,寻找那些“有提升(如1)”的依赖,判断C3是否兼容自己对C的版本声明,不兼容则重新找包并放入自己的node_modules里- 如果兼容,则不做操作
node_modules的文件嵌套关系都保存在package-lock.json中,由于package.json中排序并不是按照安装顺序进行排的序,所以如果你只有package.json进行npm i时得到的package-lock.json文件可能不一致。
- 可见安装顺序不同,
node_modules的嵌套关系也不同 - 当删除项目依赖时,如果该依赖有其它子依赖的复用,该依赖并不会真正删除
- 当依赖升级时,首先执行删除操作(包括他的依赖),再安装新版本,这时可能会将顶层的依赖升级到和其它包的子依赖一致的版本,造成包的重复,这时可以使用
npm find-dupes来查找这些重复的依赖项,npm dedupe来移除这也重复依赖
yarn扁平化
首先yarn-lock就是完全扁平的,包含所有依赖的版本声明所满足的具体版本
"debug@^3.2.7":
"version" "3.2.7"
dependencies:
"ms" "^2.1.1"
"debug@^4.0.0", "debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@^4.3.2", "debug@^4.3.4", "debug@4":
"version" "4.3.4"
dependencies:
"ms" "2.1.2"
"ms@^2.1.1", "ms@2.1.2":
"version" "2.1.2"
所有包都在顶层node_modules中,但
- 子依赖包,引用次数最多的放在顶层依赖中,如果次数一样,最低版本放入顶层依赖中。
- 直接依赖包,直接依赖放入顶层依赖中,其它版本放子目录里。
可见
yarn对安装顺序并不敏感,node_modules只和引用次数、版本大小、是否是直接依赖有关yarn-lock需要package.json文件才能恢复node_modules