Kode yang berjalan lancar belum tentu kode yang sehat: variabel yang dideklarasikan lalu dilupakan, perbandingan longgar dengan ==, sisa var dari zaman lampau — semuanya bisa hidup bertahun-tahun tanpa pernah menimbulkan error, sampai suatu hari menimbulkan bug yang sulit dilacak. Linter adalah alat yang membaca kode tanpa menjalankannya lalu menandai pola-pola mencurigakan seperti itu. Pada chapter ini kita akan memakai ESLint, linter standar dunia JavaScript: menyiapkan konfigurasinya, membaca laporannya, dan memperbaiki sebagian masalah secara otomatis.
Apa itu Linter #
Linter melakukan static analysis: memeriksa struktur kode apa adanya, tanpa mengeksekusinya. Karena tidak perlu menjalankan program, pemeriksaan bisa dilakukan setiap kali berkas disimpan, bahkan sebelum program selesai ditulis. Hasilnya bukan sekadar gaya — banyak aturan linter menangkap sumber bug sungguhan, misalnya variabel yang tertukar karena tidak pernah terbaca, atau assignment yang sebenarnya dimaksudkan perbandingan.
ESLint bekerja dengan dua bahan: kode yang diperiksa, dan konfigurasi yang menyatakan aturan apa yang berlaku. Kita mulai dengan memastikan ESLint bisa dipanggil dari terminal:
npx --yes [email protected] --versionOutput yang Dihasilkan:
v10.12.0Perintah npx menjalankan sebuah package tanpa memasangnya secara permanen; kita mencantumkan versi secara eksplisit agar contoh di Course ini selalu menghasilkan keluaran yang sama. Pada proyek nyata, cara yang lebih lazim adalah memasang ESLint sebagai devDependency dengan npm install --save-dev eslint, lalu menjalankannya cukup dengan npx eslint .. Panduan lengkap pemasangan tersedia di dokumentasi resmi ESLint
.
Konfigurasi Flat Config #
ESLint modern dikonfigurasi lewat satu berkas JavaScript di akar proyek — biasanya bernama eslint.config.mjs — yang mengekspor array objek konfigurasi. Inilah konfigurasi yang kita pakai pada chapter ini:
export default [
{
files: ["**/*.mjs"],
rules: {
"no-var": "error",
"no-unused-vars": "error",
eqeqeq: "error",
},
},
];Mari kita bedah isinya:
- Baris 1 (
export default [...]): konfigurasi berupa array agar beberapa objek bisa ditumpuk — tiap objek bisa menargetkan berkas yang berbeda dengan aturan yang berbeda. - Baris 3 (
files: ["**/*.mjs"]): objek konfigurasi ini hanya berlaku untuk berkas.mjs; berkas lain tidak terkena aturannya. - Baris 4-8 (
rules): daftar aturan dan tingkat keparahannya. Nilai"error"membuat pelanggaran dianggap error; nilai"warn"hanya menghasilkan peringatan.
Setiap aturan punya halaman dokumentasi sendiri — daftar lengkapnya, ratusan jumlahnya, ada di katalog aturan ESLint . Format berkas konfigurasi ini disebut flat config dan dijelaskan tuntas di dokumentasi konfigurasi .
Berkas yang Berjalan tetapi Menyimpan Masalah #
Sekarang kita siapkan bahan uji pemeriksaan: sebuah berkas kecil yang berfungsi benar, penuh bekal cerita lama. Simpan dan jalankan dulu untuk membuktikan bahwa tidak ada yang salah secara nyata:
var hargaSatuan = 50000;
const jumlahTerjual = 3;
const stokLama = 12;
function hitungTotal(harga, jumlah) {
return harga * jumlah;
}
if (hitungTotal(hargaSatuan, jumlahTerjual) == 150000) {
console.log("total sesuai anggaran");
}Output yang Dihasilkan:
total sesuai anggaranProgram mencetak total sesuai anggaran — 50000 dikali 3 memang 150000. Tetapi perhatikan tiga kejanggalan yang tersimpan: var di baris 1 yang seharusnya let atau const, stokLama di baris 3 yang tidak pernah dipakai lagi (sisa refactor yang lupa dibersihkan), dan perbandingan == di baris 9 yang longgar terhadap perbedaan tipe.
Membaca Laporan ESLint #
Saatnya memeriksa berkas tersebut. Jalankan ESLint dengan menunjuk direktori saat ini (.), lalu perhatikan keluarannya:
npx --yes [email protected] . | sed 's|.*/||'
echo kode keluar: ${PIPESTATUS[0]}Output yang Dihasilkan:
berkas-bermasalah.mjs
1:1 error Unexpected var, use let or const instead no-var
3:7 error 'stokLama' is assigned a value but never used no-unused-vars
9:45 error Expected '===' and instead saw '==' eqeqeq
✖ 3 problems (3 errors, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.
kode keluar: 1Cara membaca laporan di atas:
- Baris nama berkas: judul satu blok temuan. Sebenarnya ESLint menuliskan path absolut berkas di sini; pipe
sed 's|.*/||'memangkasnya hingga tersisa nama berkas agar contoh di halaman ini ringkas — di terminal Anda baris tersebut menampilkan path lengkap. - Kolom posisi
baris:kolom: lokasi persis temuan, format sama dengan lokasi pada stack trace. - Kolom tingkat:
erroratauwarning, mengikuti nilai yang kita tulis di konfigurasi. - Pesan dan nama aturan: keterangan masalah diikuti nama aturannya — nama ini bisa dicari langsung di katalog aturan.
- Ringkasan
✖ 3 problems: jumlah total temuan beserta rinciannya, termasuk berapa yang bisa diperbaiki otomatis. kode keluar: 1: ESLint mengakhiri proses dengan exit code 1 karena ada error — perilaku inilah yang dimanfaatkan pipeline CI untuk menggagalkan build saat kode bermasalah;${PIPESTATUS[0]}dipakai untuk membaca exit code ESLint di ujung pertama pipe.
Ringkasan ketiga aturan yang kita aktifkan:
| Aturan | Yang dideteksi | Mengapa penting |
|---|---|---|
no-var | Deklarasi var | Cakupan var menjalar keluar blok, sumber kejutan klasik |
no-unused-vars | Variabel yang tidak pernah dipakai | Biasanya sisa refactor; menandakan kode mati atau salah ketik nama |
eqeqeq | Pemakaian == dan != | == mengonversi tipe secara diam-diam; === membandingkan apa adanya |
Memperbaiki Otomatis dengan –fix #
Sebagian aturan punya koreksi otomatis yang aman — mengganti var menjadi let, misalnya. Flag --fix menerapkan seluruh koreksi semacam itu langsung ke berkas. Karena flag ini menulis berkas, kita menyalinnya dulu supaya berkas asli tetap utuh untuk dipelajari:
cp berkas-bermasalah.mjs salinan.mjs
npx --yes [email protected] --fix salinan.mjs | sed 's|.*/||'
cat salinan.mjs
rm salinan.mjsOutput yang Dihasilkan:
salinan.mjs
3:7 error 'stokLama' is assigned a value but never used no-unused-vars
9:45 error Expected '===' and instead saw '==' eqeqeq
✖ 2 problems (2 errors, 0 warnings)
let hargaSatuan = 50000;
const jumlahTerjual = 3;
const stokLama = 12;
function hitungTotal(harga, jumlah) {
return harga * jumlah;
}
if (hitungTotal(hargaSatuan, jumlahTerjual) == 150000) {
console.log("total sesuai anggaran");
}Bandingkan hasilnya dengan berkas semula: var hargaSatuan telah menjadi let hargaSatuan — itu satu-satunya perbaikan otomatis yang tersedia, sehingga laporan kedua tinggal menyisakan dua masalah. Sisanya memang menuntut keputusan manusia: apakah stokLama sebaiknya dihapus atau memang akan dipakai nanti, dan apakah perbandingan == sengaja longgar atau justru harus ===. Perintah rm di akhir menghapus salinan agar contoh bisa dijalankan ulang dengan hasil yang sama.
ESLint di Editor dan Pipeline #
Pemeriksaan manual dari terminal hanyalah satu cara pemakaian. Ekstensi ESLint untuk VS Code dan editor lain menandai temuan langsung di editor dengan garis bergerigi saat kita mengetik, lengkap dengan keterangan aturannya — umpan balik yang jauh lebih cepat daripada menunggu perintah dijalankan. Di sisi lain, pipeline CI menjalankan eslint . pada setiap usulan penggabungan kode; exit code 1 otomatis menahan penggabungan bila ada error. Dengan tiga titik ini — editor, terminal, CI — aturan yang sama ditegakkan di seluruh perjalanan kode.
ESLint menjaga kualitas logika kode kita, tetapi ada satu wilayah yang sengaja tidak ia sentuh: bagaimana kode tampil — lebar indentasi, posisi tanda kutip, panjang baris. Menyeragamkan wilayah itu adalah pekerjaan Prettier, topik Chapter Formatting dengan Prettier.