我只是想了解节点中的模块。我了解到诸如node围绕每个文件中放置的代码创建模块包装器函数之类的事情。
假设有两个文件,即a.js和b.js
在a.js中,当我第一次需要b.js时,如何执行b.js中存在的模块包装函数。
节点是否执行类似的操作,将b.js文件的全部内容作为字符串获取,然后使用eval
从a.js执行,然后将该函数调用的结果保存在缓存中。
答案 0 :(得分:2)
或多或少。
Node.js loads脚本文件内容和wraps和module wrapper:
Module.wrap = function(script) {
return Module.wrapper[0] + script + Module.wrapper[1];
};
Module.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];
然后模块功能为evaluated和vm.runInThisContext
:
var wrapper = Module.wrap(content);
var compiledWrapper = vm.runInThisContext(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true
});
vm
模块提供了V8 execution context,并且vm.runInThisContext
与间接eval
类似地评估代码:
vm.runInThisContext()编译代码,在当前全局变量的上下文中运行它并返回结果。正在运行的代码无权访问本地范围,但有权访问当前的全局对象。
<...>
由于vm.runInThisContext()无法访问本地范围,因此localVar保持不变。相反,eval()确实可以访问本地范围,因此更改了localVar值。这样vm.runInThisContext()非常类似于间接eval()调用,例如(0,eval)(“代码”)。
答案 1 :(得分:1)
当您确实需要时,node.js具有负责加载模块的loader.js文件。以下步骤由loader.js文件执行
我们知道node是开源的,我直接给了node.js的loader.js的github路径
这是Node.js团队编写的Module._load函数的代码
// 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;
};
也请查看本文以了解流程的工作原理