Chapter sebelumnya menunjukkan bahwa process.argv menyerahkan argumen mentah tanpa struktur: flag, nilai opsi, dan argumen posisi datang bercampur dalam satu array string. Memilah semuanya sendiri itu mungkin, tetapi setiap program akan menulis ulang aturan yang sama persis. Node.js menyediakan jalan keluar bawaan: function parseArgs() dari module node:util, yang memilah argumen berdasarkan skema yang kita deklarasikan. Pada chapter ini kita menyusun skema opsi, mengelola nilai default, memanfaatkan mode strict, dan menyediakan bantuan --help dengan tangan sendiri.
Menyusun Skema Opsi #
Inti parseArgs() ada di property options: peta nama opsi ke tipe dan singkatannya. Berkas catatan.mjs menerima satu argumen posisi, satu opsi bernilai, dan satu flag:
import { parseArgs } from "node:util";
const { values, positionals } = parseArgs({
allowPositionals: true,
options: {
prioritas: { type: "string", short: "p" },
tandai: { type: "boolean", short: "t" },
},
});
console.log("positionals:", positionals);
console.log("prioritas :", values.prioritas);
console.log("tandai :", values.tandai);Output yang Dihasilkan:
positionals: [ 'belajar-node' ]
prioritas : tinggi
tandai : trueProgram di atas dijalankan dengan perintah node catatan.mjs belajar-node --tandai --prioritas=tinggi. Mari kita telaah baris-per-baris kode di atas:
- Baris 4 (
allowPositionals: true): argumen bebas sepertibelajar-nodehanya diterima bila opsi ini diaktifkan. Tanpa baris ini,parseArgs()melempar errorERR_PARSE_ARGS_UNEXPECTED_POSITIONAL— perilaku yang sudah kita buktikan pada chapter Module util di Section Core Modules. - Baris 5-8 (
options): opsiprioritasbertipe"string"dengan bentuk pendek-p, sedangkantandaibertipe"boolean"dengan bentuk pendek-t. Tipe menentukan apakah opsi menunggu nilai atau cukup ditulis saja. - Baris 10 (
values, positionals): hasil pemilahan terbagi dua — arraypositionalsberisi argumen posisi berurutan, objectvaluesberisi pasangan opsi-nilai. Opsi--prioritas=tinggimenghasilkan string"tinggi", dan flag--tandaimenghasilkan booleantrue, bukan string"true".
Mode strict Menjaga Disiplin #
Secara bawaan parseArgs() berjalan dalam mode strict: hanya opsi terdaftar yang boleh masuk. Salah ketik sekecil apa pun langsung ditolak dengan error, bukan diam-diam diabaikan. Berkas mode-strict.mjs menangkap error tersebut agar pesannya bisa kita periksa:
import { parseArgs } from "node:util";
try {
const { values } = parseArgs({
options: {
tandai: { type: "boolean" },
prioritas: { type: "string", default: "sedang" },
},
});
console.log("opsi diterima:", values);
} catch (error) {
console.log("kode error:", error.code);
console.log("pesan :", error.message);
}Output yang Dihasilkan:
kode error: ERR_PARSE_ARGS_UNKNOWN_OPTION
pesan : Unknown option '--tanda'Program sengaja dijalankan dengan opsi yang salah ketik: --tanda, bukan --tandai. Hasilnya adalah error bawaan Node.js dengan kode ERR_PARSE_ARGS_UNKNOWN_OPTION dan pesan Unknown option '--tanda'. Tanpa try/catch, error ini menghentikan program dengan exit code 1 — perilaku yang justru diinginkan untuk alat CLI, karena pengguna langsung tahu opsinya salah alih-alih mendapat hasil aneh dari opsi yang tidak pernah terbaca.
Nilai Default dan Flag yang Tidak Diisi #
Dua perilaku values penting diketahui sebelum merancang opsi. Opsi bernilai dapat diberi default sehingga program tetap jalan meski pengguna tidak mengetik apa-apa. Sementara flag boolean yang tidak diketik bernilai undefined — bukan false. Berkas nilai-default.mjs memperlihatkan keduanya:
import { parseArgs } from "node:util";
const { values } = parseArgs({
options: {
prioritas: { type: "string", default: "sedang" },
tandai: { type: "boolean" },
},
});
console.log("prioritas :", values.prioritas);
console.log("tandai :", values.tandai);
console.log("tandai ?? false:", values.tandai ?? false);Output yang Dihasilkan:
prioritas : sedang
tandai : undefined
tandai ?? false: falseProgram berjalan tanpa argumen apa pun. Opsi prioritas terisi "sedang" dari nilai default, sedangkan tandai bernilai undefined. Untuk kondisi if, undefined memang berperilaku seperti false, tetapi saat nilainya perlu dicetak atau dikirim ke tempat lain, pola values.tandai ?? false mengubahnya menjadi boolean true/false yang eksplisit dan lebih rapi dibaca.
Menyediakan –help Sendiri #
Berbeda dengan framework CLI, parseArgs() tidak menghasilkan layar bantuan otomatis — kita mendaftarkan opsi bantuan seperti opsi lainnya lalu mencetak teksnya sendiri. Berkas bantuan.mjs memakai flag --bantuan dengan bentuk pendek -h:
import { parseArgs } from "node:util";
const { values } = parseArgs({
options: {
bantuan: { type: "boolean", short: "h" },
nama: { type: "string", short: "n", default: "Dunia" },
},
});
if (values.bantuan) {
console.log("Pemakaian: sapa.mjs [opsi]");
console.log("");
console.log(" -n, --nama <nama> nama yang akan disapa (default: Dunia)");
console.log(" -h, --bantuan tampilkan bantuan ini");
process.exit(0);
}
console.log(`Halo, ${values.nama}!`);Output yang Dihasilkan:
Pemakaian: sapa.mjs [opsi]
-n, --nama <nama> nama yang akan disapa (default: Dunia)
-h, --bantuan tampilkan bantuan iniAlurnya sederhana: bila values.bantuan bernilai true, teks bantuan dicetak lalu process.exit(0) mengakhiri program sebelum pekerjaan utama berjalan. Tanpa flag tersebut, program langsung menyapa. Jalankan dengan bentuk pendeknya untuk melihat jalur normal — kode yang sama, tanpa flag bantuan:
import { parseArgs } from "node:util";
const { values } = parseArgs({
options: {
bantuan: { type: "boolean", short: "h" },
nama: { type: "string", short: "n", default: "Dunia" },
},
});
if (values.bantuan) {
console.log("Pemakaian: sapa.mjs [opsi]");
console.log("");
console.log(" -n, --nama <nama> nama yang akan disapa (default: Dunia)");
console.log(" -h, --bantuan tampilkan bantuan ini");
process.exit(0);
}
console.log(`Halo, ${values.nama}!`);Output yang Dihasilkan:
Halo, Siti!Dengan parseArgs(), kebutuhan CLI sederhana sudah tertangani tanpa satu pun package tambahan. Namun argumen hanyalah satu kanal masukan; alat nyata juga membaca konfigurasi dari luar command line. Kanal tersebut adalah environment variable — topik chapter berikutnya.
Referensi lanjutan untuk topik chapter ini: