Qual é a diferença entre “npm install” e “npm ci”?


215

Estou trabalhando com integração contínua e descobri o comando npm ci .

Não consigo descobrir quais são as vantagens de usar este comando para o meu fluxo de trabalho.

É mais rápido? Isso torna o teste mais difícil, ok e depois?

Respostas:


327

Nos documentos da npm :

Em resumo, as principais diferenças entre o uso do npm install e do npm ci são:

  • O projeto deve ter um pacote-lock.json ou npm-shrinkwrap.json existente.
  • Se as dependências no bloqueio do pacote não corresponderem às do package.json, o npm ci será encerrado com um erro, em vez de atualizar o bloqueio do pacote.
  • O npm ci pode instalar projetos inteiros por vez: dependências individuais não podem ser adicionadas com este comando.
  • Se um node_modules já estiver presente, ele será removido automaticamente antes que o npm ci inicie sua instalação.
  • Ele nunca gravará no package.json ou em qualquer um dos bloqueios de pacotes: as instalações são essencialmente congeladas.

Essencialmente, npm installpackage.jsonpara criar uma lista de dependências e usa package-lock.jsonpara informar quais versões dessas dependências instalar. Se não houver uma dependência, package-lock.jsonela será adicionada pornpm install .

npm ci(nome de C ontinuous eu ntegração) instala dependências directamente a partir de package-lock.jsone utilizações package.jsonapenas para validar que não existem versões diferentes. Se alguma dependência estiver ausente ou tiver versões incompatíveis, ocorrerá um erro .

Use npm installpara adicionar novas dependências e atualizar dependências em um projeto. Geralmente, você o usaria durante o desenvolvimento depois de extrair alterações que atualizam a lista de dependências, mas pode ser uma boa ideia usar npm cineste caso.

Use npm cise você precisar de uma construção determinística e repetível. Por exemplo, durante a integração contínua, trabalhos automatizados, etc. e ao instalar dependências pela primeira vez, em vez de npm install.

npm install

  • Instala um pacote e todas as suas dependências.
  • As dependências são controladas por npm-shrinkwrap.jsone package-lock.json(nessa ordem).
  • sem argumentos : instala dependências de um módulo local.
  • Pode instalar pacotes globais.
  • Instalará quaisquer dependências ausentes no node_modules.
  • Pode escrever para package.jsonou package-lock.json.
    • Quando usado com um argumento ( npm i packagename), ele pode escrever package.jsonpara adicionar ou atualizar a dependência.
    • quando usado sem argumentos, ( npm i) ele pode escrever para package-lock.jsonbloquear a versão de algumas dependências se elas ainda não estiverem nesse arquivo.

npm ci

  • Requer pelo menos npm v5.7.1 .
  • Requer package-lock.jsonou npm-shrinkwrap.jsonestar presente.
  • Lança um erro se as dependências desses dois arquivos não corresponderem package.json.
  • Remove node_modulese instala todas as dependências uma só vez.
  • Ele nunca escreve para package.jsonou package-lock.json.

Algoritmo

Enquanto npm cigera a árvore de dependência inteira de package-lock.jsonou npm-shrinkwrap.json, npm install atualiza o conteúdo donode_modules uso do seguinte algoritmo ( origem ):

load the existing node_modules tree from disk
clone the tree
fetch the package.json and assorted metadata and add it to the clone
walk the clone and add any missing dependencies
  dependencies will be added as close to the top as is possible
  without breaking any other modules
compare the original tree with the cloned tree and make a list of
actions to take to convert one to the other
execute all of the actions, deepest first
  kinds of actions are install, update, remove and move

1
Eu não sabia que npm installpoderia escrever para package.json. Você sabe o que poderia escrever aqui?
Veve

5
bem, isso pode ser um pouco enganador ... ele será gravado no package.json quando você o usar para instalar, atualizar ou remover dependências. Vou deixar isso mais claro no texto, obrigado!
Lucascaro

Onde esse algoritmo está documentado? Ou seja, qual é a sua fonte?
Yngvar Kristiansen

1
@YngvarKristiansen é na documentação do NPM, adicionou um link para a seção específica para referência
lucascaro

4
npm install packagepoderia modificar tanto package-lock.json e package.json , ao mesmo tempo npm installargumentos whithout só iria modificarpackage-lock.json
knobo

20

npm ciexcluirá qualquer pasta node_modules existente e depende do package-lock.jsonarquivo para instalar a versão específica de cada pacote. É significativamente mais rápido que a instalação npm porque ignora alguns recursos. Sua instalação em estado limpo é excelente para pipelines ci / cd e builds de docker! Você também o usa para instalar tudo de uma vez e não pacotes específicos.


9

A documentação que você vinculou tinha o resumo:

Em resumo, as principais diferenças entre o uso do npm install e do npm ci são:

  • O projeto deve ter um pacote-lock.json ou npm-shrinkwrap.json existente.
  • Se as dependências no bloqueio do pacote não corresponderem às do package.json, o npm ci será encerrado com um erro, em vez de atualizar o bloqueio do pacote.
  • O npm ci pode instalar projetos inteiros por vez: dependências individuais não podem ser adicionadas com este comando.
  • Se um node_modules já estiver presente, ele será removido automaticamente antes que o npm ci inicie sua instalação.
  • Ele nunca gravará no package.json ou em qualquer um dos bloqueios de pacotes: as instalações são essencialmente congeladas.

2

Os comandos são muito semelhantes em funcionalidade, no entanto, a diferença está na abordagem adotada para instalar as dependências especificadas nos arquivos package.jsone package-lock.json.

npm ciexecuta uma instalação limpa de todas as dependências do seu aplicativo, enquanto npm installpode pular algumas instalações se elas já existirem no sistema. Pode ocorrer um problema se a versão já instalada no sistema não for a que você package.jsonpretende instalar, ou seja, a versão instalada for diferente da versão ' necessária versão ' '.

Outras diferenças seriam que npm cinunca tocam seus package*.jsonarquivos. Parará a instalação e mostrará um erro se as versões de dependência não corresponderem no package.jsonepackage-lock.json arquivos .

Você pode ler uma explicação muito melhor dos documentos oficiais aqui .

Além disso, você pode ler sobre bloqueios de pacotes aqui .


1

Vale lembrar que as imagens do docker do nó de luz, como o alpino, não possuem o Python instalado, cuja dependência node-gypé usada pelonpm ci .

Eu acho que é um pouco opinativo que, para ter npm ci funcionando, você precisa instalar o Python como dependência em sua compilação.

Mais informações aqui Docker e npm - gyp ERR! não está tudo bem


0

Enquanto todos os outros responderam às diferenças técnicas, ninguém explica em que situações usar os dois.

Você deve usá-los em diferentes situações.

npm installé ótimo para desenvolvimento e no IC quando você deseja armazenar em cache o node_modulesdiretório. Quando usar isso? Você pode fazer isso se estiver criando um pacote para uso de outras pessoas (você NÃO o inclui node_modulesem um release) . Com relação ao armazenamento em cache, tenha cuidado, se você planeja suportar versões diferentes do Node.jsLembre-se de que node_modulestalvez seja necessário reinstalar devido a diferenças entre os Node.jsrequisitos de tempo de execução. Se você deseja manter uma versão, siga a mais recente LTS.

npm cideve ser usado quando você for testar e liberar um aplicativo de produção (um produto final, não para ser usado por outros pacotes), pois é importante que você tenha a instalação o mais determinista possível, essa instalação levará mais tempo, mas acabará tornando seu aplicativo mais confiável (você inclui node_modulesnessa liberação) . Fique com a LTSversão do Node.js.

Bônus: você pode misturá-los dependendo de quão complexo você deseja torná-lo. Nas ramificações de recursos, gitvocê pode armazenar em cache node_modulespara aumentar a produtividade de suas equipes e, mediante solicitação de mesclagem, as ramificações principais dependem npm cide um resultado determinístico.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.