Pesan Error & Artinya
Ketika kamu bekerja dengan Node.js dan mencoba mengimpor pustaka Cheerio di proyek modern, kamu mungkin dihadapkan pada pesan error yang terlihat seperti ini:
SyntaxError: The requested module 'cheerio' does not provide an export named 'default'
Atau dalam beberapa lingkungan runtime, pesannya bisa muncul dalam format yang sedikit berbeda:
SyntaxError: Named export 'default' not found. The requested module 'cheerio' is a CommonJS module, which may not support all required EcmaScript module features.
Pesan error ini secara sederhana berarti bahwa kode kamu mencoba melakukan default import terhadap modul Cheerio menggunakan sintaks ESM (ECMAScript Modules), tetapi Cheerio — sebagai paket yang dipublikasikan dalam format CommonJS — tidak menyediakan ekspor bernama default. Dalam ekosistem Node.js, ada dua sistem modul yang berjalan berdampingan: CommonJS (yang menggunakan require() dan module.exports) dan ESM (yang menggunakan import dan export). Ketika kamu menulis import cheerio from 'cheerio', kamu meminta default export dari modul tersebut. Namun Cheerio mengekspor objeknya menggunakan module.exports, yang dalam konteks interop ESM-CJS tidak selalu dipetakan secara otomatis menjadi default export.
Error ini muncul paling sering ketika kamu menambahkan "type": "module" di package.json atau menggunakan ekstensi file .mjs, yang memberitahu Node.js untuk memperlakukan kode kamu sebagai ESM. Pada saat yang sama, Cheerio versi tertentu (terutama versi 1.0.0-rc.x) murni dikemas sebagai CommonJS tanpa ESM wrapper atau conditional exports yang memetakan default export. Node.js kemudian menolak melakukan interop otomatis karena dianggap ambigu dan berpotensi berbahaya — sehingga error ini dilempar ke permukaan.
Contoh kode yang memicu error:
// file: scraper.mjs
// atau file .js dengan "type": "module" di package.json
import cheerio from 'cheerio'; // ❌ Error di sini
const html = '<h2 class="title">Hello world</h2>';
const $ = cheerio.load(html);
console.log($('.title').text());
Penyebab Umum
Berikut adalah penyebab-penyebab paling umum yang membuat error ini muncul, diurutkan dari yang paling sering terjadi di lapangan:
Menggunakan default import ESM terhadap paket CJS murni. Ini adalah penyebab nomor satu. Kamu menulis
import cheerio from 'cheerio'di file ESM, tapi Cheerio dinode_modulesadalah paket CommonJS yang tidak punyaexport default. Node.js tidak bisa menebak apakahmodule.exportsseharusnya diperlakukan sebagai default export atau sebagai namespace, jadi ia menolak dan melempar error.Versi Cheerio yang tidak kompatibel dengan ESM. Cheerio versi
1.0.0-rc.10ke bawah sama sekali tidak menyertakan exports map dipackage.json-nya. Baru di versi1.0.0-rc.12dan yang lebih baru, maintainer Cheerio mulai menambahkan conditional exports yang secara eksplisit mendukung ESM. Jika kamu terjebak di versi lama, default import akan selalu gagal.Bundler atau transpiler yang mengubah perilaku interop. Tools seperti esbuild, Rollup, atau bahkan Babel dengan preset tertentu bisa menghasilkan kode interop yang berbeda-beda. esbuild, misalnya, secara default mengasumsikan CJS modules punya default export dan akan mensintesis satu. Tapi ketika kode dijalankan langsung di Node.js (tanpa bundler), asumsi itu tidak berlaku dan error muncul.
Versi Node.js yang lebih ketat terhadap ESM-CJS interop. Mulai Node.js v16 dan lebih ketat lagi di v18+, perilaku default interop antara ESM dan CJS semakin strict. Versi Node yang lebih lama mungkin "memaafkan" impor ini, tapi versi baru tidak.
Cache module yang basi. Kadang-kadang, setelah kamu mengubah konfigurasi atau meng-upgrade Cheerio, Node.js masih menggunakan versi cache yang lama dari modul resolution, sehingga error tetap muncul meskipun perbaikan sudah diterapkan.
Untuk memastikan penyebab mana yang kamu alami, jalankan diagnosa berikut:
- Cek versi Cheerio:
npm ls cheerio— jika di bawah1.0.0-rc.12, itu kemungkinan besar penyebabnya. - Cek versi Node.js:
node --version— jika di bawah v16, pertimbangkan upgrade. - Cek type di
package.json:cat package.json | grep '"type"'— jika"type": "module"ada, kamu berada di mode ESM. - Cek isi ekspor Cheerio:
node -e "console.log(Object.keys(require('cheerio')))"— ini menunjukkan apa yang sebenarnya diekspor.
Solusi Step-by-Step
Langkah 1: Ganti Default Import Menjadi Named Import atau Namespace Import
Cara paling langsung dan cepat adalah mengubah cara kamu mengimpor Cheerio. Alih-alih menggunakan default import, gunakan namespace import yang secara eksplisit menangkap seluruh module.exports sebagai objek:
// ❌ Sebelum (memicu error)
import cheerio from 'cheerio';
// ✅ Sesudah (namespace import)
import * as cheerio from 'cheerio';
Setelah diubah, kode lengkapnya menjadi:
import * as cheerio from 'cheerio';
const html = '<h2 class="title">Hello world</h2>';
const $ = cheerio.load(html);
console.log($('.title').text()); // Output: Hello world
Output yang diharapkan: Tidak ada error. Program berjalan normal dan mencetak "Hello world".
Verifikasi: Jalankan file dengan node scraper.mjs. Jika tidak ada error dan output sesuai, solusi ini berhasil.
Langkah 2: Upgrade Cheerio ke Versi yang Mendukung ESM
Jika kamu ingin tetap menggunakan sintaks import cheerio from 'cheerio' (default import), kamu perlu versi Cheerio yang secara native mendukung ESM:
npm install cheerio@latest
Atau jika kamu ingin versi spesifik yang sudah mendukung ESM:
npm install cheerio@1.0.0-rc.12
Output yang diharapkan:
added 1 package, changed 3 packages in 2s
Verifikasi: Setelah install, cek bahwa Cheerio sekarang punya exports map:
node -e "const pkg = require('cheerio/package.json'); console.log(pkg.exports)"
Jika output menunjukkan objek exports dengan kunci "import" dan "require", maka Cheerio versi baru sudah mendukung ESM dan default import seharusnya bisa digunakan.
Langkah 3: Bersihkan Cache Jika Error Masih Muncul
Kadang setelah upgrade, Node.js masih menggunakan resolusi modul yang lama dari cache:
# Hapus node_modules dan reinstall
rm -rf node_modules package-lock.json
npm install
Pada Windows (PowerShell):
Remove-Item -Recurse -Force node_modules, package-lock.json
npm install
Output yang diharapkan: Fresh install tanpa error, semua dependensi terresolve ulang.
Verifikasi: Jalankan kembali file yang bermasalah. Jika berhasil, masalahnya memang cache yang basi.
Langkah 4: Gunakan Dynamic Import sebagai Alternatif
Jika kamu berada di situasi di mana static import tetap bermasalah (misalnya karena constraint transpiler), dynamic import bisa menjadi jalan keluar yang reliable:
// dynamic-import-scraper.mjs
async function scrape() {
const cheerio = await import('cheerio');
const $ = cheerio.default
? cheerio.default.load('<h2>Hello</h2>')
: cheerio.load('<h2>Hello</h2>');
console.log($('h2').text()); // Output: Hello
}
scrape();
Pendekatan ini bekerja karena await import() mengembalikan objek namespace yang berisi seluruh named exports plus default jika tersedia. Dengan mengecek cheerio.default, kamu bisa menangani kedua skenario — baik saat Cheerio menyediakan default export maupun tidak.
Fix Permanen (Bukan Workaround)
Solusi-solusi di atas bersifat reaktif. Agar error ini tidak kembali muncul di masa depan, kamu perlu menerapkan konfigurasi dan best practice yang lebih fundamental.
Konfigurasi package.json dengan Exports Map
Jika kamu membangun pustaka sendiri yang menggunakan Cheerio secara internal, tambahkan exports map yang eksplisit di package.json kamu:
{
"name": "my-scraper",
"type": "module",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"dependencies": {
"cheerio": "^1.0.0-rc.12"
}
}
Exports map memberitahu Node.js persis file mana yang harus diresolve untuk setiap kondisi impor, mengeliminasi ambiguitas yang menjadi akar masalah error ini.
Pin Versi Cheerio di package.json
Untuk mencegah regresi, pin versi Cheerio yang sudah terbukti mendukung ESM:
{
"dependencies": {
"cheerio": "1.0.0-rc.12"
}
}
Hindari menggunakan ^ atau ~ jika kamu ingin benar-benar memastikan versi tidak bergeser ke versi yang berbeda perilaku. Meskipun dalam praktiknya, versi yang lebih baru dari 1.0.0-rc.12 seharusnya terus mendukung ESM.
Best Practice: Konsistensi Sistem Modul
Keputusan terbesar yang harus kamu buat di awal proyek adalah: apakah proyek ini ESM atau CJS? Jangan mencampur keduanya tanpa strategi yang jelas. Jika proyek kamu ESM:
- Set
"type": "module"dipackage.json. - Gunakan ekstensi
.mjsuntuk file ESM dan.cjsuntuk file CJS yang tidak bisa dihindari. - Untuk setiap dependensi CJS, gunakan
import * as pkg from 'pkg'bukanimport pkg from 'pkg'.
Jika proyek kamu CJS:
- Jangan set
"type": "module". - Gunakan
const cheerio = require('cheerio')dan tidak akan ada masalah.
Perbedaan Antar OS
Perbedaan OS biasanya tidak menjadi faktor utama untuk error ini, karena Node.js menangani ESM-CJS interop secara konsisten lintas platform. Namun, ada nuansa kecil:
- Windows: Perintah
rm -rftidak tersedia di Command Prompt. Gunakan PowerShell denganRemove-Item -Recurse -Forceseperti ditunjukkan di Langkah 3. terus, path separator (\vs/) kadang mempengaruhi bagaimana exports map di-resolve, terutama jika kamu menulis exports map manual dengan path yang salah. - macOS/Linux: Tidak ada issue spesifik. Semua perintah di artikel ini berjalan as-is.
# macOS/Linux: bersihkan cache
rm -rf node_modules/.cache
# Windows PowerShell: bersihkan cache
Remove-Item -Recurse -Force node_modules\.cache -ErrorAction SilentlyContinue
Troubleshooting Lanjutan
Jika semua solusi di atas sudah kamu coba dan error tetap muncul, ada beberapa kemungkinan yang lebih dalam yang perlu diselidiki.
Cek Apakah Ada Alias atau Resolution Override
Beberapa framework seperti Next.js, Nuxt, atau Vite melakukan module resolution k