Modules - ECMAScript(import, export) & CommonJS(require, module.exports)
Modules
JavaScript 模組(Modules
)是一種將程式碼封裝起來,並且以特定介面供其他程式碼使用的方法。在開發一個 project 時將程式碼分成模塊有以下幾個優點:
- 縮短通譯檔案長度,有助於代碼的可讀性和組織。
- 程式碼依照功能區分更方便維護也降低發生衝突的機會
- 有助於 project 中不同文件和部分中使用和重用
ECMAScript Modules vs. CommonJS
在 JavaScript 中,有兩種主要的模組系統,分別是 CommonJS
和 ECMAScript Modules
。
ECMAScript Modules
是 JavaScript 在 ES6(2015) 後的標準模組系統。它使用 import
關鍵字匯入模組,使用 export
關鍵字匯出模組。例如,我們可以使用以下方式匯入與匯出模組:
// 匯入模組
import { add, subtract } from './math.js';
// 匯出模組
export { add, subtract };
CommonJS
是一種用於 Node.js 程式碼的模組系統。它使用 require()
函式匯入模組,使用 module.exports
屬性匯出模組。例如,我們可以使用以下方式匯入與匯出模組:
// 匯入模組
const math = require('./math.js');
// 匯出模組
module.exports = { add, subtract };
ECMAScript Modules
相對於 CommonJS
有以下幾點不同:
載入方式
:CommonJS 使用同步
載入,而 ECMAScript Modules 使用非同步
載入。載入時間
:CommonJS 模組是在運行時載入,而 ECMAScript Modules 在分析時就已經載入,這使得程式碼可以進行更好的靜態分析和優化。範圍
:在 CommonJS 中,模組是在局部作用域中執行的。而在 ECMAScript Modules 中,模組是在全局作用域中執行的,但是每個模組的變數和函式都是私有的,不會泄漏到全局作用域。
- ECMAScript Modules
- CommonJS
在 Node.js 環境下,CommonJS
的同步載入機制比較適合的例子是文件系統操作。在 Node.js 中,你可以使用 fs 模組來進行文件系統的操作,例如讀取文件、寫入文件、刪除文件等等。如果你使用 ECMAScript Modules
來載入 fs 模組,你需要使用 import
指令進行非同步載入,例如:
import { readFile } from 'fs/promises';
async function readMyFile() {
const data = await readFile('myFile.txt', 'utf8');
console.log(data);
}
這樣的寫法需要使用 async/await
或者 Promise
,才能確保在讀取文件完成之後再進行後續操作。
但是在 CommonJS
中,你可以使用 require()
函式進行同步載入,例如:
const fs = require('fs');
function readMyFile() {
const data = fs.readFileSync('myFile.txt', 'utf8');
console.log(data);
}
這樣的寫法可以讓你直接獲取文件的內容,並且不需要使用 async/await
或者 Promise
。由於在 Node.js 中,文件系統操作通常是同步進行的,因此使用 CommonJS
的同步載入機制比較適合。但是需要注意的是,如果你在進行大量的文件系統操作,使用同步載入可能會導致程式阻塞,因此需要根據具體情況進行選擇。
ECMAScript Modules
ECMAScript Modules
是 ES6
引入的一個新特性,它是一個內建的模組系統,可以用來進行模組化開發。ECMAScript Modules
使用 import 和 export 關鍵字來載入和導出模組,支援非同步載入和靜態分析。在 ECMAScript Modules
中,模組是在編譯時靜態分析的,也就是說,模組載入是在程式碼執行之前完成的。
在瀏覽器中運行
如果要在瀏覽器運行模組化,需要在 <script>
標籤加上 type="module"
,告訴瀏覽器該區塊應該被視為一個模塊。接下來就能在該 <script>
內外運用模組功能。
<!doctype html>
<script type="module">
import {sayHi} from './say.js';
document.body.innerHTML = sayHi('John');
</script>