File requirements.txt hasil pip freeze aman untuk aplikasi, tetapi file itu membeku sekali dan tidak punya cerita asal-usul: kita tidak tahu baris mana direct dependency, siapa yang menuntut apa, dan kapan pembekuan itu perlu diulang. Masalah sebenarnya lebih dalam — deklarasi rentang seperti requests>=2.31 membiarkan pip memilih versi bebas setiap kali instalasi terjadi. Lockfile menyelesaikan keduanya: file terpisah yang merekam hasil resolusi pohon dependency secara eksak dan dapat dibangun ulang secara sadar.
Masalah Reproducibility #
Perhatikan skenario berikut. Metadata aplikasi kita menyatakan requests>=2.31, dan requests sendiri menyatakan urllib3>=1.21.1. Tiga bulan terjadi dua instalasi:
- Budi, bulan Januari: pip memilih
requests 2.31.0danurllib3 2.2.1— versi terbaru saat itu. - Siti, bulan Maret: pip memilih
requests 2.32.5danurllib3 2.5.0— versi terbaru kini.
Kedua instalasi sah menurut deklarasi, tetapi hasil akhirnya berbeda. Bug yang muncul di mesin Siti tidak muncul di mesin Budi, dan tidak ada yang bisa menjelaskan kenapa. Semakin dalam pohon dependency (transitive dari transitive), semakin banyak titik yang bisa bergeser diam-diam.
Apa Itu Lockfile #
Lockfile adalah berkas hasil membekukan resolusi pohon dependency: satu perintah membaca deklarasi dependency kita, menelusuri seluruh pohon hingga daun, memilih satu versi eksak untuk setiap node, lalu mencatat semuanya. Isi khasnya:
- seluruh package, direct maupun transitive, beserta versi eksak;
- hash berkas arsipnya, sehingga unduhan bisa diverifikasi tidak dirusak;
- referensi ke deklarasi asal (file
.inataupyproject.toml).
Instalasi dari lockfile tidak menjalankan resolusi apa pun — pip (atau tool terkait) tinggal mengunduh persis apa yang tertulis. Dua pengguna yang memakai lockfile yang sama mendapat environment yang identik, dan perbedaan perilaku antar-mesin hilang sebagai kelas bug.
pip-tools: Lockfile untuk pip #
Tool klasik di dunia pip adalah pip-tools, pasangan pip-compile dan pip-sync. Deklarasi direct dependency ditulis di requirements.in; pip-compile menghasilkan lockfile requirements.txt:
pip-compile requirements.inOutput yang Dihasilkan (ilustratif — hasil sesungguhnya bergantung pada versi terbaru saat perintah dijalankan):
#
# This file is autogenerated by pip-compile via pip-tools 7.4.1
#
build==1.6.1
# via -r requirements.in
packaging==26.3
# via build
pyproject-hooks==1.3.3
# via buildYang membuat format ini istimewa adalah komentar # via: setiap package tertelusur asal-usulnya — packaging hadir via build, build hadir karena kita menuliskannya sendiri. Pertanyaan “bolehkah baris ini dihapus?” kini punya jawaban tertulis. Menjalankan pip-compile ulang memperbarui pembekuan; pip-sync memasang persis isi lockfile sekaligus menghapus package yang tidak tercatat.
Perbandingan Tool Lockfile #
pip-tools hanyalah satu dari beberapa generasi tool. Tabel berikut memetakan yang paling umum dijumpai:
| Tool | File deklarasi | Lockfile | Perintah sinkronisasi |
|---|---|---|---|
| pip-tools | requirements.in | requirements.txt | pip-sync |
| Poetry | pyproject.toml | poetry.lock | poetry install |
| uv | pyproject.toml | uv.lock | uv sync |
| PDM | pyproject.toml | pdm.lock | pdm install |
Poetry dan uv juga mengelola venv sekaligus, jadi satu tool menaungi siklus penuh: buat environment, deklarasikan dependency di pyproject.toml sesuai Chapter pyproject.toml, kunci di lockfile, pasang dengan satu perintah. uv dikenal karena kecepatannya; pilihan tool kurang penting dibanding disiplin memakai lockfile itu sendiri.
Lockfile Masuk Version Control #
Untuk proyek aplikasi, lockfile selalu di-commit bersama kodenya:
- rekan tim dan server CI memasang dari lockfile, mendapat environment identik;
- upgrade dependency jadi keputusan eksplisit — satu commit yang menjalankan ulang
pip-compile/uv lockdan terlihat di code review; - saat ada regresi setelah upgrade, lockfile lama tinggal dipulihkan dari history Git untuk mengembalikan environment.