npm3的扁平化和yarn的扁平化

440 阅读2分钟

npm3扁平化

比如,我们有以下需要安装的模块,安装顺序从上到下:

// npm 2
node_modules
├─┬ A
| └── C1
└─┬ B
| └── C2
└── C3

安装过程:

  1. npm i A时,查找顶层依赖里有没有C,没有C就将C1放入顶层依赖里
  2. npm i B时,查找顶层依赖里有没有C,这时有C1,判断C1是否兼容BC的版本声明,如果不兼容,将C2放入B自己的node_modules
    • 如果兼容,保持顶层C1不变
  3. 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