CommonJS模塊化規范
- 加載時機:
- 服務器端: 模塊的加載是運行時同步加載的,node.js實現了模塊化規范
- 瀏覽器端: 模塊需要提前編譯打包處理,需使用Browserify編譯打包,推薦使用ESM
- 暴露模塊:module.exports、exports
- 導入模塊:require
模塊導出
- module.exports = 任意數據 (字符串、整數、布爾值、對象)
- exports.模塊名 = 任意數據 (字符串、整數、布爾值、對象),相當于
exports={模塊名: 任意數據}
- module.exports 與 exports 的關系:
- 在模塊內部存在一種隱式關系:
exports = module.exports = {}
- 模塊最終取的是module.exports的值
exports只能是引用類型數據
,不能使用exports = 基本類型的數據。如果 exports = ‘abc’,不會改變模塊返回的結果,因為module.exports為{},所以模塊返回的是{}
- 在模塊內部存在一種隱式關系:
模塊導入
-
使用require方法導入文件:
- 自定義的模塊:路徑建議
寫相對路徑 const m = require('./m.js');
,并且不能省略./
或../
- 內置的模塊:直接
require('模塊名')
,無需加./
或../
- 自定義的模塊:路徑建議
-
文件類型處理
js
、json
類型的文件不用寫后綴- 其他類型的文件不寫后綴就會按
js
類型處理
-
require導入自定義模塊的基本流程:
- 將相對路徑轉為絕對路徑,定位目標文件
- 緩存檢測
- 讀取目標文件代碼
- 包裹為一個函數并執行(自執行函數),通過
arguments.callee.toString()
查看自執行函數 - 緩存模塊的值
- 返回
module.exports
的值
const path = require('path'); const fs = require('fs'); let caches = []; function require(file) {// 將相對路徑轉為絕對路徑,定位目標文件let absolutePath = path.resolve(__dirname, file);// 緩存檢測if(caches[absolutePath]) {return caches[absolutePath];}// 讀取目標文件代碼let code = fs.readFileSync(absolutePath).toString();// 包裹為一個函數并執行(自執行函數)let module = {};let exports = module.exports = {};(function(exports, require, module, __filename, __dirname){// eval(code)})(exports, require, module, __filename, __dirname)// 緩存模塊的值caches[absolutePath] = module.exports;// 返回module.exports的值return module.exports; } // 測試 const m = require('./m.js');// m.js文件 const mt = {name: '模塊1' }; module.exports = mt;
-
導入路徑是文件夾的處理流程:
- 先檢查該文件夾下
package.json
文件的main
屬性對應的文件,如果main
屬性或package.json
文件不存在,則會檢查文件夾下的index.js
或index.json
文件,如果還是找不到就會報錯
- 先檢查該文件夾下