我知道npm库安装后可以在分层树中安装同一个库的多个版本,如下所示:
a@0.1.0
-> b@1.0
-> c@2.0
-> b@2.0
在上文中,版本为a
的软件包0.1.0
及其依赖项b@1.0
和c@2.0
已被提取。同样,c@2.0
的依赖性是
拉进来,这是b@2.0
。
我从某人那里听说,即使软件包b
安装在两个不同的版本中,其中只有一个实际上已加载到内存中并使用。我也听说过这可能是也可能不是javascript与浏览器部署的节点部署。
所以我的问题是:只有一个b
包加载到内存中是真的吗?如果是,对于节点和浏览器都是如此,还是存在差异?
答案 0 :(得分:4)
可以加载多个版本的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包一起使用。
您应该可以使用您的加载程序打包上述示例,并查看其行为方式。