Belajar Node.js - Modul CommonJS vs ES Modules
Episode 4 of 23

Belajar Node.js - Modul CommonJS vs ES Modules

Node.js mendukung dua sistem modul: CommonJS dengan require dan ES Modules dengan import. Episode ini membandingkan keduanya, menjelaskan field type di package.json, serta cara mencampur kedua sistem di satu project.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Node.js punya sejarah unik dalam hal modul: awalnya memakai CommonJS dengan require, lalu sejak versi 12 mendukung penuh ES Modules dengan import yang standar di seluruh ekosistem JavaScript. Keduanya masih hidup berdampingan, dan kalian akan menemukan keduanya di kode production.

Episode 4 membandingkan kedua sistem modul: sintaks, cara kerja internal, cara menentukan mode default via package.json, dan aturan mencampur keduanya. Setelah episode ini, kalian bisa membaca dan menulis kode dalam kedua format tanpa ragu.

CommonJS: require dan module.exports

Sistem Modul Asli Node.js

CommonJS adalah sistem modul yang mengantar Node.js sejak lahir. Setiap file dianggap modul terpisah, dan satu file mengekspos isinya lewat objek module.exports:

JSmath.js (CommonJS)
function tambah(a, b) {
  return a + b;
}
 
module.exports = { tambah };

File lain memuatnya dengan require:

JSapp.js (CommonJS)
const { tambah } = require("./math.js");
 
console.log(tambah(2, 3));

Pola module.exports = { tambah } mengekspor objek, lalu require("./math.js") memuatnya dan destructuring mengambil fungsi tambah. Ciri khas CommonJS: eksekusi terjadi sinkron saat require dipanggil, dan hasilnya di-cache sehingga pemanggilan kedua tidak mengeksekusi file lagi.

Variabel Khas CommonJS

Di CommonJS, Node.js menyuntikkan variabel khusus: module, exports, require, __filename, dan __dirname. Dua yang terakhir sangat berguna untuk menyusun jalur file, seperti yang kita pakai di episode 3.

ES Modules: import dan export

Standar JavaScript Modern

ES Modules (ESM) adalah sistem modul resmi dari spesifikasi JavaScript — dipakai di browser dan Node.js. Sintaksnya deklaratif dan static, sehingga analyzer bisa memeriksa dependensi tanpa menjalankan kode:

JSmath.mjs (ESM)
export function tambah(a, b) {
  return a + b;
}
JSapp.mjs (ESM)
import { tambah } from "./math.mjs";
 
console.log(tambah(2, 3));

Perhatikan perbedaannya: export langsung menandai fungsi yang diekspos, dan import { tambah } from "./math.mjs" memuatnya. Di ESM, __dirname tidak tersedia — sebagai gantinya Node.js menyediakan import.meta.url yang menunjuk lokasi file saat ini.

ESM Bersifat Asynchronous

Berbeda dengan CommonJS yang sinkron, ESM di Node.js dieksekusi asynchronous — sangat penting untuk mendukung top-level await, yaitu memakai await langsung di tingkat teratas file tanpa membungkusnya dalam fungsi. Ini membuat kode ESM jauh lebih bersih untuk operasi I/O.

Menentukan Mode Modul

Field type di package.json

Format file ditentukan oleh ekstensi dan field "type" di package.json:

  • Tanpa "type" atau "type": "commonjs": file .js diperlakukan sebagai CommonJS.
  • "type": "module": file .js diperlakukan sebagai ES Modules.
  • Ekstensi .mjs selalu ESM; ekstensi .cjs selalu CommonJS.
package.json
{
  "name": "belajar-modul",
  "version": "1.0.0",
  "type": "module"
}

Dengan "type": "module", semua file .js di project memakai sintaks import. Project baru disarankan memakai ESM — ini arah standar industri dan seluruh contoh selanjutnya di series ini.

Mencampur Kedua Sistem

Interoperabilitas yang Fleksibel

Kabar baiknya, kedua sistem bisa berdampingan. Node.js mengizinkan memakai import untuk memuat modul CommonJS, dan memakai require untuk memuat modul ESM (khususnya di file .cjs):

JSMemuat CJS dari ESM
import math from "./math.cjs";
 
console.log(math.tambah(4, 5));

Modul CommonJS mengekspor objek module.exports yang otomatis menjadi default export ketika dimuat dari ESM. Karena itu, import math from "./math.cjs" langsung mendapatkan seluruh objek ekspor tanpa kurung kurawal.

Berpindah Antar Format dengan Aman

Saat migrasi project dari CommonJS ke ESM, mulai dari file dengan dependensi paling sedikit. Modul pihak ketiga modern hampir semuanya sudah menyediakan export ESM, sedangkan paket lawas tetap bisa dimuat dari ESM melalui default export. Yang perlu dihindari: berganti-ganti "type" di tengah project tanpa perencanaan, karena akan memicu error seperti ERR_REQUIRE_ESM atau ERR_UNKNOWN_FILE_EXTENSION.

Penutup

Inti yang harus dibawa pulang:

  • CommonJS memakai require dan module.exports; sinkron dan di-cache.
  • ESM memakai import dan export; standar JavaScript modern dan asynchronous.
  • Field "type": "module" menjadikan file .js sebagai ESM.
  • Ekstensi .mjs dan .cjs memaksa format masing-masing.
  • Modul CJS bisa dimuat dari ESM lewat default export.
  • Project baru disarankan memakai ES Modules.

Di episode 5 selanjutnya kita akan membahas file I/O dan stream dasar — API fs/promises yang modern, konsep stream untuk file besar, pipeline, dan readline. Kalian akan melihat kenapa streaming bukan sekadar gaya, tapi kebutuhan untuk server yang hemat memori.

Belajar Node.js - Modul CommonJS vs ES Modules | Belajar Node.js