What Is a Lockfile? Reproducible Installs, Explained (package-lock, Cargo.lock and more)

  • VersionDude
  • guides
  • 7 min de leitura

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.

Um lockfile e um arquivo que seu gerenciador de pacotes grava para registrar as versoes exatas de cada dependencia que seu projeto instalou, nao apenas as que voce pediu, mas tambem as dependencias dessas dependencias. Todo o seu proposito e a reprodutibilidade: ele garante que voce, seu colega de equipe e seu servidor de producao instalem todos exatamente o mesmo conjunto de pacotes, byte a byte, em vez do que por acaso for mais recente no momento da instalacao. Se voce ja viu um package-lock.json, yarn.lock ou Cargo.lock e se perguntou para que serve, e para isto.

Para entender por que isso importa, voce precisa olhar o que seu manifesto realmente diz. Um arquivo como package.json geralmente fixa dependencias como faixas de versao, nao versoes exatas, por exemplo ^1.2.3, que sob o Versionamento Semantico significa qualquer lancamento de 1.2.3 ate, mas sem incluir, 2.0.0. Essa flexibilidade e util, mas tem uma desvantagem: instale o projeto hoje e voce pode receber 1.2.4, instale no mes que vem e voce pode receber 1.2.9. Mesmo manifesto, codigo real diferente.

O lockfile fecha essa lacuna. Quando voce instala pela primeira vez, o gerenciador de pacotes resolve todas essas faixas em versoes concretas e as grava no lockfile junto com um hash de integridade para cada pacote. A partir dai, qualquer pessoa que instala le o lockfile e obtem essas versoes exatas, nao a faixa, mas a versao especifica resolvida. O resultado e uma instalacao deterministica e reproduzivel a cada vez, o que elimina toda uma classe de bugs do tipo 'mas funciona na minha maquina'.

Esse hash de integridade cumpre uma segunda tarefa importante. Cada entrada no lockfile registra uma soma de verificacao do conteudo do pacote, de modo que, quando o gerenciador de pacotes baixa uma dependencia, ele pode verificar se os bytes correspondem ao que foi travado. Se um pacote no registro tivesse sido adulterado, o hash nao corresponderia e a instalacao falharia. Numa era de ataques a cadeia de suprimentos, essa verificacao e um beneficio de seguranca discreto, mas real.

Cada ecossistema tem sua propria versao da mesma ideia. Em JavaScript ha package-lock.json (npm), yarn.lock (Yarn) e pnpm-lock.yaml (pnpm); em Rust, Cargo.lock; em Python, poetry.lock e uv.lock; em Ruby, Gemfile.lock; em PHP, composer.lock. O formato do arquivo difere, mas a tarefa e identica: registrar a arvore de dependencias resolvida exata para que possa ser reproduzida exatamente.

Uma pergunta comum e se voce deve commitar o lockfile no controle de versao. Para aplicacoes, sim, voce quer que seus deploys instalem as versoes exatas que voce testou, entao o lockfile pertence ao repositorio. Para bibliotecas, a convencao e diferente: muitos autores de bibliotecas nao commitam um lockfile, porque os projetos que dependem da biblioteca vao resolver e travar suas proprias versoes de qualquer forma.

O lockfile e o manifesto sao uma equipe, nao rivais. O manifesto expressa a intencao com faixas SemVer, 'quero uma 1.x compativel deste pacote', o que mantem voce aberto a atualizacoes seguras. O lockfile registra a realidade, 'esta versao exata e o que realmente usamos', o que mantem as instalacoes reproduziveis. Se voce quiser os detalhes das faixas em si, veja nosso guia de Versionamento Semantico.

Como o lockfile e atualizado depende do comando que voce executa. Uma instalacao comum (como npm install) pode atualizar o lockfile se encontrar versoes mais recentes ainda permitidas pelas suas faixas. Uma instalacao estrita e reproduzivel (como npm ci) ignora as faixas por completo e instala exatamente o que o lockfile diz, falhando se os dois discordarem, o que e justamente o que voce quer em integracao continua e builds de producao.

Alguns habitos praticos mantem os lockfiles sem dor de cabeca. Nao os edite a mao; deixe a ferramenta regenera-los. Quando voce receber um conflito de merge em um lockfile, o que acontece porque dois branches adicionaram dependencias, resolva-o executando a instalacao novamente em vez de editar o arquivo a mao. E sempre commite o lockfile de uma aplicacao, para que a versao que todos constroem seja a versao que voce realmente testou.

Projeto relacionado