Penulis materi, terjemahan yang kami terbitkan hari ini, mengatakan bahwa salah satu masalah yang harus dihadapi oleh programmer adalah bahwa kode mereka berfungsi untuk mereka, dan itu memberikan kesalahan kepada orang lain. Masalah ini, mungkin salah satu yang paling umum, muncul karena fakta bahwa dependensi yang berbeda yang digunakan program diinstal dalam sistem pembuat dan pengguna program. Untuk mengatasi fenomena ini, file kunci yang disebut ada di manajer paket
benang dan
npm . Mereka berisi informasi tentang versi dependensi yang tepat. Mekanisme ini bermanfaat, tetapi jika seseorang mengembangkan paket yang direncanakan akan diterbitkan dalam npm, ia lebih baik tidak menggunakan file kunci. Materi ini didedikasikan untuk kisah mengapa demikian.

Singkatnya, hal terpenting
File kunci sangat berguna ketika mengembangkan aplikasi Node.js seperti server web. Namun, jika Anda berbicara tentang membuat perpustakaan atau alat baris perintah dengan tujuan penerbitan di npm, Anda perlu tahu bahwa file kunci di npm tidak dipublikasikan. Ini berarti bahwa jika file-file ini digunakan selama pengembangan, maka pembuat paket npm, dan mereka yang menggunakan paket ini, akan menggunakan versi dependensi yang berbeda.
Apa itu file kunci?
File kunci menjelaskan pohon ketergantungan lengkap dalam bentuk yang diperolehnya selama pekerjaan pada proyek. Deskripsi ini juga termasuk dependensi bersarang. File tersebut berisi informasi tentang versi spesifik dari paket yang digunakan. Dalam manajer paket npm, file seperti itu disebut
package-lock.json
, di thread -
yarn.lock
. Di kedua manajer, file-file ini terletak di folder yang sama dengan
package.json
.
Inilah yang terlihat seperti
package-lock.json
.
{ "name": "lockfile-demo", "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } } } }
Berikut ini contoh file
yarn.lock
. Itu tidak dirancang seperti
package-lock.json
, tetapi itu berisi data serupa.
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0"
Kedua file ini mengandung beberapa informasi ketergantungan kritis:
- Versi persis dari setiap ketergantungan yang diinstal.
- Ketergantungan informasi untuk setiap ketergantungan.
- Informasi tentang paket yang diunduh, termasuk checksum yang digunakan untuk memverifikasi integritas paket.
Jika semua dependensi terdaftar di file kunci, mengapa mereka menambahkan informasi tentang itu ke
package.json
? Mengapa dua file dibutuhkan?
Perbandingan package.json dan file kunci
Tujuan dari bidang
dependencies
dari file
package.json
adalah untuk menunjukkan dependensi proyek yang harus diinstal agar dapat berfungsi dengan baik. Tetapi ini tidak termasuk informasi tentang dependensi dari dependensi ini. Informasi ketergantungan dapat mencakup versi paket yang tepat atau rentang versi tertentu yang ditentukan sesuai dengan aturan
versi semantik . Saat menggunakan npm atau rentang benang, versi paket yang paling cocok dipilih.
Misalkan perintah
npm install
dijalankan untuk menginstal dependensi dari proyek tertentu. Selama proses instalasi, npm mengambil paket yang sesuai. Jika Anda menjalankan perintah ini lagi, setelah beberapa saat, dan jika versi baru dependensi dirilis selama waktu ini, mungkin saja kedua kalinya versi lain dari paket yang digunakan dalam proyek dimuat. Misalnya, jika Anda menginstal dependensi, seperti
twilio
, menggunakan
npm install twilio
, entri berikut ini mungkin muncul di bagian
dependencies
file
package.json
:
{ "dependencies": { "twilio": "^3.30.3" } }
Jika Anda melihat
dokumentasi versi semantik npm, Anda dapat melihat bahwa tanda
^
menunjukkan bahwa versi paket mana pun yang cocok, jumlah yang lebih besar dari atau sama dengan 3.30.3 dan kurang dari 4.0.0. Akibatnya, jika tidak ada file kunci dalam proyek dan versi baru dari paket dilepaskan, perintah
npm install
atau
yarn install
akan secara otomatis menginstal versi baru paket ini. Informasi dalam
package.json
tidak akan diperbarui. Saat menggunakan file kunci, semuanya terlihat berbeda.
Jika npm atau benang menemukan file kunci yang sesuai, mereka akan menginstal paket berdasarkan file ini, dan bukan pada
package.json
. Ini sangat berguna, misalnya, ketika menggunakan sistem Continuous Integration (CI) pada platform di mana Anda perlu memastikan pengoperasian kode dan pengujian yang seragam di lingkungan yang karakteristiknya diketahui sebelumnya. Dalam kasus seperti itu, Anda dapat menggunakan perintah atau bendera khusus ketika memanggil manajer paket yang sesuai:
npm ci # , package-lock.json yarn install --frozen-lock-file # , yarn.lock,
Ini sangat berguna jika Anda mengembangkan proyek seperti aplikasi web atau server, karena di lingkungan CI Anda perlu mensimulasikan perilaku pengguna. Akibatnya, jika kami menyertakan file kunci dalam repositori proyek (misalnya, dibuat menggunakan alat git), kami dapat memastikan bahwa setiap pengembang, setiap server, setiap sistem pembangunan kode dan setiap lingkungan CI menggunakan versi yang sama ketergantungan.
Mengapa tidak melakukan hal yang sama ketika menerbitkan perpustakaan atau alat perangkat lunak lain di registri npm? Sebelum menjawab pertanyaan ini, kita perlu berbicara tentang bagaimana proses penerbitan paket bekerja.
Proses Penerbitan Paket
Beberapa pengembang percaya bahwa apa yang diterbitkan dalam npm adalah persis apa yang disimpan dalam repositori git, atau apa yang diubah proyek setelah penyelesaian pekerjaan di dalamnya. Ini sebenarnya tidak demikian. Saat menerbitkan paket, npm mengetahui file mana yang akan diterbitkan dengan mengakses kunci
files
di file
package.json
dan file
.npmignore
. Jika tidak ada yang dapat dideteksi, file
.gitignore
digunakan. Selain itu, beberapa file selalu dipublikasikan, dan beberapa tidak pernah dipublikasikan. Anda dapat mengetahui apa file-file ini di
sini . Sebagai contoh, npm selalu mengabaikan folder
.git
.
Setelah itu, npm mengambil semua file yang sesuai dan
mengemasnya menjadi file
tarball
menggunakan perintah
npm pack
. Jika Anda ingin melihat apa sebenarnya yang dimasukkan ke dalam file seperti itu, Anda dapat menjalankan
npm pack --dry-run
perintah di folder proyek dan melihat daftar bahan di konsol.
Npm pak --dry-run perintah outputFile
tarball
dihasilkan kemudian diunggah ke registri npm. Ketika Anda menjalankan
npm pack --dry-run
Anda dapat memperhatikan fakta bahwa jika ada file
package-lock.json
dalam proyek, itu tidak termasuk dalam file tarball. Ini disebabkan oleh fakta bahwa file ini, sesuai dengan
aturan npm, selalu diabaikan.
Hasilnya adalah jika seseorang menginstal paket orang lain, file
package-lock.json
tidak akan terlibat. Apa yang ada di file ini yang dimiliki oleh pengembang paket tidak akan diperhitungkan saat menginstal paket oleh orang lain.
Ini bisa, kebetulan kebetulan, mengarah ke masalah yang kita bicarakan di awal. Dalam sistem pengembang, kodenya berfungsi dengan baik, dan di sistem lain ia menghasilkan kesalahan. Tetapi kenyataannya adalah bahwa pengembang proyek dan mereka yang menggunakan proyek menggunakan versi paket yang berbeda. Bagaimana cara memperbaikinya?
Penolakan file kunci dan penggunaan teknologi shrinkwrap
Pertama, Anda perlu mencegah dimasukkannya file kunci dalam repositori proyek. Saat menggunakan git, Anda harus memasukkan yang berikut ini dalam file
.gitignore
proyek Anda:
yarn.lock package-lock.json
Dokumentasi benang mengatakan bahwa
yarn.lock
perlu ditambahkan ke repositori bahkan jika itu menyangkut pengembangan perpustakaan yang Anda rencanakan untuk diterbitkan. Tetapi jika Anda ingin Anda dan pengguna perpustakaan Anda bekerja dengan kode yang sama, saya akan merekomendasikan memasukkan
yarn.lock
dalam file
.gitignore
.
Anda dapat menonaktifkan pembuatan otomatis file
package-lock.json
dengan
.npmrc
file
.npmrc
dengan konten berikut ke folder proyek:
package-lock=false
Saat bekerja dengan benang, Anda dapat menggunakan perintah
yarn install --no-lockfile
, yang memungkinkan Anda untuk menonaktifkan pembacaan file
yarn.lock
.
Namun, fakta bahwa kami menyingkirkan file
package-lock.json
tidak berarti bahwa kami tidak dapat menangkap informasi tentang dependensi dan dependensi bersarang. Ada
file lain yang disebut
npm-shrinkwrap.json
.
Secara umum, ini
adalah file yang sama dengan
package-lock.json
, ini dibuat oleh perintah
npm shrinkwrap
. File ini masuk ke registri npm ketika paket diterbitkan.
Untuk mengotomatiskan operasi ini, perintah
npm shrinkwrap
dapat ditambahkan ke bagian deskripsi skrip dari file
package.json
sebagai skrip prabayar. Anda dapat mencapai efek yang sama menggunakan hook komit git. Sebagai hasilnya, Anda dapat yakin bahwa dalam lingkungan pengembangan Anda, dalam sistem CI Anda, dan pengguna proyek Anda menggunakan dependensi yang sama.
Perlu dicatat bahwa teknik ini direkomendasikan untuk digunakan secara bertanggung jawab. Dengan membuat file shrinkwrap, Anda mengkomit versi dependensi tertentu. Di satu sisi, ini berguna untuk memastikan operasi proyek yang stabil, di sisi lain, ini dapat mencegah pengguna memasang tambalan penting, yang, jika tidak, akan dilakukan secara otomatis. Bahkan, npm sangat menyarankan untuk tidak menggunakan file shrinkwrap ketika mengembangkan perpustakaan, membatasi penggunaannya untuk sesuatu seperti sistem CI.
Mencari paket dan informasi ketergantungan
Sayangnya, dengan semua kekayaan informasi tentang manajemen ketergantungan dalam
dokumentasi npm, terkadang sulit untuk menavigasi informasi ini. Jika Anda ingin tahu apa yang sebenarnya diinstal selama instalasi dependensi atau paket sebelum mengirim paket ke npm, Anda dapat, dengan perintah yang berbeda, menggunakan flag
--dry-run
. Penggunaan bendera ini mengarah pada fakta bahwa tim tidak mempengaruhi sistem. Sebagai contoh, perintah
npm install --dry-run
tidak benar-benar menginstal dependensi, dan perintah
npm publish --dry-run
tidak memulai proses penerbitan paket.
Berikut beberapa perintah serupa:
npm ci --dry-run # , package-lock.json npm-shrinkwrap.json npm pack --dry-run # , npm install <dep> --verbose --dry-run #
Ringkasan
Banyak hal yang kita bicarakan di sini bergantung pada spesifikasi melakukan berbagai operasi menggunakan npm. Kita berbicara tentang pengemasan, penerbitan, pemasangan paket, bekerja dengan dependensi. Dan mengingat fakta bahwa npm terus berkembang, kita dapat mengatakan bahwa semua ini dapat berubah di masa depan. Selain itu, kemungkinan aplikasi praktis dari rekomendasi yang diberikan di sini tergantung pada bagaimana pengembang paket merasakan masalah menggunakan berbagai versi dependensi di lingkungan yang berbeda.
Semoga materi ini telah membantu Anda lebih memahami bagaimana ekosistem ketergantungan npm bekerja. Jika Anda ingin mempelajari lebih dalam tentang pertanyaan ini - di
sini Anda dapat membaca tentang perbedaan antara perintah
npm install
npm ci
dan
npm install
.
Di sini Anda dapat menemukan apa yang sebenarnya masuk ke file
package-lock.json
dan
npm-shrinkwrap.json
.
Ini adalah halaman dokumentasi npm tempat Anda dapat mengetahui file proyek mana yang termasuk dan tidak termasuk dalam paket.
Pembaca yang budiman! Apakah Anda menggunakan file npm-shrinkwrap.json di proyek Anda?
