这是nodejs源码module.js的代码 https://github.com/nodejs/node/blob/master/lib/module.js const NativeModule = require(‘native_module’); const util = require(‘util’); const internalModule = require(‘internal/module’); const vm = require(‘vm’); const assert = require(‘assert’).ok; const fs = require(‘fs’); const internalFS = require(‘internal/fs’);
这是require的源码 Module.prototype.require = function(path) { assert(path, ‘missing path’); assert(typeof path === ‘string’, ‘path must be a string’); return Module._load(path, this, / isMain / false); };
module.js是实现require函数的,为什么第一行就调用了require,require函数不是还没实现吗?,那么第一行的require是哪里的? https://github.com/nodejs/node/blob/master/lib/internal/module.js internal目录下的module.js又是做什么用的呢?
一般每个模块默认会加上(function (exports, require, module, __filename, __dirname) { // 模块源码 }); 这里的require又是哪里的? 好混乱啊,求各位大神指教,谢谢!
看看require的源码就可以看到了: Module.prototype.require
-> Module._load
->
var filename = Module._resolveFilename(request, parent, isMain);
if (NativeModule.nonInternalExists(filename)) {
debug('load native module %s', request);
return NativeModule.require(filename);
}
所以 module.js
第一行的 require
调用的是 NativeModule.require
,专门载入核心模块的。
@hyj1991 const NativeModule = require(‘native_module’); 这个require后面是Module.prototype.require -> Module._load ->会判断然后调用 NativeModule.require(filename); ,但NativeModule这个是require来的啊,这不是自相矛盾吗?
至于你提到的 internal/module.js
,也很简单,这里面提供了三个函数:
-
makeRequireFunction:生成一个
require
函数,这个require
函数就是开发者编写的js文件直接使用的require
关键字对应的函数 -
stripBOM:因为
require
操作本质上会读取js文件内容,这个函数用来对读取出来的js文件内容进行BOM头剥离,主要是处理编码问题的 -
addBuiltinLibsToObject:给node真正的入口js文件
bootstrap_node.js
构造一些内建模块到global
对象上用的,比如:assert
,buffer
等
@chenqichenqi 建议你再仔细看看源代码,所有代码第一次执行前 boot_strap_node.js
已经被执行了,你编写的入口js文件已经被这个文件包裹后执行,所以此时 require
已经定义了。所以在 boot_strap_node.js
中的所有 require
操作都是使用 NativeModule.require
,而在这里的 NativeModule
定义就在 boot_strap_node.js
中,所以不会自相矛盾
@chenqichenqi 在最开始,node中真正的第一次 require('module')
操作发生在 boot_strap_node.js
中,此时使用的是 NativeModule.require('module')
:
const Module = NativeModule.require('module');
//...省略
Module.runMain()
而这里的 NativeModule
就定义在 boot_strap_node.js
文件中,并且NativeModule.require('module')
调用了 NativeModule.prototype.compile
对 module
核心类进行了编译,你可以看看这里的处理逻辑,此时构建的匿名函数传入的 require
还是 NativeModule.require
,所以并没有矛盾。
当然 NativeModule.require
获取源代码的方式和 module.js
中的 require
方法不一样,是通过 process.binding('natives')['module']
的方式从C源码部分获取的
@hyj1991 恩,谢谢,我再看看源码