node环境里模块如何执行

47 阅读2分钟

当执行一个模块或使用require时,会将模块放置在一个函数环境中

假如有两个模块:myModule.js 和 index.js, index.js中导入myModule.js。 代码如下:

myModule.js

console.log("当前模块路径:", __dirname);
console.log("当前模块文件:", __filename);
this.m = 5;
exports.c = 3;
module.exports = {
 a: 1,
 b: 2
}

index.js

const result = require("./myModule");
console.log(result)

执行结果为:

截屏2025-11-18 11.26.20.png

假如说myModule.js的代码为:

console.log("当前模块路径:", __dirname);
console.log("当前模块文件:", __filename);
this.m = 5;
exports.c = 3;
module.exports.a = 1
module.exports.a = 2

执行结果为:

截屏2025-11-18 11.34.04.png

这是为什么呢? index.js 执行 require("./myModyle")时,会执行以下代码(伪代码):

function require(modulePath) {
  //1. 将modulePath转换为绝对路径:**:\***\****\node的模块化细节\myModule.js
  //2. 判断是否该模块已有缓存
  if(require.cache["**:\***\****\node的模块化细节\myModule.js"]){
     // 如果有缓存,返回模块的运行结果
     return require.cache["**:\***\****\node的模块化细节\myModule.js"].result;
   }
  // 如果没有缓存
  //3. 读取文件内容
  //4. 包裹到一个函数中

  function __temp(module, exports, require,  __dirname, __filename) {
    console.log("当前模块路径:", __dirname);
    console.log("当前模块文件:", __filename);
    exports.c = 3;
    module.exports = {
      a: 1,
      b: 2
    };
    this.m = 5;
  }

  //5. 创建module对象
  module.exports = {};
  const exports = module.exports;

  __temp.call(module.exports, module, exports, require, module.path, module.filename)
    // 运行函数,最终返回的是module.exports
    return module.exports;
}

require.cache = {};

我们可以看到, myModule.js模块代码是放在一个函数中执行的,函数会给一些参数:module, exports,require, __dirname, __filename

然后调用函数时,将this指向了module.exports。同时需要注意,创建module对象时是这样的

//5. 创建module对象 
module.exports = {}; 
const exports = module.exports;

所以最初,module.exports, exports, this都是指向的同一地址。但是执行函数后,返回的是module.exports。因此第一次执行结果返回的是:{a:1, b:2} 是因为执行到代码:

module.exports = {
 a: 1,
 b: 2
}

时,module.exports 被重新赋值了,而exports和this还是指向的原来的地址,所以只返回了:{a:1, b:2}。第二次返回结果是:{m:5, c:3, a:1, b:2}是因为exports,this, module.exports指向的是同一地址。

综上,myModule模块中的代码是放在函数中执行的,函数给一些参数:module, exports,require, __dirname, __filename,所以可以打印__dirname和__filename,同时需要注意调用函数时this的指向。

建议在平时要不全部用module.exports,要么全部用exports