前言
在 JavaScript 開發中,ES Modules (ESM) 已成為標準。從 Node.js 12 開始,ESM 已獲得原生支援,而前端開發(如 React、Vue、Svelte 等框架)早已全面採用 ES Module。
然而,當我們使用 Jest 來撰寫與執行測試時,若要直接使用 ES Module,會遇到一些設定上的挑戰。本篇筆記將說明如何在專案中讓 Jest 正確執行 ES Module 程式碼,並透過實例展示操作流程。
1. Jest 是否支援 ES Module?
Jest 自 v27 版本開始實驗性支援 ES Module,到了 v28 以後更加穩定。但因為 Node.js 與 CommonJS、ESM 的處理邏輯不同,仍需要額外設定。
若你使用 ES Module(例如 .mjs
檔案、type: module
),或是前端專案用 ES6 import
/ export
,就必須進行相應的 Jest 設定。
2. 初始化專案與安裝 Jest
首先,我們建立一個 Node.js 專案:
mkdir jest-esm-demo |
接著安裝 Jest:
npm install --save-dev jest |
重點! 在 package.json
中加入 type: "module"
,讓整個專案採用 ES Module:
{ |
3. 撰寫 ES Module 程式碼
假設我們有一個簡單的 加法模組 sum.mjs
:
// sum.mjs |
接著建立測試檔案 sum.test.mjs
:
// sum.test.mjs |
這時候直接執行 npm test
會報錯:
SyntaxError: Cannot use import statement outside a module |
因為 Jest 預設使用 CommonJS,不認得 ES Module,需要額外設定。
4. 設定 Jest 支援 ES Module
方案一:使用 jest.config.js
並指定 transform
首先,安裝 Babel 或 jest-esm-transformer
之類的工具。如果希望簡單一點,可以直接使用 Jest 的內建 ESM 模式(推薦)。
建立 jest.config.js
:
// jest.config.js |
重點設定解釋:
transform: {}
表示不使用 Babel 或其他轉譯器extensionsToTreatAsEsm
告訴 Jest 哪些副檔名視為 ESMtestEnvironment: 'node'
使用 Node 環境(非 jsdom)
執行 npm test
,這時候仍會報錯:
Jest encountered an unexpected token |
因為 Jest 內建 transform 無法處理 ES Module 語法(即便 Node.js 支援,但 Jest 內部解析流程不同)。
5. 方案二:使用 babel-jest
轉譯 ESM
安裝 Babel 及相關套件:
npm install --save-dev @babel/preset-env babel-jest |
建立 .babelrc
:
{ |
更新 jest.config.js
:
export default { |
這樣 Jest 會用 babel-jest 處理 .js
、.mjs
檔案,並當作 ESM 解析。
此時執行 npm test
,測試就會通過:
PASS ./sum.test.mjs |
6. 測試更複雜情境
假設我們有一個 fetch 模組,使用 async function:
// fetchData.mjs |
測試檔:
// fetchData.test.mjs |
一樣執行 npm test
,因為已經設定好 Babel 與 ESM,非同步測試也能正常運作。
7. 使用 import.meta.url
注意事項
如果你的程式中有用 import.meta.url
(例如讀取檔案、動態載入),要注意 Jest 執行時 context 與 Node.js 直跑不同。
例如:
// fileUtil.mjs |
測試時要確保 import.meta.url
能被正確解析(可能需要 jest-environment-node
,或 Mock 檔案路徑)。
8. 常見錯誤與解法
問題:SyntaxError: Cannot use import statement outside a module
- 確認
jest.config.js
中有extensionsToTreatAsEsm
- 測試檔、副程式檔是否副檔名為
.mjs
問題:Unexpected token export
- 確認有設定
transform
使用babel-jest
- 確認
.babelrc
正確啟用@babel/preset-env
問題:ESM 測試檔找不到 module
- 確認
package.json
有type: module
- 相對路徑記得補
.mjs
副檔名
9. 實用 Jest CLI 指令
- 執行單一測試檔:
npx jest sum.test.mjs |
- 只跑某個測試:
test.only('專跑這個測試', () => { ... }); |
- 顯示覆蓋率:
npx jest --coverage |
總結
Jest 預設是為 CommonJS 設計,但隨著 ES Module 在 Node.js 與前端日漸普及,支援 ESM 變得越來越重要。
透過本文介紹,我們可以知道:
type: module
啟用 ESM- Jest 需要設定
transform
及extensionsToTreatAsEsm
- 使用
babel-jest
來處理 ESM - 注意
import.meta.url
、路徑、非同步等 ESM 細節
雖然設定比 CJS 稍微複雜,但一旦設定好後,整個測試流程一樣流暢,也能為未來更符合現代標準的專案奠定基礎。
建議未來若有使用 TypeScript、React、Vue 等,也可以結合對應的 transformer 與設定,讓 Jest 完全支援你的開發堆疊。