Apa arti error ini?
SyntaxError: Cannot use import statement outside a moduleError ini muncul ketika file berisi deklarasi import dijalankan dalam konteks yang tidak memperlakukannya sebagai ES module. Di Jest, penyebabnya bisa berupa transformasi yang tidak berlaku, mode modul yang tidak cocok, atau dependensi ESM yang masuk ke jalur CommonJS.
Pilih satu strategi untuk test: ubah modul ke CommonJS melalui transformer, atau jalankan sebagai native ESM. Jangan mencampurkan transform: {} dari resep ESM dengan harapan Babel tetap mengonversi import menjadi CommonJS.
Format file penting: .mjs menandai ESM, .cjs menandai CommonJS, sedangkan .js dipengaruhi type pada package.json terdekat dan perilaku runtime. Jangan mengandalkan deteksi sintaks Node untuk menyamakan perilaku Jest. Menambahkan "type": "module" saja tidak mengonfigurasi seluruh pipeline Jest dan dapat mengubah makna file konfigurasi .js lainnya.
Diagnosis sebelum mengubah konfigurasi
- Baca path file pertama yang gagal. Jika berada di
src, periksa transformasi sumber; jika dinode_modules, periksa format dan ekspor dependensi itu. Jika file konfigurasi sendiri gagal dimuat, perbaiki format konfigurasinya lebih dahulu. - Periksa versi Node, Jest, Babel, dan transformer. Major version
jestdanbabel-jestsebaiknya selaras; nomor major Babel tidak harus sama dengan Jest. - Pilih satu sumber konfigurasi Jest. Saat beberapa konfigurasi ditemukan secara implisit, Jest dapat menolak karena ambigu; jangan menganggap konfigurasi di
package.jsondiam-diam digabung dan menimpajest.config.js. - Baca konfigurasi efektif dengan
--showConfig. Perintah ini menampilkan konfigurasi lalu keluar, bukan menjalankan test.
Jika Jest sudah terpasang lokal:
node --version
npm ls jest babel-jest @babel/core @babel/preset-env
node node_modules/jest/bin/jest.js --showConfigTambahkan --config <file-konfigurasi> jika ada beberapa konfigurasi yang memang disengaja. Periksa rootDir, transform, transformIgnorePatterns, dan lingkungan test. Setelah perubahan, --no-cache berguna untuk diagnosis; membersihkan cache terus-menerus bukan solusi bagi konfigurasi yang salah.
Contoh sumber dan test minimum
Gunakan direktori percobaan terpisah dengan package.json; jangan mengganti konfigurasi aplikasi produksi untuk mencoba resep. Contoh berikut memakai JavaScript biasa, tanpa JSX atau TypeScript. Target kedua resepnya Jest 29.x, dengan Babel 7.x untuk jalur CommonJS; ini batas contoh, bukan klaim versi terbaru. Pada pemeriksaan 11 September 2026, dokumentasi Jest 29.7 menandai versi itu tidak lagi aktif dipelihara. Untuk proyek baru, evaluasi versi yang masih dipelihara; jangan menafsirkan pin contoh sebagai rekomendasi downgrade.
Simpan sumber berikut sebagai sum.js:
// sum.js
export function sum(a, b) {
return a + b;
}Simpan test sebagai sum.test.js di direktori yang sama:
// sum.test.js
import { expect, test } from '@jest/globals';
import { sum } from './sum.js';
test('menjumlahkan dua angka', () => {
expect(sum(2, 3)).toBe(5);
});export dan test memakai huruf kecil. Import @jest/globals eksplisit membuat contoh test dapat dipakai pada kedua strategi. Pengujian di bawah ditujukan ke Node, sehingga tidak membutuhkan jsdom.
Jalur A: transformasi Babel ke CommonJS
Gunakan jalur ini bila Anda ingin menulis import/export tetapi menjalankan test melalui pipeline CommonJS. Untuk fixture baru dengan versi contoh:
npm install -D jest@29 babel-jest@29 @jest/globals@29 @babel/core@7 @babel/preset-env@7Pada proyek yang sudah ada, sesuaikan versi transformer dengan Jest yang dipakai; jangan upgrade semuanya hanya untuk mengatasi error import.
Gunakan konfigurasi .cjs supaya module.exports tetap valid, termasuk bila package aplikasi memakai "type": "module":
// babel.config.cjs
module.exports = {
env: {
test: {
presets: [
['@babel/preset-env', {
targets: { node: 'current' },
modules: 'commonjs',
}],
],
},
},
};Transformasi CommonJS dibatasi ke environment Babel test agar tidak mengubah output build aplikasi. Jest menetapkan NODE_ENV=test bila belum diatur; pastikan BABEL_ENV atau NODE_ENV dari shell/CI tidak memilih environment lain. Jangan menimpa konfigurasi Babel proyek yang sudah memiliki preset framework; gabungkan hanya pengaturan test yang diperlukan.
// jest.config.cjs
module.exports = {
testEnvironment: 'node',
transform: {
'^.+\\.m?jsx?$': 'babel-jest',
},
};Pola tersebut mencakup .js, .jsx, dan .mjs, tetapi resep Babel ini belum menambahkan transformasi JSX. Untuk React diperlukan preset JSX yang sesuai; untuk TypeScript gunakan transformer/preset TypeScript dan typecheck terpisah. Mengubah ekstensi dalam regex saja tidak menambahkan kemampuan tersebut.
Jalankan tanpa flag native ESM:
node node_modules/jest/bin/jest.js --config jest.config.cjs --runTestsByPath sum.test.js --runInBand --no-cacheKriteria keberhasilan: test benar-benar ditemukan, assertion 2 + 3 = 5 dijalankan, dan proses berakhir dengan exit code 0. Jangan menyalin log keberhasilan dari artikel sebagai bukti eksekusi sendiri.
Opsi modules pada @babel/preset-env menentukan transformasi modul. Mode auto mempertimbangkan informasi caller dari tool yang memanggil Babel; bukan sekadar membaca type di package.json. Menggunakan modules: 'commonjs' dalam environment test membuat maksud jalur ini eksplisit.
Jalur B: native ESM tanpa Babel
Ini alternatif, bukan tambahan pada Jalur A. Pada fixture terpisah, pasang jest@29 dan @jest/globals@29, lalu tambahkan "type": "module" dan script berikut ke package.json yang ada:
{
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.esm.config.cjs"
}
}Potongan JSON itu menunjukkan field untuk digabung, bukan instruksi menghapus dependencies lain. Untuk versi Jest yang dicontohkan, jalur native ESM menggunakan VM modules eksperimental Node. Periksa dukungan Node/Jest yang Anda pilih sebelum menerapkannya pada proyek yang lebih baru.
// jest.esm.config.cjs
module.exports = {
testEnvironment: 'node',
transform: {},
};transform: {} tepat untuk JavaScript ESM yang tidak memerlukan transpiling. Jika Anda memakai transformer untuk TypeScript/JSX pada jalur ESM, transformer harus menghasilkan ESM, bukan CommonJS.
npm test -- --runTestsByPath sum.test.js --runInBand --no-cachePath node_modules/jest/bin/jest.js menunjuk file JavaScript sebenarnya dan dapat dipakai di Windows maupun shell Unix. Jangan menjalankan shell wrapper di .bin melalui node. File .js di fixture ini menjadi ESM karena type; tidak perlu memasukkan .js ke extensionsToTreatAsEsm.
Mocking ESM berbeda dari CommonJS karena import statis dievaluasi lebih awal. jest.mock dengan asumsi hoisting CommonJS tidak otomatis cocok; baca dokumentasi ESM Jest untuk penggunaan jest.unstable_mockModule dan dynamic import. Migrasi test kompleks bukan sekadar menambahkan flag Node.
Jika error berasal dari node_modules
Secara default, Jest mengabaikan node_modules dalam transformasi. Pada Jalur A, bila dependensi bermasalah memang perlu diubah ke CommonJS, allowlist paket tertentu dan pastikan ekstensi filenya cocok dengan transformer.
Contoh konfigurasi lengkap di bawah memakai nama placeholder esm-package. Ganti dengan paket yang benar-benar disebut stack trace; jangan memasang paket placeholder:
// jest.dependency.config.cjs
module.exports = {
testEnvironment: 'node',
transform: {
'^.+\\.m?jsx?$': 'babel-jest',
},
transformIgnorePatterns: [
'/node_modules/(?!(?:esm-package)/)',
],
};Pola ini mengabaikan paket lain, tetapi membolehkan esm-package/ ditransformasi. Slash setelah nama paket mencegah nama mirip seperti esm-package-extra ikut lolos. Jangan menambahkan pola /node_modules/ umum di entri lain, karena kecocokan salah satu pola ignore sudah cukup untuk melewati transformasi.
Resep ini mengasumsikan layout node_modules sederhana. pnpm menggunakan path nyata di .pnpm; Yarn PnP berbeda lagi. Periksa path aktual dan contoh resmi transformIgnorePatterns, bukan menyalin regex ini ke semua package manager. Allowlist tidak menjamin library kompatibel dengan CommonJS: top-level await atau perilaku ESM tertentu mungkin membutuhkan jalur native ESM.
Masalah lain yang perlu dibedakan
- Config gagal sebelum test ditemukan: gunakan
.cjsuntuk configmodule.exports, atau format ESM yang didukung. Konfigurasi test bukan file yang bisa diperbaiki hanya dengan transformer test. - Test browser:
testEnvironment: 'jsdom'membutuhkan paketjest-environment-jsdomyang kompatibel pada Jest modern.jsdomsendiri tidak memperbaiki error import. - Perbedaan CI dan lokal: samakan Node, manifest, lockfile, environment Babel, working directory, dan perintah test. Untuk npm dengan lockfile sinkron gunakan
npm ci; jangan membuang lockfile saat diagnosis. - Perubahan dependency menjadi ESM-only: tinjau changelog dan ekspor paket, lalu pilih transformasi yang kompatibel atau migrasi ESM. Downgrade membabi buta atau menonaktifkan seluruh ignore pattern bukan perbaikan umum.
Batas verifikasi
Review independen lokal 11 September 2026 menjalankan Jest dan Babel sebenarnya, dengan snippet artikel diekstrak ke dua fixture sementara terpisah pada Windows x64, Node 24.12.0, npm 11.6.2. Versi terpasang: Jest, babel-jest, dan @jest/globals 29.7.0; @babel/core serta @babel/preset-env 7.29.7. Instalasi jaringan dilakukan hanya di fixture, dengan --ignore-scripts; manifest dan lockfile aplikasi tidak diubah.
Jalur Babel CommonJS dan native ESM masing-masing menemukan satu test, menjalankan assertion, dan keluar dengan kode 0. Varian CommonJS dengan type: "module" serta dependency ESM sintetis yang di-allowlist juga berhasil. Kontrol negatif mengubah penjumlahan menjadi pengurangan: kedua jalur keluar dengan kode 1 dan satu assertion gagal. Menonaktifkan transformasi pada fixture CommonJS serta mengabaikan dependency ESM juga gagal sesuai dugaan. Ini membedakan eksekusi test nyata dari pemeriksaan sintaks saja.
Native ESM tetap mengeluarkan ExperimentalWarning: VM Modules. Instalasi Jest 29 mengeluarkan peringatan dependensi transitif lama inflight dan glob; tidak dilakukan audit kerentanan (--no-audit). Uji ini tidak mencakup Jest 30+, Node lain, Linux/macOS, JSX/TypeScript, jsdom, mocking ESM, top-level await, pnpm, atau Yarn PnP. Fixture dihapus setelah uji; fixture native ESM berjalan tanpa konfigurasi Babel, meskipun Jest membawa paket Babel transitif. Ulangi test proyek Anda dengan versi dan environment yang sesuai.
Sumber resmi
Rujukan berikut diperiksa secara daring pada 11 September 2026. Dokumentasi ESM Jest terkini juga diperiksa, tetapi runner versi terbaru tidak diuji di sini: