Open kangyana opened 1 year ago
当 require('package-hello') 时,假设 package-hello 是一个 npm 库,我们是如何找到该 package 的?
require('package-hello')
package-hello
node_modules/package-hello
../node_modules/package-hello
在 npmv2 时,node_modules 对于各个 package 的拓扑为嵌套结构。
node_modules
假设:
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")
此时最大的问题:
目前在 npm/yarn 中仍然为平铺结构,但 pnpm 使用了更省空间的方法,以后将会提到 在 npmv3 之后 node_modules 为平铺结构,拓扑结构如下: graph app(node_modules) ---> A(package-a) app ---> B(package-b) app ---> C("lodash@4.17.4")
目前在 npm/yarn 中仍然为平铺结构,但 pnpm 使用了更省空间的方法,以后将会提到 在 npmv3 之后 node_modules 为平铺结构,拓扑结构如下:
graph app(node_modules) ---> A(package-a) app ---> B(package-b) app ---> C("lodash@4.17.4")
可参考该示例 依赖关系以 Markdown 列表表示: - package-a - `lodash@^4.17.4` - package-b - `lodash@^4.16.1`
可参考该示例 依赖关系以 Markdown 列表表示:
- package-a - `lodash@^4.17.4` - package-b - `lodash@^4.16.1`
答:与上拓扑结构一致,因为二者为 ^ 版本号,他们均会下载匹配该版本号范围的最新版本,比如 @4.17.4,因此二者依赖一致。
^
@4.17.4
注意:此时如果有 lock,会有一点小问题,待稍后讨论
node_modules 目录结构如下图:
可参考该示例 - package-a - `lodash@4.17.4` - package-b - `lodash@4.16.1`
可参考该示例
- package-a - `lodash@4.17.4` - package-b - `lodash@4.16.1`
答:package-b 先从自身 node_modules 下寻找 lodash,找到 lodash@4.16.1
lodash
lodash@4.16.1
graph app(node_modules) ---> A(package-a) app ---> B(package-b) app ---> C("lodash@4.17.4") B ---> D("lodash@4.16.1")
- 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 不可避免地会被安装两次。
package-d
lodash@3.0.0
package-c
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")
可参考 npm doppelgangers
1. 基础
当
require('package-hello')
时,假设package-hello
是一个 npm 库,我们是如何找到该 package 的?node_modules/package-hello
目录../node_modules/package-hello
目录,以此递归查找2. 很久以前: 嵌套结构
在 npmv2 时,
node_modules
对于各个 package 的拓扑为嵌套结构。假设:
package-a
与package-b
两个 packagepackage-a
与package-b
均依赖lodash@4.17.4
依赖关系以 Markdown 列表表示:
此时
node_modules
目录结构如下:此时最大的问题:
3. 现在阶段: 平铺结构
情况1:以下依赖最终 node_modules 结果如何?
答:与上拓扑结构一致,因为二者为
^
版本号,他们均会下载匹配该版本号范围的最新版本,比如@4.17.4
,因此二者依赖一致。node_modules
目录结构如下图:情况2:以下依赖最终 node_modules 结果如何?
答:
package-b
先从自身node_modules
下寻找lodash
,找到lodash@4.16.1
node_modules
目录结构如下图:情况3:以下依赖最终
node_modules
结果如何?答:
package-d
只能从自身的node_modules
下寻找lodash@3.0.0
,而无法从package-c
下寻找,此时lodash@3.0.0
不可避免地会被安装两次。node_modules
目录结构如下图:4. 重复的版本依赖有什么问题?
可参考 npm doppelgangers