問題
CommonJS (CJS) 和 ES Modules (ESM) 是兩種不同的模塊系統,主要用于在 JavaScript 中組織和加載代碼模塊。
區別如下:
語法差異:CJS 使用
require()
和module.exports
進行模塊導入和導出,而 ESM 使用import
和export
關鍵字。加載方式:CJS 采用同步加載模塊的方式,即在代碼執行過程中按需加載模塊。ESM 則采用異步加載模塊的方式,即在模塊加載過程中不會阻塞代碼執行。
靜態編譯:ESM 模塊是在靜態階段編譯并分析模塊的依賴關系,這使得編譯器能夠靜態地確定模塊之間的依賴關系。而 CJS 模塊在運行時解析和執行,并且可以有條件地導入和導出模塊。
導入和導出的特性:ESM 支持導入和導出命名的模塊成員、默認導出和命名空間導入。CJS 則只支持整個模塊的導入和導出。
瀏覽器支持:ESM 目前在現代瀏覽器中原生支持,但在較舊的瀏覽器中需要使用轉譯器(如Babel)進行轉換。而 CJS 可以通過使用打包工具(如Webpack)將模塊打包成瀏覽器可執行的代碼。
需要注意的是,CJS 和 ESM 是兩種不兼容的模塊系統,因此在使用時需要根據具體情況選擇合適的模塊系統和相應的語法規則。在 Node.js 環境中,可以使用 CJS,而在現代瀏覽器環境中,可以使用 ESM。
舉例
當使用 CommonJS 和 ES Modules 進行模塊導入和導出時,下面是詳細的示例:
- CommonJS (CJS) 示例:
在一個名為 math.js
的模塊中,我們導出了兩個函數 add
和 subtract
:
// math.js
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;
module.exports = {
add,
subtract
};
在另一個模塊中,我們使用 require()
來導入 math.js
模塊并使用其中的函數:
// app.js
const math = require('./math.js');
console.log(math.add(1, 2)); // 輸出:3
console.log(math.subtract(5, 3)); // 輸出:2
在上述示例中,math.js
模塊中定義了兩個函數 add
和 subtract
,然后通過導出對象的方式將這兩個函數暴露給外部使用。在 app.js
模塊中,使用 require('./math.js')
導入 math.js
模塊,然后通過 math.add
和 math.subtract
訪問導出的函數。
- ES Modules (ESM) 示例:
在一個名為 math.js
的模塊中,我們使用 export
關鍵字導出了兩個函數 add
和 subtract
:
// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
在另一個模塊中,我們使用 import
關鍵字來導入 math.js
模塊并使用其中的函數:
// app.js
import { add, subtract } from './math.js';
console.log(add(1, 2)); // 輸出:3
console.log(subtract(5, 3)); // 輸出:2
在上述示例中,math.js
模塊中通過 export
關鍵字將兩個函數 add
和 subtract
導出,使其可以在其他模塊中使用。在 app.js
模塊中使用 import { add, subtract } from './math.js'
從 math.js
模塊中導入具體的函數,然后可以直接使用 add
和 subtract
函數進行計算。
需要注意的是,在使用 ES Modules 時,需要在支持的環境中進行正確的配置和加載,例如在瀏覽器中使用 <script type="module" src="app.js"></script>
加載模塊化的 JavaScript 文件。而在 Node.js 環境中,默認情況下是使用 CommonJS 模塊系統,如果要使用 ES Modules,需要在文件擴展名為 .js
的文件中使用 import
和 export
關鍵字,并在執行文件時添加 --experimental-modules
參數或者將文件擴展名更改為 .mjs
。