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
不存在这样的非法访问问题。