一段报错信息
我们可以通过下面的一段报错信息,了解nodejs整个执行过程。我将根据整个执行过程,来进行源码的讲解,为源码添加大量注释来达到直观效果。
|
|
bootstrap_node载入Module
bootstrap_node(bootstrap_node源码)
文件是nodejs第一个js执行文件,通过node.cc文件执行。
startup函数通过如下源码,去加载module模块:
NativeModule
NativeModule是加载,生成原生模块实例,编译,执行原生模块的函数,源码在bootstrap_node文件中,源码如下:
通过上面源码可以看出const Module = NativeModule.require('module')
,Module其实是新创建的原生模块实例的exports属性返回值。
而module.js文件中代码可以使用这个新创建的原生模块实例所有属性。
Module源码
根据代码的调用顺序进行,源代码的解析:
runMain
bootstrap_node文件中执行Module.runMain()
,Module模块runMain源码如下:
_load
runMain执行了_load这个函数,_load源码:
load
tryModuleLoad函数源码:
|
|
load函数源码:
Module._extensions
|
|
_compile
|
|
上面的代码,我们看见了一个模块的加载和执行过程,并了解了我们能直接使用exports,require,module,__dirname等等的原因。
还有this指代module.exports的原因,下面将解释我们最常用的require
的源码。
require
|
|
我们看见require的代码就短短几句话,最后返回Module._load的执行结果。而通过上面的代码解释,我们知道Module._load返回的是
我们引入的模块的实例化对象的exports属性。如果还不明白可以看下面例子。
例子讲解
例如:
简单的来说,那么程序会执行。
- bootstrap_node的startup函数,加载Module模块。然后执行Module.runMain。
- Module.runMain会加载并执行主文件index.js。
- 主文件执行
require
这里的require其实就是主文件实例化后的module.require。 - 然后,加载并执行add.js,生成新的模块实例,执行并为add.js模块实例的属性exports赋值。
- 最终,将新的模块的exports属性,即module.exports,返回给add这个变量。
- 所以add变量的值,其实就为
function(a,b){return a+b}
这个函数。
参考
node源码