实际上*使用了什么版本的npm库?

时间:2017-08-12 22:38:34

标签: javascript node.js npm

我知道npm库安装后可以在分层树中安装同一个库的多个版本,如下所示:

a@0.1.0
  -> b@1.0
  -> c@2.0
       -> b@2.0

在上文中,版本为a的软件包0.1.0及其依赖项b@1.0c@2.0已被提取。同样,c@2.0的依赖性是 拉进来,这是b@2.0

我从某人那里听说,即使软件包b安装在两个不同的版本中,其中只有一个实际上已加载到内存中并使用。我也听说过这可能是也可能不是javascript与浏览器部署的节点部署。

所以我的问题是:只有一个b包加载到内存中是真的吗?如果是,对于节点和浏览器都是如此,还是存在差异?

1 个答案:

答案 0 :(得分:4)

的NodeJS

可以加载多个版本的Node模块/库,具体取决于它们的加载位置。 module loader is covered in depth in the Node.js文档。

require()根据已解析的文件路径调用caches modules

模块require('b')中的

a将解析为.../a/node_modules/b

模块require('b')中的

c将解析为.../a/node_modules/c/node_modules/b

因此,将为同一个呼叫加载单独的模块。这可以用一个小例子来证明。

模块B - node_modules/b/index.js

module.exports = {
  VERSION = 'b-0.5.0'
}

模块C - node_modules/c/index.js

module.exports = {
  VERSION: 'c-1.0.0',
  BVERSION: require('b').VERSION,
}

模块C的B副本 - node_modules/c/node_modules/b/index.js

module.exports = {
  VERSION: 'b-9.8.7',
}

创建程序以输出版本。

console.log('b', require('b').VERSION)
console.log('c', require('c').VERSION)
console.log('cb', require('c').BVERSION)

然后输出版本

→node index.js 
b b-0.5.0
c c-1.0.0
cb b-9.8.7

因此,使用require('b').VERSION的两个具有不同路径的模块会获得不同的值。

穿越

值得注意的是,如果Node.js require('b')无法找到本地安装的./node_modules/b,那么它将遍历目录树以在父b中查找node_modules }目录。

再次使用上面的示例案例,但删除a/node_modules/c/node_modules/b

模块c执行require('b')但无法找到...a/node_modules/c/node_modules/b然后它将进入父node_modules/并查找b,在这种情况下它会加载...a/node_modules/b

的缓存副本
→node index.js 
b b-0.5.0
c c-1.0.0
cb b-0.5.0

浏览器

浏览器没有npm模块的概念。您需要一个支持CommonJS模块的加载器,如Browserify或Webpack。如果加载器不遵守CommonJS / Node.js规则,那么它不太可能与npm包一起使用。

您应该可以使用您的加载程序打包上述示例,并查看其行为方式。