Built-in Modules: fs, path, os — Node.js

Node.js menyediakan banyak built-in modules yang tidak perlu diinstall. Tiga yang paling sering dipakai: fs, path, dan os. fs — File System Ada 3 varian untuk…

Node.js datang dengan modul bawaan yang tinggal dipakai, tanpa npm install. Bayangin kamar kos yang sudah lengkap perabotnya: ada lemari untuk menyimpan barang, denah yang memberi alamat tiap ruangan, dan papan info gedung. Di Node, lemarinya fs (membaca dan menulis file), denahnya path (menyusun alamat file), dan papan infonya os (info tentang mesin).

🧪 Tebakan cepat: __dirname berisi /home/budi/catatan-api. File mana yang dibuka __dirname + "data/catatan.json"? Tebak dulu, jawabannya ada di bagian "path: menyusun alamat file".

Modul bawaan: tinggal require

const fs = require("node:fs/promises");
const path = require("node:path");
const os = require("node:os");

Awalan node: menandai modul bawaan Node. Tanpa awalan juga jalan (require("fs")), tapi dengan awalan langsung jelas ini bukan paket dari npm. node:fs/promises adalah versi fs yang mengembalikan Promise, jadi bisa dipakai dengan await.

fs: membaca file

Proyek catatan-api sekarang menyimpan datanya di file data/catatan.json, isinya array dua catatan yang sama dengan pelajaran sebelumnya. app.js membacanya:

async function main() {
  const lokasi = path.join(__dirname, "data", "catatan.json");
  console.log(lokasi);
  try {
    const isi = await fs.readFile(lokasi, "utf8");
    const catatan = JSON.parse(isi);
    console.log(catatan.length + " catatan dibaca");
  } catch (err) {
    console.log(err.message);
  }
}

main();
$ node app.js
/home/budi/catatan-api/data/catatan.json
2 catatan dibaca

Hampir tiap fungsi fs punya tiga gaya: Promise (await fs.readFile, yang dipakai di sini), callback (fs.readFile(lokasi, "utf8", (err, isi) => {...}), gaya lama), dan Sync (fs.readFileSync). Versi Sync memblokir event loop: selama file dibaca, Node gak bisa mengerjakan apa pun, termasuk menjawab request lain. Itu gak masalah di script sekali jalan atau saat server baru menyala, tapi jangan dipakai di dalam handler request.

path: menyusun alamat file

__dirname berisi folder tempat file yang sedang jalan berada. path.join menyambung bagian-bagian alamat dengan pemisah yang benar untuk OS-nya:

Kode Linux dan macOS Windows
path.join(__dirname, "data", "catatan.json") /home/budi/catatan-api/data/catatan.json C:\Users\budi\catatan-api\data\catatan.json
__dirname + "/data/catatan.json" /home/budi/catatan-api/data/catatan.json C:\Users\budi\catatan-api/data/catatan.json
__dirname + "data/catatan.json" /home/budi/catatan-apidata/catatan.json C:\Users\budi\catatan-apidata/catatan.json

Baris terakhir menjawab tebakannya: __dirname gak diakhiri garis miring, jadi catatan-api dan data menempel jadi catatan-apidata. File itu gak ada, hasilnya ENOENT. Baris tengah jalan di Linux, tapi di Windows pemisahnya campur aduk: Node di Windows masih mau membukanya, tapi path seperti itu gak cross-platform dan gampang rusak waktu dibandingkan atau dikirim ke program lain. path.join memilih pemisah yang benar dan merapikan garis miring ganda, jadi pakai itu.

Fungsi path lain yang sering dipakai, untuk lokasi di atas:

os: info tentang mesin

console.log(os.platform()); // "linux", "darwin" (macOS), atau "win32" (Windows)
console.log(os.cpus().length); // jumlah core CPU, misalnya 8
console.log(os.homedir()); // "/home/budi"

os berguna untuk menyesuaikan program dengan mesinnya, misalnya memakai semua core CPU (nanti di pelajaran clustering).

Di ES Modules, __dirname gak ada

File ES Modules yang menulis __dirname gagal dengan ReferenceError: __dirname is not defined in ES module scope. Penggantinya import.meta.dirname (ada sejak Node 20.11), dan import.meta.filename untuk path file-nya sendiri.

Di latihan: fs tiruan

Simulator latihan gak punya disk sungguhan, jadi "file system"-nya object files yang memetakan nama file ke isinya. readFile(filepath) mengembalikan isinya, atau melempar error dengan throw new Error("File tidak ditemukan") kalau nama itu gak ada. transform(filepath) membacanya di dalam try, membesarkan hurufnya dengan toUpperCase(), mengambil ekstensinya dengan path.extname, lalu mencetak:

notes.txt -> ext: .txt, content: HELLO DUNIA
data.json -> ext: .json, content: {"X":1}
missing.txt -> Error: File tidak ditemukan

⚠️ Jebakan yang sering ketemu

TL;DR: Modul bawaan dipakai tanpa install: require("node:fs/promises"), require("node:path"), require("node:os"). Baca file dengan await fs.readFile(lokasi, "utf8") di dalam try/catch, dan file yang gak ada memberi err.code "ENOENT". readFileSync memblokir event loop, jadi jangan dipakai di handler request. Susun alamat dengan path.join(__dirname, "data", "catatan.json"): pemisahnya / di Linux dan macOS, \ di Windows, sedangkan menyambung dengan + gak cross-platform. path.extname mengambil ekstensi, os.platform() memberi nama OS. Di ES Modules, pakai import.meta.dirname.

Yang akan kamu pelajari