Qual é a diferença entre npm-shrinkwrap.json e package-lock.json?

158

Com o lançamento do npm @ 5 , ele escreverá um a package-lock.jsonmenos que npm-shrinkwrap.jsonjá exista.

Instalei o npm @ 5 globalmente via:

npm install npm@5 -g

E agora, se um npm-shrinkwrap.jsonfor encontrado durante:

npm install

um aviso será impresso:

npm WARN read-shrinkwrap This version of npm
is compatible with lockfileVersion@1,
but npm-shrinkwrap.json was generated for lockfileVersion@0.
I'll try to do my best with it!

Então, minha opinião é que eu deveria substituir o papel termo-retrátil pelo package-lock.json.

No entanto, por que existe um novo formato para isso? O que pode package-lock.jsonfazer o que npm-shrinkwrap.jsonnão pode?

k0pernikus
fonte

Respostas:

176

Os arquivos têm exatamente o mesmo conteúdo, mas há algumas diferenças em como o npm lida com eles, descritas no site docs e também em um arquivo doc no repositório npm que começa abordando explicitamente a diferença entre esses dois arquivos :

  • package-lock.jsonnunca é publicado para npm, enquanto npm-shrinkwrapé por padrão
  • package-lock.json arquivos que não estão no pacote de nível superior são ignorados, mas os arquivos shrinkwrap pertencentes às dependências são respeitados
  • npm-shrinkwrap.jsoné compatível com versões anteriores das npm 2, 3 e 4, enquanto package-lock.jsoné reconhecido apenas pela npm 5+

Você pode converter um existente package-lock.jsonem um npm-shrinkwrap.jsonexecutando npm shrinkwrap.

Portanto:

  • Se você não está publicando seu pacote no npm, a escolha entre esses dois arquivos é de pouca importância. Você pode usar package-lock.jsonporque é o padrão e seu nome é mais claro para iniciantes no npm; Como alternativa, convém usar npm-shrinkwrap.jsona compatibilidade com as npm 2-4, se for difícil garantir que todos da sua equipe de desenvolvimento estejam com as npm 5+. (Observe que o npm 5 foi lançado em 25 de maio de 2017; a compatibilidade com versões anteriores se tornará cada vez menos importante à medida que avançarmos a partir dessa data, pois a maioria das pessoas fará o upgrade.)
  • Se você estiver publicando seu pacote no npm, poderá escolher entre:

    1. usando a package-lock.jsonpara registrar exatamente quais versões de dependências você instalou, mas permitindo que as pessoas que instalam seu pacote usem qualquer versão das dependências que seja compatível com os intervalos de versão ditados pelo seu package.json, ou
    2. usando um npm-shrinkwrap.jsonpara garantir que todos que instalam seu pacote obtenham exatamente a mesma versão de todas as dependências


    A visão oficial descrita (muito detalhadamente) nos documentos é que a opção 1 deve ser usada para bibliotecas (presumivelmente para reduzir a quantidade de duplicação de pacotes causada quando muitas dependências de um pacote dependem de versões ligeiramente diferentes da mesma dependência secundária) , mas essa opção 2 pode ser razoável para os executáveis ​​que serão instalados globalmente.

Mark Amery
fonte
2
+1 - você pode esclarecer seu segundo ponto? Qual é a distinção entre esse comportamento e ter um npm-shrinkwrap?
Rhys
2
@ A segunda bala não importa na prática, a menos que você esteja fazendo algo estranho. Basicamente, ele apenas diz que, se uma biblioteca de alguma forma fez publicar um package-lock.json(que não é possível), então se você fosse para instalar essa biblioteca como uma dependência de algum outro pacote, da biblioteca package-lock.jsonseria ignorado pelo NPM. No entanto, se uma biblioteca publica um npm-shrinkwrap.jsone você instala a biblioteca como uma dependência, também instalará como dependências secundárias as versões exatas de todas as dependências especificadas nas bibliotecas npm-shrinkwrap.json.
Mark Amery
Você pode adicionar o que npm ciexiste para garantir a instalação do package-lock.jsoncomo somente leitura. ( npm installTransforma as package-lock.jsoncausando confusão e potenciais erros e não aproveitar o package-lock.jsonper se.)
k0pernikus
@ k0pernikus Eu não acho que haja qualquer diferença entre como npm cialças npm-shrinkwrap.jsone package-lock.json- o que é a sua relevância a esta pergunta sobre a diferença entre os dois arquivos? Além disso, depois de ler: acho que " npm install... não tira proveito do package-lock.json" tem sido falso desde a NPM 5.4 - acredito que npm installagora respeita o seu, a package-lock menos que seja totalmente incompatível com o seu package.json, nesse caso, o último terá precedência. (Mas eu estive fora do mundo JavaScript para um pouco - estou faltando alguma coisa?)
Mark Amery
27

Explicação do NPM Developer :

A idéia é definitivamente que o package-lock.json seja o mais recente e o melhor em tecnologia shrinkwrap, e o npm-shrinkwrap.json seja reservado para aquelas pessoas preciosas por aí que se preocupam muito com suas bibliotecas com um node_modules exato - e para pessoas que desejam que o IC usando o npm @> = 2 instale uma árvore específica sem precisar aumentar a versão do npm.

O novo arquivo de bloqueio ("package-lock.json") compartilha basicamente todo o mesmo código, exatamente o mesmo formato que npm-shrinkwrap (você pode renomeá-los entre si!). Também é algo que a comunidade parece entender: "possui um arquivo de bloqueio" parece clicar muito mais rápido com as pessoas. Por fim, ter um novo arquivo significava que poderíamos ter uma compatibilidade retroativa de risco relativamente baixo com o termo retrátil sem precisar fazer coisas estranhas, como permitir a publicação mencionada na postagem principal.

SeriousM
fonte
18
Ainda não estou claro sobre a diferença. Se npm-shrinkwrapfor exatamente para node_modules .... Presumo que package-lock.jsonestá bloqueando menos que exato? E se sim, o que não npm-shrinkwrapestá bloqueando está bloqueando?
dman
você entendeu errado @dman. package-lock é a nova versão do npm-shrinkwrap. o bloqueio do pacote é desativado (portanto, você deve remover o recurso porque é ativado por padrão), o npm-shrinkwrap é ativado (portanto, você deve ativá-lo porque não está incluído o meu padrão). a razão pela qual eles introduziram o bloqueio de pacotes é que 1. o usuário agora tem uma maneira mais segura de lidar com dependências, porque é ativado por padrão e 2. o nome implica o que ele tem em oposição a "shrinkwrap". O npm-shrinkwrap tinha algumas configurações especiais de comportamento de dependência que o pacote-lock não possui agora. npm-shrinkwrap agora está obsoleto.
SeriousM
10
isso está incorreto. Ao dizer que o pacote-lock é a nova versão do npm-shrinkwrap, você está dizendo que é um substituto. O npm-shrinkwrap não está obsoleto e possui diferenças com o package-lock.json. Além disso, o package-lock.json possui um erro, enquanto o npm-shrinkwrap não ... enfatizando mais, portanto, eles não são o mesmo código.
dman 12/07
Também package-lock.json é intrusivo. Portanto, pode causar facilmente conflitos scm se você chamar "npm i" enquanto o shrinkwrap deve ser gerado explicitamente e não causará conflitos nos servidores ci. Sim, eu posso estar errado aqui.
Norekhov 29/03/19
@dman "O pacote-lock.json tem um erro, enquanto o npm-shrinkwrap não" - não, não tem. Não há indicação disso no problema ao qual você está vinculado; nem sequer menciona npm-shrinkwrap. Como observo na minha resposta, converter um package-lock.jsonpara um npm-shrinkwrap.jsoné literalmente acabado de renomear o arquivo; eles são "o mesmo código".
precisa
12

Eu acho que a idéia era ter --save e shrinkwrap acontecendo por padrão, mas evite possíveis problemas com um shrinkwrap acontecendo onde não era desejado. Então, eles apenas deram um novo nome de arquivo para evitar conflitos. Alguém da npm explicou mais detalhadamente aqui:

https://www.reddit.com/r/javascript/comments/6dgnnq/npm_v500_released_save_by_default_lockfile_better/di3mjuk/

A citação relevante:

O npm publica a maioria dos arquivos no diretório de origem por padrão, e as pessoas publicam shrinkwraps há anos. Não queríamos quebrar a compatibilidade. Com --save e shrinkwrap por padrão, havia um grande risco de acidentalmente entrar e propagar pelo registro e basicamente tornar nula nossa capacidade de atualizar deps e dedupe ...

Então escolhemos um novo nome. E escolhemos um novo nome de repente. O novo arquivo de bloqueio compartilha basicamente todo o mesmo código, exatamente o mesmo formato

Cody Brumfield
fonte