这是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->所以
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'):而这里的
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 恩,谢谢,我再看看源码