Kenapa ini penting
Sebelum menulis server, kamu perlu nyaman dengan alat kerjanya: cara menjalankan file, membaca argumen dan environment variable, memilih sistem modul, dan mengatur skrip di package.json. Ini hal yang kamu lakukan puluhan kali sehari. Kalau dasarnya goyah, kamu akan membuang waktu di error seperti Cannot use import statement outside a module atau API key yang tiba-tiba undefined.
Kabar baiknya, Node versi modern sudah membawa banyak fitur yang dulu butuh paket tambahan: auto-restart saat file berubah (--watch), membaca file .env (--env-file), fetch bawaan, test runner bawaan (node:test), bahkan menjalankan file TypeScript sederhana. Tutorial lama sering masih menyuruh instal nodemon dan dotenv; untuk proyek baru, itu tidak perlu lagi.
Konsep inti
Instalasi dan versi
Pakai versi LTS (Long Term Support), yaitu versi genap yang dirawat lama. Per 24 Oktober 2026, LTS aktif adalah Node 24.x (terbaru 24.22.1, kode nama "Krypton"). Node 26 sudah rilis tapi masih berstatus "Current"; biasanya versi genap baru menjadi LTS sekitar akhir Oktober. Cek versi dengan:
node -v # contoh: v24.22.1
npm -v
Kalau kamu perlu berganti-ganti versi antar proyek, gunakan version manager seperti nvm, fnm, atau volta.
REPL dan menjalankan file
REPL (Read-Eval-Print Loop) adalah konsol interaktif, mirip tab Console di DevTools. Ketik node tanpa argumen, lalu coba-coba kode. Keluar dengan .exit atau Ctrl+D. Untuk menjalankan file: node nama-file.js. Untuk satu baris cepat: node -e "console.log(1 + 1)" atau node -p "1 + 1" (-p langsung mencetak hasil).
process: jendela ke proses yang sedang berjalan
Objek global process berisi informasi tentang program yang berjalan:
| Properti/metode | Isi |
|---|---|
process.argv |
Array argumen command line. Indeks 0 = path node, 1 = path file, sisanya argumenmu |
process.env |
Environment variable, semuanya berupa string (atau undefined) |
process.version / process.platform |
Versi Node dan OS (darwin, linux, win32) |
process.cwd() |
Folder tempat perintah dijalankan |
process.exit(kode) |
Menghentikan program; kode 0 = sukses, selain 0 = gagal |
process.uptime() |
Lama proses berjalan dalam detik |
Environment variable adalah konfigurasi di luar kode: port, URL database, API key. Analoginya seperti setelan di dinding dapur: resepnya (kode) sama, tapi suhu oven (konfigurasi) bisa beda di tiap cabang (laptop, staging, produksi). Rahasia seperti API key tidak boleh ditulis langsung di kode atau di-commit ke Git.
--env-file dan --watch
Node bisa membaca file .env langsung: node --env-file=.env app.js. Kalau file mungkin tidak ada (misalnya di server produksi yang memakai env sungguhan), gunakan --env-file-if-exists=.env supaya tidak error. Dari dalam kode, ada juga process.loadEnvFile() dari node:process.
node --watch app.js menjalankan ulang program setiap kali file itu atau modul yang di-import berubah. Mode watch berstatus stabil sejak Node 22. Untuk mengawasi folder tertentu, ada --watch-path=./src.
ESM vs CommonJS
Node punya dua sistem modul:
| ESM (ECMAScript Modules) | CommonJS (CJS) | |
|---|---|---|
| Sintaks | import x from "y", export |
const x = require("y"), module.exports |
| Aktif kalau | "type": "module" di package.json, atau file .mjs |
default lama, atau file .cjs |
await di level atas |
Bisa | Tidak bisa |
| Path file sendiri | import.meta.filename, import.meta.dirname |
__filename, __dirname |
| Import file lokal | Wajib pakai ekstensi: ./utils.js |
Ekstensi boleh dihilangkan |
ESM adalah standar JavaScript yang sama dengan yang kamu pakai di React/Vite, jadi kita pakai ESM di seluruh materi. Modul bawaan Node sebaiknya di-import dengan prefix node: (node:fs, node:path) supaya jelas bukan paket npm.
npm dan package.json
npm init -y membuat package.json. File ini berisi nama proyek, dependensi, dan scripts. npm install express menambahkan paket ke dependencies dan mengunci versi persisnya di package-lock.json (yang harus ikut di-commit). Paket yang hanya dipakai saat development diinstal dengan npm install -D.
Scripts dijalankan dengan npm run <nama>; khusus start dan test bisa tanpa run. Node juga punya node --run <nama> yang menjalankan script lebih cepat tanpa lewat npm.
Bagaimana dengan TypeScript?
Node 24 bisa menjalankan file .ts secara langsung dengan type stripping (stabil sejak v24.12.0): anotasi tipe dibuang lalu kodenya dijalankan. Tidak ada pengecekan tipe, dan sintaks yang butuh transformasi seperti enum tidak didukung kecuali dengan flag --experimental-transform-types. Untuk pengecekan tipe tetap pakai tsc --noEmit atau editor.
Contoh kode
Struktur package.json yang dipakai di materi ini:
{
"name": "belajar-node",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "node --watch --env-file=.env server.js",
"start": "node --env-file=.env server.js",
"test": "node --test"
}
}
Membaca argumen dan environment:
// argv.js
const [, , nama = "teman", ...sisanya] = process.argv; // lewati path node & path file
console.log(`Halo, ${nama}!`);
console.log("Argumen lain:", sisanya);
console.log("PORT dari env:", process.env.PORT ?? "(tidak ada)");
console.log("Node versi:", process.version, "| platform:", process.platform);
# File .env (JANGAN di-commit; tambahkan ke .gitignore)
# PORT=4000
# APP_NAME=Tugasku
node argv.js Budi a b
# → Halo, Budi!
# → Argumen lain: [ 'a', 'b' ]
# → PORT dari env: (tidak ada)
# → Node versi: v26.0.0 | platform: darwin
node --env-file=.env argv.js Sari
# → Halo, Sari!
# → Argumen lain: []
# → PORT dari env: 4000
# → Node versi: v26.0.0 | platform: darwin
(Output di atas diambil dari mesin uji yang memakai Node 26.0.0; di Node 24 LTS hasilnya sama kecuali baris versi.)
Mencoba REPL dan TypeScript langsung:
node -e 'console.log(1 + 1)'
# → 2
node # masuk REPL
> const x = [1, 2, 3]; x.map((n) => n * 2)
# → [ 2, 4, 6 ]
> .exit
// tipe.ts, dijalankan dengan: node tipe.ts
type Tugas = { id: number; judul: string };
const t: Tugas = { id: 1, judul: "Coba TS" };
console.log(t.judul);
// → Coba TS
Kesalahan umum
- Lupa
"type": "module". Hasilnya errorCannot use import statement outside a moduleatau peringatan module type. Tambahkan dipackage.json, atau pakai ekstensi.mjs. - Import file lokal tanpa ekstensi di ESM.
import { x } from "./utils"gagal denganERR_MODULE_NOT_FOUND. Tulis./utils.js. - Menganggap
process.env.PORTberupa angka. Semua env adalah string.process.env.DEBUG === trueselalufalse; bandingkan dengan"true", dan ubah angka denganNumber(...). - Commit file
.env. Rahasia bocor ke riwayat Git selamanya. Masukkan.envke.gitignoredan sediakan.env.exampletanpa nilai rahasia. - Masih memakai
__dirnamedi ESM. Tidak tersedia. Gunakanimport.meta.dirname(danimport.meta.filename).
Latihan
- Mudah, Buat skrip
salam.jsyang menerima nama dan jam (node salam.js Rina 20) lalu mencetak "Selamat pagi/siang/malam, Rina" sesuai jam. - Sedang, Buat skrip
config.jsyang membacaPORTdanMODEdari env. KalauPORTbukan angka, cetak pesan error dan keluar denganprocess.exit(1). Jalankan dengan--env-file. - Menantang, Siapkan proyek dengan script
dev(watch + env file) dancheckyang mencetak versi Node lalu gagal (exit 1) kalau versi mayor di bawah 24.
Lihat solusi
1.
// salam.js
const [, , nama = "teman", jamTeks = String(new Date().getHours())] = process.argv;
const jam = Number(jamTeks);
const waktu = jam < 11 ? "pagi" : jam < 15 ? "siang" : jam < 18 ? "sore" : "malam";
console.log(`Selamat ${waktu}, ${nama}`);
// node salam.js Rina 20 → Selamat malam, Rina
2.
// config.js, jalankan: node --env-file=.env config.js
const port = Number(process.env.PORT);
if (!Number.isInteger(port) || port <= 0) {
console.error(`PORT tidak valid: ${process.env.PORT}`);
process.exit(1);
}
const mode = process.env.MODE ?? "development";
console.log({ port, mode });
3.
{
"type": "module",
"scripts": {
"dev": "node --watch --env-file-if-exists=.env server.js",
"check": "node check-version.js"
}
}
// check-version.js
const mayor = Number(process.versions.node.split(".")[0]);
console.log(`Node ${process.version}`);
if (mayor < 24) {
console.error("Butuh Node 24 atau lebih baru");
process.exit(1);
}
Ringkasan
- Pakai Node versi LTS (24.x per Oktober 2026); cek dengan
node -v. process.argvberisi argumen,process.envberisi konfigurasi yang selalu bertipe string.node --env-file=.envdannode --watchmenggantikandotenvdannodemonuntuk kebutuhan dasar.- Gunakan ESM (
"type": "module"), tulis ekstensi file saat import lokal, dan prefixnode:untuk modul bawaan. - Simpan perintah rutin di
scriptspackage.json; commitpackage-lock.json, jangan commit.env. - Node 24 bisa menjalankan
.tssederhana via type stripping, tanpa pengecekan tipe.