CommonJS是JavaScript的模塊化規范,主要用于服務器端(如Node.js)的模塊化開發,其核心功能和特點如下:
一、核心功能
-
模塊定義與導出
module.exports
:用于導出模塊的內容,可以是函數、對象、變量等。例如:module.exports = function(a, b) { return a + b; }; // 導出單個函數 module.exports = { add, subtract }; // 導出多個方法[^1^][^4^]
exports
:module.exports
的簡寫引用,用于簡化導出操作。例如:exports.sayHello = function(name) { return `Hello, ${name}`; }; [^4^]```
-
模塊導入
require()
:同步導入模塊并返回其導出的內容。例如:const math = require('./math'); // 導入整個模塊 const { add } = require('./math'); // 解構導入[^1^][^4^]
二、關鍵特點
-
同步加載
- 模塊加載是同步的,執行
require
時會阻塞后續代碼,直到模塊加載完成。適用于服務器端本地文件加載(速度快),但不適合瀏覽器環境[1][4]。
- 模塊加載是同步的,執行
-
單例模式與緩存
- 每個模塊在首次加載后會被緩存,后續
require
同一模塊直接返回緩存實例。例如:const moduleA = require('./module'); const moduleB = require('./module'); console.log(moduleA === moduleB); // true[^1^][^4^]
- 每個模塊在首次加載后會被緩存,后續
-
動態導入
- 支持運行時動態加載模塊,根據條件靈活導入不同模塊。例如:
if (condition) {const moduleA = require('./moduleA'); } else {const moduleB = require('./moduleB'); }[^1^][^4^]
- 支持運行時動態加載模塊,根據條件靈活導入不同模塊。例如:
-
文件即模塊
- 每個文件視為獨立模塊,擁有單獨的作用域,避免全局變量污染[2][4]。
三、模塊加載機制
-
加載流程
- 路徑解析:優先從緩存中查找模塊;若未緩存,則檢查是否為核心模塊(如
fs
);否則按路徑查找文件模塊[4]。 - 文件擴展名:自動按
.js
、.json
、.node
順序補全后綴[2]。 - 編譯與執行:加載后立即編譯并執行模塊代碼[4]。
- 路徑解析:優先從緩存中查找模塊;若未緩存,則檢查是否為核心模塊(如
-
循環依賴處理
- 通過緩存機制解決循環依賴,但需注意模塊的加載順序和狀態[3][4]。
四、應用場景
-
服務器端開發
- Node.js默認使用CommonJS,適合后端代碼的組織與管理。例如,通過
require
引入數據庫驅動、路由模塊等[1][4]。
- Node.js默認使用CommonJS,適合后端代碼的組織與管理。例如,通過
-
前端開發
- 需通過構建工具(如Webpack、Browserify)將CommonJS模塊轉換為瀏覽器兼容格式。例如:
# 使用Webpack打包 webpack --entry ./src/index.js --output ./dist/bundle.js [^5^]
- 需通過構建工具(如Webpack、Browserify)將CommonJS模塊轉換為瀏覽器兼容格式。例如:
五、與ES模塊(ESM)的對比
特性 | CommonJS | ES模塊(ESM) |
---|---|---|
語法 | require() 、module.exports | import 、export |
加載方式 | 同步加載(阻塞) | 異步加載(非阻塞) |
動態導入 | 支持require() 動態加載 | 需使用import() 返回Promise |
緩存機制 | 模塊單例緩存 | 無默認緩存(可通過import 實現) |
適用環境 | 服務器端(Node.js) | 瀏覽器端、現代前端工程 |
靜態分析 | 不支持(運行時解析) | 支持(編譯時優化) |
六、總結
CommonJS通過同步加載、單例緩存和簡單的API設計,成為服務器端JavaScript模塊化的事實標準。雖然ES模塊在現代前端開發中更受青睞,但在Node.js生態和舊項目中,CommonJS仍具有重要價值[1][4][5]。