Dipendenze
Che cos'è un lockfile?
Un lockfile registra la versione esatta di ogni dipendenza risolta da un package manager, diretta e transitiva, così l'installazione successiva ottiene lo stesso albero. È il miglior piano che Lei abbia per una build. Non è una registrazione di ciò che la build ha effettivamente usato.
Aggiornato il
Che cosa registra un lockfile
Il Suo manifest, come package.json o pyproject.toml, elenca i pacchetti da cui dipende
e gli intervalli di versione che accetta. Il package manager trasforma quegli intervalli in versioni esatte per l'intero albero,
comprese le dipendenze transitive, e scrive il risultato nel lockfile.
La documentazione di npm dice che package-lock.json descrive "l'albero esatto che è stato generato,
in modo che le installazioni successive possano generare alberi identici".
Una singola voce in package-lock.json si presenta così:
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-...",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
}
}
- version è la versione esatta scelta.
- resolved è il punto da cui è stata scaricata: l'URL di un tarball del registry, oppure un URL git con un commit.
- integrity è un hash Subresource Integrity del tarball, così un download manomesso fallisce.
- dependencies sono le sue dipendenze, ed è così che si ricompone l'albero, o grafo delle dipendenze.
Lockfile per package manager
| Package manager | Lockfile | Installare senza modificarlo |
|---|---|---|
| npm | package-lock.json | npm ci |
| Yarn (Berry) | yarn.lock | yarn install --immutable |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile |
| uv | uv.lock | uv sync --locked |
| Poetry | poetry.lock | poetry install |
| Cargo | Cargo.lock | cargo build --locked |
| Bundler | Gemfile.lock | bundle config set frozen true |
| Go modules | Versioni in go.mod e checksum in go.sum |
Per impostazione predefinita i comandi di build non aggiornano go.mod |
Con il solo pip, il sostituto più comune è un requirements.txt con versioni esatte. Fissa ciò che elenca,
ma tutto ciò che tralascia viene risolto di nuovo a ogni installazione.
Usi installazioni frozen in CI
Un lockfile serve solo se la build installa a partire da esso. Un semplice npm install può aggiornare
package-lock.json quando non corrisponde più a package.json, così la build risolve in silenzio un
nuovo albero. npm ci è pensato per gli ambienti automatizzati:
- Richiede un
package-lock.jsono unnpm-shrinkwrap.json. - Se il lockfile e
package.jsonnon coincidono, termina con un errore invece di aggiornare il lock. - Rimuove prima qualsiasi
node_modulesesistente. - Non scrive mai in
package.jsonné nel lockfile.
Gli altri comandi nella tabella qui sopra svolgono lo stesso compito per i rispettivi package manager.
Applicazioni e librerie
Esegua il commit del lockfile per le applicazioni e per tutto ciò che distribuisce. Per le librerie, blocca solo il Suo sviluppo
e la Sua CI: npm non pubblica mai package-lock.json e lo ignora ovunque tranne che nel progetto radice. Le
applicazioni che installano la Sua libreria ne risolvono le dipendenze da sole, entro i Suoi intervalli di versione. L'unica
eccezione di npm è npm-shrinkwrap.json, che viene pubblicato e ha la precedenza, e che la maggior parte
delle librerie non dovrebbe usare.
Perché un lockfile non è un registro di ciò che è stato distribuito
Un lockfile è il piano di un package manager in un progetto. La build che ha prodotto la Sua release ha fatto più che seguire quel piano:
- Può non averlo usato. Un'installazione non frozen, un lockfile mancante o un secondo lockfile in un monorepo significano che l'albero è stato risolto in modo diverso dal file che Lei sta guardando.
- Cache. I pacchetti ripristinati da una cache CI vengono installati senza essere scaricati, e una cache ripristinata da una chiave parziale può essere precedente al lockfile attuale. Veda che cosa nasconde la cache di GitHub Actions.
- Strumenti di build. Setup action, compilatori, linter e generatori di codice arrivano attraverso altri canali, con i propri alberi di dipendenze.
-
Download e script di installazione. Un
curlin uno step di build o lo script di installazione di un pacchetto scaricano codice che nessun lockfile elenca. - Immagini base. Una build di container scarica immagini e pacchetti del sistema operativo che stanno fuori da ogni lockfile di linguaggio.
Gli hash di integrità non aiutano in nessuno di questi casi. Dimostrano che i pacchetti nel lockfile non sono stati manomessi; non dicono nulla di ciò che la build ha scaricato al di fuori di esso. Gli strumenti SCA che trasformano un lockfile in una SBOM ereditano gli stessi punti ciechi.
Registri la build, mantenga il lockfile
Continui a eseguire il commit dei lockfile e a installare da essi con installazioni frozen. Rendono le build ripetibili. Per la registrazione di ciò che contiene una release, CRACI registra la build stessa: un proxy che riconosce i pacchetti sui suoi runner GitHub Actions registra ogni pacchetto scaricato da ciascun job, compresi i pacchetti ripristinati dalle cache CI, e la SBOM di ogni job dichiara la propria completezza. Quella registrazione offre una visione più completa delle dipendenze in uso rispetto alla scansione del lockfile. Veda le SBOM in fase di build, oppure prenoti una demo per confrontare le due su una delle Sue build.
Lockfile: domande frequenti
Che cos'è un lockfile?
Un lockfile è un file che un package manager scrive per registrare la versione esatta di ogni dipendenza risolta, diretta e transitiva, insieme alla sua provenienza e a un checksum. Le installazioni successive lo leggono per riprodurre lo stesso albero invece di risolvere di nuovo gli intervalli di versione.
Devo eseguire il commit del lockfile?
Sì, per le applicazioni e per tutto ciò che distribuisce. Senza un lockfile nel repository, ogni nuova installazione risolve di nuovo gli intervalli di versione e può acquisire nuove versioni transitive. Ne esegua il commit e installi da esso con un'installazione frozen come npm ci in CI.
Un lockfile fissa le dipendenze transitive?
Sì. È il suo compito principale. Il manifest elenca solo le Sue dipendenze dirette e gli intervalli consentiti; il lockfile registra la versione esatta scelta per ogni pacchetto dell'albero.
I lockfile si applicano alle librerie che pubblico?
Non per i Suoi utenti. npm, ad esempio, non pubblica mai package-lock.json e lo ignora ovunque tranne che nel progetto radice. Le applicazioni che installano la Sua libreria ne risolvono le dipendenze da sole, entro gli intervalli consentiti dal Suo package.json.
A che cosa serve il campo integrity in package-lock.json?
Contiene un hash Subresource Integrity, di solito sha512, del tarball del pacchetto. npm vi confronta il pacchetto scaricato, quindi l'installazione di un tarball manomesso per una versione bloccata fallisce. Protegge i pacchetti nel lockfile, non ciò che la build scarica al di fuori di esso.
Un lockfile è la stessa cosa di una SBOM?
No. Un lockfile è un input: il piano che un package manager segue per un progetto. Una SBOM è un inventario di una release. Gli strumenti SCA trasformano spesso un lockfile in una SBOM, il che funziona quando la build ha installato esattamente il lockfile e nient'altro.
Confronti il Suo lockfile con la Sua build
Esegua un workflow su CRACI e metta la SBOM registrata dei pacchetti scaricati accanto a ciò che dice il Suo lockfile.
Prenota una demo