
What Is a Lockfile? Reproducible Installs, Explained (package-lock, Cargo.lock and more)
- VersionDude
- guides
- 7 min di lettura
A lockfile records the exact resolved version of every dependency so everyone installs the same thing. Why manifests alone are not enough, how integrity hashes add security, and whether to commit it.
Un lockfile e un file che il tuo package manager scrive per registrare le versioni esatte di ogni dipendenza installata dal tuo progetto, non solo quelle che hai richiesto, ma anche le dipendenze di quelle dipendenze. Il suo scopo principale e la riproducibilita: garantisce che tu, il tuo collega e il tuo server di produzione installiate tutti byte per byte lo stesso insieme di pacchetti, invece di qualunque sia la versione piu recente al momento dell'installazione. Se hai mai visto un package-lock.json, yarn.lock o Cargo.lock e ti sei chiesto a cosa serva, ecco la risposta.
Per capire perche e importante, devi guardare cosa dice davvero il tuo manifest. Un file come package.json di solito fissa le dipendenze come intervalli di versione, non come versioni esatte, per esempio ^1.2.3, che secondo il Semantic Versioning significa qualsiasi release da 1.2.3 fino a, ma esclusa, 2.0.0. Quella flessibilita e utile, ma ha uno svantaggio: installa il progetto oggi e potresti ottenere 1.2.4, installalo il mese prossimo e potresti ottenere 1.2.9. Stesso manifest, codice effettivamente diverso.
Il lockfile colma quel divario. Alla prima installazione, il package manager risolve tutti quegli intervalli in versioni concrete e le scrive nel lockfile insieme a un hash di integrita per ogni pacchetto. Da quel momento in poi, chiunque installi legge il lockfile e ottiene quelle versioni esatte, non l'intervallo, ma la versione specifica risolta. Il risultato e un'installazione deterministica e riproducibile ogni volta, ed e cio che elimina un'intera categoria di bug del tipo 'ma sul mio computer funziona'.
Quell'hash di integrita svolge un secondo compito importante. Ogni voce nel lockfile registra un checksum del contenuto del pacchetto, cosi quando il package manager scarica una dipendenza puo verificare che i byte corrispondano a cio che era stato bloccato. Se un pacchetto nel registry venisse manomesso, l'hash non corrisponderebbe e l'installazione fallirebbe. In un'epoca di attacchi alla catena di fornitura, quella verifica e un vantaggio di sicurezza silenzioso ma concreto.
Ogni ecosistema ha la propria versione della stessa idea. In JavaScript ci sono package-lock.json (npm), yarn.lock (Yarn) e pnpm-lock.yaml (pnpm); in Rust, Cargo.lock; in Python, poetry.lock e uv.lock; in Ruby, Gemfile.lock; in PHP, composer.lock. Il formato del file cambia, ma il compito e identico: registrare l'albero delle dipendenze risolto in modo esatto affinche possa essere riprodotto esattamente.
Una domanda comune e se si debba fare il commit del lockfile nel controllo di versione. Per le applicazioni, si: vuoi che i tuoi deployment installino le versioni esatte che hai testato, quindi il lockfile appartiene al repository. Per le librerie la convenzione e diversa: molti autori di librerie non fanno il commit di un lockfile, perche i progetti che dipendono dalla libreria risolveranno e bloccheranno comunque le proprie versioni.
Il lockfile e il manifest sono una squadra, non rivali. Il manifest esprime l'intento con gli intervalli SemVer, 'voglio una 1.x compatibile di questo pacchetto', il che ti mantiene aperto ad aggiornamenti sicuri. Il lockfile registra la realta, 'questa versione esatta e cio che usiamo davvero', il che mantiene le installazioni riproducibili. Se vuoi i dettagli sugli intervalli stessi, consulta la nostra guida al Semantic Versioning.
Il modo in cui il lockfile si aggiorna dipende dal comando che esegui. Un'installazione semplice (come npm install) puo aggiornare il lockfile se trova versioni piu recenti ancora consentite dai tuoi intervalli. Un'installazione rigorosa e riproducibile (come npm ci) ignora completamente gli intervalli e installa esattamente cio che dice il lockfile, fallendo se i due non concordano, il che e cio che vuoi nella continuous integration e nelle build di produzione.
Alcune abitudini pratiche rendono i lockfile indolori. Non modificarli a mano; lascia che sia lo strumento a rigenerarli. Quando ottieni un conflitto di merge in un lockfile, cosa che accade perche due branch hanno aggiunto dipendenze, risolvilo rieseguendo l'installazione invece di modificare il file a mano. E fai sempre il commit del lockfile per un'applicazione, cosi che la versione che tutti costruiscono sia la versione che hai davvero testato.


