Javascript 节点中的require是否使用eval在另一个文件中运行代码
我只是想理解node中的模块。我了解了一些事情,比如node围绕放置在每个文件中的代码创建模块包装函数 假设有两个文件,a.js和b.js 在a.js中,当我第一次需要b.js时,b.js中的模块包装器函数将如何执行Javascript 节点中的require是否使用eval在另一个文件中运行代码,javascript,node.js,Javascript,Node.js,我只是想理解node中的模块。我了解了一些事情,比如node围绕放置在每个文件中的代码创建模块包装函数 假设有两个文件,a.js和b.js 在a.js中,当我第一次需要b.js时,b.js中的模块包装器函数将如何执行 node是否会执行以下操作:将b.js文件的全部内容作为字符串获取,然后使用eval从a.js执行,然后将此函数调用的结果保存在缓存中。当您确实需要时,node.js具有loader.js文件,该文件负责加载模块。通过loader.js文件执行以下步骤 首先,它检查缓存模块中是否存
node是否会执行以下操作:将b.js文件的全部内容作为字符串获取,然后使用
eval
从a.js执行,然后将此函数调用的结果保存在缓存中。当您确实需要时,node.js具有loader.js文件,该文件负责加载模块。通过loader.js文件执行以下步骤
// Check the cache for the requested file.
// 1. If a module already exists in the cache: return its exports object.
// 2. If the module is native: call `NativeModule.require()` with the
// filename and return the result.
// 3. Otherwise, create a new module for the file and save it to the cache.
// Then have it load the file contents before returning its exports
// object.
Module._load = function(request, parent, isMain) {
if (parent) {
debug('Module._load REQUEST %s parent: %s', request, parent.id);
}
var filename = Module._resolveFilename(request, parent, isMain);
var cachedModule = Module._cache[filename];
if (cachedModule) {
updateChildren(parent, cachedModule, true);
return cachedModule.exports;
}
if (NativeModule.nonInternalExists(filename)) {
debug('load native module %s', request);
return NativeModule.require(filename);
}
// Don't call updateChildren(), Module constructor already does.
var module = new Module(filename, parent);
if (isMain) {
process.mainModule = module;
module.id = '.';
}
Module._cache[filename] = module;
tryModuleLoad(module, filename);
return module.exports;
};
还可以查看本文以了解该过程是如何工作的
差不多
Node.js脚本文件内容和包含:
然后模块函数与vm一起运行。runInThisContext:
var wrapper = Module.wrap(content);
var compiledWrapper = vm.runInThisContext(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true
});
vm
模块提供并评估代码,类似于间接eval
:
runInThisContext()编译代码,在当前全局的上下文中运行并返回结果。运行的代码无权访问本地范围,但可以访问当前全局对象
由于vm.runInThisContext()无权访问本地作用域,因此localVar保持不变。相反,eval()确实可以访问本地范围,因此值localVar发生了更改。通过这种方式,vm.runInThisContext()非常类似于间接eval()调用,例如(0,eval)('code')
太棒了,我也给出了同样的答案,但是你解释得很好,这很简单,很短,并且获得了很多关于loader.js的模式知识。谢谢你reply@SourabhSomani不久前刚刚浏览了这部分节点源代码。很高兴它对你也有帮助。是的,它很有帮助。我在回答中也给出了节点源代码的链接。我还研究了源代码。关于源代码的最佳解释。。。。终极的。谢谢@Estus在require.js中也一样吗??
var wrapper = Module.wrap(content);
var compiledWrapper = vm.runInThisContext(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true
});