Budi memindahkan proyek etalase tokonya ke laptop Siti untuk dikerjakan bersama. Folder tersalin, tetapi begitu dijalankan, hasilnya berantakan — versi Prettier di mesin Siti berbeda, dan tidak ada catatan package apa saja yang diperlukan proyek. Semua pengetahuan itu selama ini tersimpan di kepala Budi, bukan di proyek.
package.json adalah jawaban ekosistem Node atas persoalan tersebut: satu berkas manifes di akar folder proyek yang mencatat identitas proyek, perintah yang bisa dijalankan, dan daftar dependensinya. Setiap alat yang kita bahas di section ini — ESLint, Prettier, bundler — dibaca dan dikendalikan dari berkas ini. Chapter ini membedah strukturnya medan per medan, lalu menutup dengan aturan versi yang dipakai npm di chapter berikutnya.
Anatomi package.json #
Berkas berikut adalah manifes realistis untuk proyek etalase Budi. Berkas JSON ini wajar dibuat manual — seluruh isinya kita bahas satu per satu:
{
"name": "toko-budi",
"version": "1.2.0",
"description": "Aplikasi etalase toko buku milik Budi",
"type": "module",
"main": "src/index.js",
"scripts": {
"dev": "node --watch src/index.js",
"test": "node --test",
"build": "esbuild src/index.js --bundle --minify --sourcemap --outfile=dist/bundle.js"
},
"keywords": ["toko", "buku", "etalase"],
"author": "Budi Santoso",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"devDependencies": {
"esbuild": "^0.27.2"
}
}Mari kita telaah tiap kelompoknya:
- Baris 2 (
"name": "toko-budi"): identitas proyek, ditulis huruf kecil tanpa spasi. Bila suatu hari proyek ini dipublikasikan ke registry npm, nama inilah yang dipakai orang lain untuk memasangnya. - Baris 3 (
"version": "1.2.0"): versi proyek mengikuti skema semantic versioning (dibahas di bagian bawah). Keduanya,namedanversion, adalah satu-satunya field yang wajib ada. - Baris 4–5 (
"description"dan"main"): keterangan singkat proyek, lalu berkas titik masuk yang dieksekusi bila proyek dipanggil denganrequire()atauimportdari proyek lain. - Baris 6 (
"type": "module"): menentukan bagaimana Node membaca berkas.jsdi proyek ini. Nilai"module"berartiimport/exportsah ditulis; tanpa field ini, berkas.jsdiperlakukan CommonJS (require). Field inilah yang membuat berkas.mjsdi chapter Modules bisa ditulis.js. - Baris 7–11 (
"scripts"): kumpulan pintasan perintah, dibahas di bagian berikutnya. - Baris 12–13 (
"keywords","author","license"): metadata tambahan — kata kunci pencarian, penulis, dan lisensi. Lisensi penting begitu kode dibagikan:MITmengizinkan pemakaian bebas dengan syarat mencantumkan atribusi. - Baris 14–19 (
"dependencies"dan"devDependencies"): dua daftar package yang dibutuhkan proyek, dibahas di bagian terakhir chapter ini.
scripts: Pintasan Perintah Proyek #
Field scripts memetakan nama pendek ke perintah terminal. Alih-alih mengingat baris esbuild ... --bundle --minify ..., kita cukup menjalankan npm run build. Untuk melihat cara kerjanya, manifes ini memakai satu script sederhana bernama salam:
npm run salamOutput yang Dihasilkan:
> [email protected] salam
> node salam.js
Halo, saya Budi dari proyek latihanDua baris pertama keluaran adalah bekas npm: npm memberi tahu proyek ([email protected]) dan nama script yang dijalankan (salam), lalu mencetak perintah yang sesungguhnya dieksekusi (node salam.js). Baris terakhir adalah keluaran program kita. Pola ini berlaku sama untuk script besar: npm run build akan mencetak perintah build di baris kedua, diikuti keluaran esbuild.
Beberapa nama script berstatus khusus: npm test dan npm start boleh dipanggil tanpa kata run. Nama lain — dev, build, salam, apa pun — selalu lewat npm run <nama>.
Versi dan Semantic Versioning #
Setiap nomor versi mengikuti skema semantic versioning (semver): MAJOR.MINOR.PATCH, contohnya 1.2.0. Tiga bagian itu punya kontrak makna:
- MAJOR naik bila ada perubahan yang merusak kompatibilitas (breaking change) — pemanggil lama bisa berhenti bekerja.
- MINOR naik bila ada fitur baru yang tetap kompatibel — pemanggil lama tetap bekerja.
- PATCH naik untuk perbaikan tanpa perubahan perilaku, misalnya bug kecil.
Di berkas contoh-package.json, dependensi ditulis "ms": "^2.1.3". Tanda ^ (caret) berarti “versi ini dan seterusnya selama MAJOR tetap sama” — npm boleh memasang 2.1.9 atau 2.3.0, tetapi tidak akan pernah memasang 3.0.0. Karakter ~ lebih sempit lagi (hanya PATCH yang boleh naik), dan penulisan tanpa awalan seperti 2.1.3 mengunci versi persis. Kontrak ini yang menjelaskan kenapa npm install bisa menghasilkan versi sedikit berbeda di dua mesin — dan kenapa berkas lockfile di chapter berikutnya dibutuhkan.
dependencies dan devDependencies #
Dua field terakhir memisahkan package berdasarkan tujuan pemakaiannya:
- dependencies: package yang dibutuhkan saat aplikasi berjalan.
msadalah contohnya — kode disrc/index.jsmemanggilnya saat pengguna membuka etalase. - devDependencies: package yang hanya dibutuhkan saat pengembangan: linter, formatter, test runner, dan bundler.
esbuildbekerja saat build di mesin pengembang; hasilnya (berkasdist/) yang dikirim ke pengguna, bukan esbuild itu sendiri.
Keduanya sama-sama terpasang lewat npm install di mesin pengembang, sehingga selama menulis kode perbedaannya tidak terasa. Perbedaan baru terasa saat memasang proyek untuk produksi: npm menyediakan opsi --omit=dev untuk melewati devDependencies, sehingga server produksi hanya membawa package yang memang dieksekusi.
Manifes ini menuliskan nama package yang dibutuhkan. Pertanyaan berikutnya: siapa yang benar-benar mengunduh package itu, menempatkan berkasnya ke folder node_modules, dan mencatat versi persisnya? Jawabannya npm — topik utuh chapter berikutnya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh-package.json
Unduh berkas{
"name": "toko-budi",
"version": "1.2.0",
"description": "Aplikasi etalase toko buku milik Budi",
"type": "module",
"main": "src/index.js",
"scripts": {
"dev": "node --watch src/index.js",
"test": "node --test",
"build": "esbuild src/index.js --bundle --minify --sourcemap --outfile=dist/bundle.js"
},
"keywords": ["toko", "buku", "etalase"],
"author": "Budi Santoso",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"devDependencies": {
"esbuild": "^0.27.2"
}
}