你有想過,我們在 JavaScript 要引入其他文件,有的時候使用 require,有的時候使用 import,這兩個方式有什麼差別?效能上又有什麼差別呢?本篇就來說明一下!
遵循的模塊化規範不同
require/exports 遵循 CommonJS 規範,主要用於 Node.js 伺服器端開發,以同步方式載入模組,也就是要載入完成後才能執行後面的程式碼。
而 import/export 則是 ES6 模組(ESM)標準,由 TC39 制定,屬於靜態編譯,編譯期就能解析依賴,瀏覽器與 Node.js 都原生支持(Node.js 14+)。若舊環境不支援,則可以透過 Babel + Webpack 轉譯。
出現的時間不同
require/exports:2010 年左右在 CommonJS 規範中出現,Node.js 廣泛採用。import/export:ES6 (ES2015) 引入,2015 年之後才廣泛使用,Babel 是早期轉譯支援的重要工具。
現在 Node.js 14+ / 16+ 已原生支援 ES Module,不需要 Babel 也能直接使用 import/export。
寫法與使用方式不同
CommonJS (require/exports)
| |
ES6 Module (import/export)
| |
動態載入(Dynamic Import)
靜態 import 必須是字面量字串,編譯期就要能確定模組路徑:
| |
若需要 動態載入,可以使用 CommonJS 的 require() 或 ESM 的動態 import():
| |
說明
| 方法 | 同步/非同步 | 支援變數 | 適用環境 |
|---|---|---|---|
import (靜態) | 靜態編譯 | ❌ | ESM(編譯期) |
require() | 同步 | ✅ | CommonJS (Node.js) |
await import() | 非同步 | ✅ | ESM (Node.js / 瀏覽器) |
Node.js 支援情況
- Node.js 14.8+:動態
import()正式可用(無需 flag)。 - Node.js 16+ LTS:動態
import()穩定,CommonJS 與 ESM 都可使用。 - 靜態
import與動態import()都可以取代 Babel 轉譯的需求,但 Babel/Webpack 仍用於瀏覽器或舊版兼容。
本質上的不同
- CommonJS 與 ES Module 輸出都是物件,但 ESM 支援
export default與強綁定屬性。 require()載入的是值或引用,靜態與動態都可以。- 動態
import()與require()的動態行為對等,但非同步,不阻塞事件循環。
範例比較
| |
執行結果:
| |
效能差異
- 靜態
import:編譯期執行。 require():同步載入,阻塞事件循環。- 動態
import():非同步載入,不阻塞事件循環。
在現代 Node.js 專案,如果能用靜態 import 就用,需動態載入才使用
require()或await import()。效能差異微乎其微,但動態載入的同步/非同步行為會影響事件循環。

