npm版本嵌套

289 阅读2分钟

3.1 嵌套结构(以前版本)

npm 的早期版本, npm 处理依赖的方式简单粗暴,以递归的形式,严格按照 package.json 结构以及子依赖包的 package.json 结构将依赖安装到他们各自的 node_modules 中。直到有子依赖包不再依赖其他模块

例如:我的模块my-app现在依赖了两个模块:bufferignore:

{"name": "my-app",
"dependencies": {
"buffer": "^5.4.3",
"ignore": "^5.1.4",}
}

其中ignore是不依赖其他任何模块,而buffer又依赖了下面两个模块:base64-js , ieee754:

{"name": "buffer",
"dependencies": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"}
}

那么,执行npm install 后,得到的node_modules中模块目录结构就如下图

但是如果依赖模块太多,会使嵌套层级非常深

3.2扁平结构

  • 安装模块时,不管其是直接依赖还是子依赖的依赖,优先将其安装在 node_modules 根目录。

还是上面的依赖结构,我们在执行 npm install 后将得到下面的目录结构

如果我们在模块中又依赖了base64-js@1.0.1版本

{"name": "my-app",
"dependencies": {
"buffer": "^5.4.3",
"ignore": "^5.1.4",
"base64-js": "1.0.1",
 }
}

当安装到相同模块时,判断已安装的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下安装该模块

对应的,如果我们在项目代码中引用了一个模块,模块查找流程如下:

  • 在当前模块路径下搜索
  • 在当前模块 node_modules 路径下搜素
  • 在上级模块的 node_modules 路径下搜索
  • ...
  • 直到搜索到全局路径中的 node_modules

假设我们又依赖了一个包 buffer2@^5.4.3,而它依赖了包 base64-js@1.0.3,则此时的安装结构是下面这样的:

所以 npm 3.x 版本并未完全解决老版本的模块冗余问题,甚至还会带来新的问题。

试想一下,你的APP假设没有依赖 base64-js@1.0.1 版本,而你同时依赖了依赖不同 base64-js 版本的 bufferbuffer2。由于在执行 npm install 的时候,按照 package.json 里依赖的顺序依次解析,则 bufferbuffer2package.json 的放置顺序则决定了 node_modules 的依赖结构:

先依赖buffer2

先依赖buffer

这样的依赖结构不确定性会带来很多问题