「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
很久以前:嵌套结构
在 npmv2
时,node_modules
对于各个 package 的拓扑为嵌套结构。
假设:
- 项目依赖
package-a
与package-b
两个 package package-a
与package-b
均依赖lodash@4.17.4
依赖关系以 Markdown 列表表示:
+ package-a
+ `lodash@4.17.4`
+ package-b
+ `lodash@4.17.4`
此时 node_modules
目录结构如下:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
A ---> C("lodash@4.17.4")
B ---> D("lodash@4.17.4")
此时最大的问题
- 嵌套过深
- 占用空间过大
现在阶段: 平铺结构
在 npmv3
之后 node_modules
为平铺结构,拓扑结构如下:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
一个问题: 以下依赖最终 node_modules 结果如何?
可参考该示例
依赖关系以 Markdown 列表表示
+ package-a
+ `lodash@^4.17.4`
+ package-b
+ `lodash@^4.16.1`
答: 与上拓扑结构一致,因为二者为 ^
版本号,他们均会下载匹配该版本号范围的最新版本,比如 @4.17.4
,因此二者依赖一致。
此时如果有 lock,会有一点小问题,待稍后讨论
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
再一个问题: 以下依赖最终 node_modules 结果如何?
可参考该示例
+ package-a
+ `lodash@4.17.4`
+ package-b
+ `lodash@4.16.1`
答:package-b 先从自身 node_modules 下寻找 lodash
,找到 lodash@4.16.1
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
B ---> D("lodash@4.16.1")
再一个问题: 以下依赖最终 node_modules 结果如何
+ package-a
+ `lodash@4.0.0`
+ package-b
+ `lodash@4.0.0`
+ package-c
+ `lodash@3.0.0`
+ package-d
+ `lodash@3.0.0`
答:package-d 只能从自身的 node_modules 下寻找 lodash@3.0.0
,而无法从 package-c 下寻找,此时 lodash@3.0.0 不可避免地会被安装两次
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C(package-c)
app ---> D(package-d)
app ---> X("lodash@4.0.0")
C ---> Y("lodash@3.0.0")
D ---> Z("lodash@3.0.0")
现在阶段问题: 重复的版本依赖有什么问题?
- Install Size,安装体积变大,浪费磁盘空间
- Build Size,构建打包体积变大,浪费带宽,网站打开延迟,破坏用户体验 (PS: 支持 Tree Shaking 会好点)
- 破坏单例模式,破坏缓存,如 postcss 的许多插件将 postcss 扔进 dependencies,重复的版本将导致解析 AST 多次