我想知道在node.js中使用require()
是否等同于延迟加载?
例如,如果我的函数需要我的代码中其他地方不需要的特定node.js包,那么我最好在该函数内部使用require()
来包含所需的包函数被调用。
由于我对node.js架构缺乏了解,我还不确定这是否能提供任何性能改进?我认为它将为我的服务器每个连接使用更少的内存。但是,当它必须读取包时,它是否会增加磁盘的I / O,或者这将是一次性的将其存入内存?
如果是这种情况我应该在多大程度上采取这种做法,我是否应该尝试尽可能多地编写node.js软件包呢?
答案 0 :(得分:33)
require()
是按需加载。加载模块后,如果再次运行require()调用,则不会重新加载。通过将其放在函数而不是顶级模块代码中,您可以延迟其加载,或者如果您从未实际调用该函数,则可能会避免加载。但是,require()
是同步的并且从磁盘加载模块,因此最佳做法是在应用程序开始提供请求之前加载应用程序启动时所需的任何模块,然后确保在应用程序运行时仅发生异步IO。
Node是单线程的,因此加载模块的内存占用量不是每个连接,而是每个进程。加载模块是一次性的,可以将其存入内存。
在开始处理请求之前,只需坚持此约定并在应用程序的顶级范围内需要所需的模块。我认为这是一个例子,如果你不得不问是否需要以不寻常的方式编写代码,你不需要以不寻常的方式编写代码。
答案 1 :(得分:5)
如果您想延迟加载模块,现在可以使用ES6(Node v6)
编辑:如果您需要访问require的属性(如 require.cache)。
module.js
console.log('Module was loaded')
exports.d=3
main.js
var _require = require;
var require = function (moduleName) {
var module;
return new Proxy(function () {
if (!module) {
module = _require(moduleName)
}
return module.apply(this, arguments)
}, {
get: function (target, name) {
if (!module) {
module = _require(moduleName)
}
return module[name];
}
})
};
console.log('Before require');
var a = require('./module')
console.log('After require');
console.log(a.d)
console.log('After log module');
输出
Before require
After require
Module was loaded
3
After log module