一段报错信息
我们可以通过下面的一段报错信息,了解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源码