package-lock.json adalah berkas yang merekam versi spesifik setiap dependensi beserta sumber dan integritasnya. Topik ini membahas struktur lockfile, perbedaan npm install dan npm ci, serta peran lockfile dalam menjaga instalasi yang dapat direproduksi. Setelah membaca topik ini, lockfile dapat diperlakukan sebagai bagian dari sumber kode, bukan berkas yang dibuang.
Isi package-lock.json#
Lockfile diciptakan otomatis oleh npm install di samping package.json. Berkas ini berisi metadata versi, alamat registry tempat paket diunduh, dan integrity hash yang diverifikasi npm saat pengunduhan berikutnya. Bilangan lockfileVersion menyatakan versi format, saat ini 3 untuk npm modern.
# siapkan direktori demo di /tmp (bersihkan dulu bila ada)
rm -rf /tmp/lockfile-demo
mkdir -p /tmp/lockfile-demo
(cd /tmp/lockfile-demo && npm init -y >/dev/null && npm install semver@^7.5.0 >/dev/null 2>&1)
# tampilkan ringkasan struktur lockfile
node -e "const l=require('/tmp/lockfile-demo/package-lock.json'); console.log('lockfileVersion:', l.lockfileVersion); console.log('packages:', Object.keys(l.packages)); console.log('semver:', l.packages['node_modules/semver'].version);"lockfileVersion: 3
packages: [ '', 'node_modules/semver' ]
semver: 7.8.5Setiap entri pada objek packages menyatakan satu paket terpasang. Kunci berupa jalur relatif node_modules/<nama>, dan nilai berisi version, resolved (URL tarball), integrity (hash SHA-512), serta dependencies jika paket itu memiliki dependensi sendiri. Akar ("") menyatakan paket proyek sendiri, dengan referensi ke package.json sebagai sumber deklarasi rentang.
Integrity hash menjadi pemeriksaan keamanan. Saat npm mengunduh tarball pada instalasi berikutnya, hash dihitung ulang dan dibandingkan dengan yang tercatat di lockfile. Bila hash berbeda, npm membatalkan instalasi karena tarball telah berubah, kemungkinan karena kompromi registry atau penggantian paket tanpa pemberitahuan.
install vs ci#
npm install memasang dependensi sesuai rentang pada package.json, dan boleh memperbarui lockfile bila ada versi lebih baru yang terpenuhi. Perintah ini cocok untuk pengembangan sehari-hari, ketika pembaruan minor dan patch diterima. npm ci sebaliknya memasang persis dari lockfile, mengabaikan rentang pada package.json, dan menghapus node_modules yang ada sebelum memasang ulang.
# simulasi fresh clone: hapus node_modules, lalu pasang dari lockfile
(cd /tmp/lockfile-demo && rm -rf node_modules && npm ci >/dev/null 2>&1 && npm ls semver)[email protected] /tmp/lockfile-demo
└── [email protected]npm ci memerlukan package-lock.json yang sinkron dengan package.json. Bila sebuah dependensi ditambahkan ke package.json tanpa pembaruan lockfile, npm ci membatalkan instalasi dengan pesan yang menyebutkan paket hilang dari lockfile. Perilaku ini mencegah instalasi yang tidak terduga pada lingkungan CI.
Selain sinkronisasi, npm ci juga memerlukan package.json yang ada di direktori yang sama. Perintah ini tidak menerima argumen nama paket, sehingga tidak dapat dipakai untuk menambah dependensi baru. Penambahan atau pembaruan dependensi dilakukan melalui tiga langkah berurutan: jalankan npm install <pkg> untuk memperbarui package.json dan lockfile, komit lockfile yang diperbarui ke repository, lalu pakai npm ci pada instalasi berikutnya.
# tambah dependensi pada package.json tanpa memperbarui lockfile
(cd /tmp/lockfile-demo && node -e "const fs=require('fs'); const p=JSON.parse(fs.readFileSync('./package.json')); p.dependencies['debug']='^4.3.4'; fs.writeFileSync('./package.json', JSON.stringify(p,null,2))" && rm -rf node_modules && npm ci 2>&1 | head -5)npm error code EUSAGE
npm error
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error
npm error Missing: [email protected] from lock filePerintah di atas menambahkan debug ke package.json tanpa menjalankan npm install, sehingga lockfile tidak memuat entri untuk debug. npm ci mendeteksi ketidaksesuaian ini dan membatalkan instalasi. Untuk memperbaikinya, jalankan npm install agar lockfile diperbarui, baru kemudian npm ci berhasil.
Reproducibility#
Lockfile menjamin bahwa dua instalasi pada mesin berbeda menghasilkan pohon node_modules yang sama, selama lockfile-nya identik. Jaminan ini penting pada pipeline CI dan kolaborasi tim, di mana perbedaan versi dependensi dapat menyebabkan perilaku berbeda pada pengujian atau produksi.
Tanpa lockfile, npm install menyelesaikan rentang versi setiap kali dijalankan, sehingga versi yang dipasang bergantung pada apa yang tersedia di registry saat itu. Paket yang merilis versi minor baru antara dua instalasi dapat membuat pohon dependensi berbeda tanpa perubahan pada package.json. Lockfile mengunci versi spesifik, sehingga perilaku kode tetap dapat diprediksi.
Praktik yang dianjurkan adalah menyimpan package-lock.json di dalam repository versi, kecuali pada paket yang dipublikasikan ke registry sebagai library. Untuk library, beberapa pemelihara mengabaikan lockfile pada publikasi agar konsumen memperoleh versi terbaru dalam rentang yang dideklarasikan. Aplikasi dan layanan sebaiknya selalu menyimpan lockfile.
Selain reproduksibilitas, lockfile juga mempercepat instalasi. Karena versi spesifik dan alamat tarball sudah diketahui, npm tidak perlu menyelesaikan rentang versi atau menjelajahi metadata paket satu per satu. Pada pipeline CI dengan cache node_modules, npm ci dapat menyelesaikan instalasi dalam hitungan detik untuk proyek menengah, jauh lebih cepat dibanding npm install yang menyelesaikan rentang dari awal.
Kesalahan umum#
Penyertaan package-lock.json di .gitignore menghilangkan jaminan reproduksibilitas. Tim yang berbeda versi dependensi dapat mengalami bug yang tidak terjadi pada mesin lain. Sertakan lockfile di repository untuk aplikasi dan layanan.
Pemakaian npm install pada CI, alih-alih npm ci, memungkinkan pembaruan dependensi tanpa peninjauan. Perubahan minor pada dependensi dapat masuk ke produksi tanpa pengujian eksplisit. Gunakan npm ci pada lingkungan CI, dan npm install hanya untuk pengembangan lokal.
Penanganan konflik lockfile saat penggabungan cabang sering dilakukan dengan menerima salah satu versi secara membabi buta. Pendekatan yang benar adalah menjalankan npm install setelah penggabungan agar lockfile diregenerasi dari package.json yang sudah konsolidasi.
Penghapusan package-lock.json untuk “menyelesaikan” konflik instalasi juga sering terjadi, tetapi tindakan ini menghapus seluruh rekam jejak versi spesifik. Bila instalasi bermasalah, periksa dulu apakah package.json dan lockfile sinkron, lalu jalankan npm install untuk memperbarui lockfile, bukan menghapusnya.
Ringkasan#
package-lock.jsonmencatat versi spesifik, alamat registry, dan integrity hash setiap paket terpasang, dengan formatlockfileVersion: 3pada npm modern.npm installmemasang sesuai rentang padapackage.jsondan dapat memperbarui lockfile, sedangkannpm cimemasang persis dari lockfile dan gagal bila lockfile tidak sinkron denganpackage.json.- Integrity hash pada lockfile diverifikasi npm saat pengunduhan berikutnya, sehingga tarball yang berubah tanpa otoritas membatalkan instalasi.
- Lockfile disimpan di repository untuk aplikasi dan layanan, dan
npm cidipakai pada CI agar instalasi dapat direproduksi.
Referensi#
- package-lock.json — npm Docs
— Skema dan bidang
package-lock.json, termasuklockfileVersiondan strukturpackages. - npm ci — npm Docs
— Perintah
npm ci, persyaratannya, dan perbedaan perilaku dibandingnpm install. - About audit reports — npm Docs — Hubungan integrity hash dengan pemeriksaan keamanan paket pada lockfile.