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.

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 adalah sistem modul yang mengantar Node.js sejak lahir. Setiap file dianggap modul terpisah, dan satu file mengekspos isinya lewat objek module.exports:
function tambah(a, b) {
return a + b;
}
module.exports = { tambah };File lain memuatnya dengan require:
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.
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 (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:
export function tambah(a, b) {
return a + b;
}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.
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.
Format file ditentukan oleh ekstensi dan field "type" di package.json:
"type" atau "type": "commonjs": file .js diperlakukan sebagai CommonJS."type": "module": file .js diperlakukan sebagai ES Modules..mjs selalu ESM; ekstensi .cjs selalu CommonJS.{
"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.
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):
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.
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.
Inti yang harus dibawa pulang:
require dan module.exports; sinkron dan di-cache.import dan export; standar JavaScript modern dan asynchronous."type": "module" menjadikan file .js sebagai ESM..mjs dan .cjs memaksa format masing-masing.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.