Nodejs 之 exports, require, module, __filename, __dirname

嚴俊東發表於2019-03-04

開頭

Nodejs程式碼中常見的引入模組函式“require”。其實很少人瞭解為什麼能使用“require”,以及Nodejs基本的執行機制。

是否還記得“arguments”,arguments可以直接拿到呼叫函式傳入的引數。

(function() {
  console.log(arguments)} // [1, 2, 3]
)(1, 2, 3)
複製程式碼

其實Nodejs可以直接列印 arguments。用Node執行檔案:

// index.js
// node index.js 執行
console.log(arguments)
// 輸出
//{ `0`: {},
//  `1`:{ [Function: require]
//  `2`:
//   Module {
//     id: `.`,
//     exports: {},
//     parent: null,
//     filename: `D:\Personal\Desktop\a
//     loaded: false,
//     children: [],
//     paths:
//      [ `D:\Personal\Desktop\abc\nod
//        `D:\Personal\Desktop\node_mod
//        `D:\Personal\node_modules`,
//        `D:\node_modules` ] },
//  `3`: `D:\Personal\Desktop\abc\inde
//  `4`: `D:\Personal\Desktop\abc` }
複製程式碼

可以看到arguments內有五個引數。這五個引數分別是 exports, require, module, __filename, __dirname

原始碼解析

在Nodejs原始碼 loader.js檔案中,可以看到這幾行js程式碼

Module.wrap = function(script) {
  return Module.wrapper[0] + script + Module.wrapper[1];
};

Module.wrapper = [
  `(function (exports, require, module, __filename, __dirname) { `,
  `
});`
];

// ....
Module.prototype._compile = function(content, filename) {
 content = internalModule.stripShebang(content);
  // create wrapper function
 var wrapper = Module.wrap(content);
// ....
複製程式碼

大致邏輯是:

在執行檔案內容的頭部新增 `(function (exports, require, module, __filename, __dirname) { `

在執行檔案內容尾部新增 `
});`

之後的解析就是把字串轉為程式碼(函式)供來呼叫。

備註

exports
require
module
__filename
__dirname

相關文章