Qual é o papel do package-lock.json?

290

npm @ 5 foi publicado, ele possui um novo arquivo package-lock.json (after npm install) que me confunde. Eu quero saber qual é o efeito desse arquivo?

SecretCastle
fonte

Respostas:

289

Ele armazena uma árvore de dependência exata e com versão, em vez de usar versão com estrela, como o próprio package.json (por exemplo, 1.0. *). Isso significa que você pode garantir as dependências para outros desenvolvedores ou lançamentos de produtos, etc. Ele também possui um mecanismo para bloquear a árvore, mas geralmente será regenerado se o package.json mudar.

Desde os docs NPM :

O package-lock.json é gerado automaticamente para qualquer operação em que o npm modifique a árvore node_modules ou o package.json. Ele descreve a árvore exata que foi gerada, de forma que as instalações subseqüentes possam gerar árvores idênticas, independentemente das atualizações intermediárias de dependência.

Este arquivo deve ser confirmado nos repositórios de origem e serve a vários propósitos:

Descreva uma única representação de uma árvore de dependência, de modo que colegas de equipe, implantações e integração contínua garantam a instalação exatamente das mesmas dependências.

Forneça um recurso para os usuários "viajarem no tempo" para estados anteriores de node_modules sem precisar confirmar o próprio diretório.

Para facilitar uma maior visibilidade das alterações nas árvores por meio de diferenças de controle de fonte legíveis.

E otimize o processo de instalação, permitindo que o npm pule as resoluções repetidas de metadados para pacotes instalados anteriormente ".

Editar

Para responder à pergunta de jrahhali abaixo, basta usar o package.json com os números de versão exatos. Lembre-se de que seu package.json contém apenas suas dependências diretas, não as dependências de suas dependências (às vezes chamadas de dependências aninhadas). Isso significa que com o package.json padrão, você não pode controlar as versões dessas dependências aninhadas, referenciá-las diretamente ou como dependências de pares não ajudarão, pois você também não controla a tolerância de versão que suas dependências diretas definem para essas dependências aninhadas .

Mesmo se você bloquear as versões de suas dependências diretas, não poderá garantir 100% que sua árvore de dependência completa será idêntica todas as vezes. Em segundo lugar, convém permitir alterações sem interrupção (com base no controle de versão semântico) de suas dependências diretas, o que oferece um controle ainda menor das dependências aninhadas e, novamente, você não pode garantir que suas dependências diretas não quebrem as regras de controle de versão semânticas em algum momento si mesmos.

A solução para tudo isso é o arquivo de bloqueio que, conforme descrito acima, bloqueia as versões da árvore de dependência completa. Isso permite que você garanta sua árvore de dependência para outros desenvolvedores ou para liberações, enquanto ainda permite testar novas versões de dependência (direta ou indireta) usando o package.json padrão.

NB. O jink shrink wrap anterior fez praticamente a mesma coisa, mas o arquivo de bloqueio o renomeia para que sua função seja mais clara. Se já houver um arquivo de quebra de contração no projeto, ele será usado em vez de qualquer arquivo de bloqueio.

Matt
fonte
78
Se a obtenção de uma versão exata das dependências é tão procurada, por que não aplicar a especificação exata da versão no package.json e renunciar a um arquivo package-lock.json?
precisa saber é o seguinte
15
@jrahhali - alterei minha resposta com base em sua pergunta.
Matt
1
Como essa árvore de dependência do pacakge.json.lock é aplicada a outros desenvolvedores? Automaticamente?
Stevek
40
Observe que esta resposta não está mais correta ! O package-lock.jsonarquivo está sendo atualizado toda vez que você chama o npm install desde o NPM 5.1. (alteração no github.com/npm/npm/issues/16866 , exemplo em github.com/npm/npm/issues/17979 ) Portanto, não pode mais ser usado para definir as mesmas versões para todos os desenvolvedores , a menos que você especifique versões exatas como em 1.2.3vez de 1.2.*no seu package.jsonarquivo.
Christian
5
Você deve adicionar uma referência a npm cicomo npm installatualizará o package-lock.json, enquanto ci usa seu conteúdo. Somente com npm civocê obterá versões robustas e repetíveis.
k0pernikus
34

É uma melhoria muito importante para o npm: garanta exatamente a mesma versão de cada pacote .

Como garantir que seu projeto seja construído com os mesmos pacotes em ambientes diferentes em um momento diferente? Digamos, você pode usar^1.2.3 suas package.jsonou algumas de suas dependências dessa maneira, mas como você pode garantir que cada vez npm installescolha a mesma versão em sua máquina de desenvolvimento e no servidor de compilação? O package-lock.json garantirá isso.

npm install irá gerar novamente o arquivo de bloqueio, quando estiver no servidor de compilação ou no servidor de implantação, faça npm ci (que lerá o arquivo de bloqueio e instalará toda a árvore de pacotes)

Xin
fonte
9
Observe que isso está meio desatualizado agora. No 5.1.0 em diante, "npm install" não lê o package-lock.jsonarquivo. Apenas instala package.jsoncomo antes. Para usar o package-lock.jsonarquivo, você deve usar o novo comando "npm ci", que instalará as versões exatas listadas em package-lock.jsonvez dos intervalos de versões fornecidos em package.json.
Venryx
5
Receio que Venryx esteja incorreto. npm install se ler a partir package-lock.json. Para reproduzir, faça o seguinte. usando este package.json, execute npm install{... "devDependencies": {"sinon": "7.2.2"}} Agora copie / cole package.jsone package-lock.jsonem um novo diretório. Mude package.jsonpara: "sinon": "^ 7.2.2" run npm install. O npm lê o pacote-lock.json e instala o 7.2.2 em vez do 7.3.0. Sem o package-lock.json, o 7.3.0 seria instalado.
zumafra 23/03/19
2
E não apenas isso, mas se você quiser fazer algo como adicionar o cursor ^ a package-lock.json, a única maneira razoável de fazer isso é excluí package-lock.json-lo e regenerá-lo usando npm install. (Você não deseja editar manualmente package-lock.json). Alterar o valor da propriedade "version" (próximo à parte superior) de package.jsonmudará o mesmo para package-lock.jsonon npm install, mas adicionar um sinal de intercalação a uma dependência não fará o mesmo package-lock.json.
Zumafra 23/03/19
1
Pense package.jsoncomo algo que você pode modificar manualmente e package-lock.jsoncomo algo que você nunca toca manualmente. Você sempre controla os dois arquivos, especialmente package-lock.json. Abra os dois arquivos, edite manualmente o nome do projeto package.json, execute npm installe observe como o nome do projeto é alterado package-lock.json. licenseparece não estar gravado package-lock.json.
zumafra
2
@zumafra arquivo de pacote-lock.json será utilizado ao fazer npm ci, npm installsó vai usar package.json, mesmo que o arquivo de bloqueio é fornecido
Xin
13

package-lock.json é gravado quando um valor numérico em uma propriedade como a propriedade "version" ou uma propriedade de dependência é alterada em package.json .

Se esses valores numéricos em package.jsonepackage-lock.json correspondentes package-lock.jsonforem lidos.

Se esses valores numéricos package.jsone package-lock.jsonnão corresponderem,package-lock.json eles serão gravados com esses novos valores e novos modificadores, como o cursor e o til, se estiverem presentes. Mas é o numeral que está provocando a mudança para package-lock.json.

Para entender o que quero dizer, faça o seguinte. Usando package.jsonsem package-lock.json, execute npm installcom:

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "7.2.2"
  }
}

package-lock.json agora terá:

"sinon": {
  "version": "7.2.2",

Agora copie / cole os dois arquivos em um novo diretório. Mude package.jsonpara (apenas adicionando circunflexo):

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "^7.2.2"
  }
}

correr npm install. Se não houvesse package-lock.jsonarquivo, [email protected] seria instalado. npm installestá lendo de package-lock.json e instalando 7.2.2.

Agora mude package.jsonpara:

{
  "name": "test",
  "version": "1.0.0",
  ...
  "devDependencies": {
    "sinon": "^7.3.0"
  }
}

correr npm install. package-lock.jsonfoi gravado e agora mostrará:

"sinon": {
  "version": "^7.3.0",
zumafra
fonte
7

Uma coisa importante a mencionar também é a melhoria de segurança que acompanha o arquivo de bloqueio de pacote. Como ele mantém todos os hashes dos pacotes se alguém violar o registro público do npm e alterar o código-fonte de um pacote sem alterar a versão do pacote, ele será detectado pelo arquivo de bloqueio de pacotes.

nflaig
fonte
4

O package-lock.json é gerado automaticamente para qualquer operação em que o npm modifique a árvore node_modules ou o package.json. Ele descreve a árvore exata que foi gerada, de forma que as instalações subseqüentes possam gerar árvores idênticas, independentemente das atualizações intermediárias de dependência.

Ele descreve uma representação única de uma árvore de dependência, de modo que colegas de equipe, implantações e integração contínua garantam a instalação exatamente das mesmas dependências. Ele contém as seguintes propriedades.

    {
"name": "mobileapp",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@angular-devkit/architect": {
  "version": "0.11.4",
  "resolved": "https://registry.npmjs.org/@angular- devkit/architect/-/architect-0.11.4.tgz",
  "integrity": "sha512-2zi6S9tPlk52vyqNFg==",
  "dev": true,
  "requires": {
    "@angular-devkit/core": "7.1.4",
    "rxjs": "6.3.3"
  }
},

}

DIBYA RANJAN TRIPATHY
fonte
2

Este arquivo é criado e usado automaticamente pelo npm para acompanhar as instalações do seu pacote e gerenciar melhor o estado e o histórico das dependências do seu projeto. Você não deve alterar o conteúdo deste arquivo.

user_ahmed
fonte
1
então o que acontece se eu entrar em conflito com este arquivo?
Oliver Watkins
0

package-lock.json: contém os detalhes exatos da versão atualmente instalados para o seu aplicativo.

Shubham Srivastava
fonte
1
Olá e bem vindo. Esta pergunta já foi respondida. Você deve verificar se a pergunta foi marcada como respondida, para ver se alguma das respostas tem um cheque verde na frente.
Néstor