npm 扁平化包带来的好处以及缺陷

在 npm 2.x 的时候,会依次解压处理包的依赖关系,所以 node_modules​ 层级非常深

例如:A 依赖于 B,B 依赖于 C 那么,层级关系就会成为:

- A
  - B
    - C

即使有完全相同的依赖,也会再次复制。

例如:

- A
  - B
    - C
- A2
  - B
    - C

而 npm 3.x 之后,会将包扁平化到 node_modules 目录下

上面的例子就会变成:

- A
- A2
- B
- C

一切似乎都很好,消除了大量的重复依赖。

但是,扁平化处理包的依赖关系带来了潜在的幽灵依赖问题(即在项目中直接使用了未在 package.json​ 中声明的包):

举个例子: A 依赖于 B,那么 A 和 B 都会被扁平化到 node_modules 目录下。此时,我们在项目中可以直接导入 B 这个包,即使这个包没有在 package.json 中声明,这时候项目跑起来还没啥问题。

但是如果后续 A 包更新版本后不再依赖于 B 包,很显然,我们重新安装依赖后 B 包也就不会扁平化到 node_modules 目录下。

此时,项目引入 B 包就报错了 —— 任何代码都没更改,仅仅因为某个包更新后不再依赖 B 包了,项目就跑不起来了,这就很坑爹吧 = =。

另外,pnpm​不存在这样的非法访问问题。