Cli: [BUG] npm ci instala uma dependência opcional que visa um sistema operacional diferente do sistema operacional host

Criado em 5 dez. 2019  ·  32Comentários  ·  Fonte: npm/cli

O que? Por que

O npm ci parece instalar uma dependência opcional para o sistema operacional linux ao executar em um mac e parece instalar a dependência opcional para mac ao executar em linux.

Quando

$ npm init -y; npm i [email protected]; npm ls; npm ci; npm ls
clique para ver a saída do comando acima
 Escreveu em /private/tmp/d/package.json:

 {
 "nome": "d",
 "versão": "1.0.0",
 "descrição": "",
 "main": "index.js",
 "scripts": {
 "test": "echo \" Erro: nenhum teste especificado \ "&& exit 1"
 },
 "palavras-chave": [],
 "autor": "",
 "licença": "ISC"
 }



 > [email protected] postinstall / private / tmp / d / node_modules / oax
 > node ./postinstall.js

 O aviso npm criou um arquivo de bloqueio como pacote-lock.json. Você deve enviar este arquivo.
 npm WARN [email protected] Sem descrição
 npm WARN [email protected] Nenhum campo de repositório.
 npm WARN opcional SKIPPING DEPENDÊNCIA OPCIONAL: [email protected] (node_modules / oax / node_modules / oax-windows-64):
 npm AVISO notsup IGNORANDO DEPENDÊNCIA OPCIONAL: plataforma não suportada para [email protected]: queria {"os": "win32", "arch": "x64"} (atual: {"os": "darwin", "arch": "x64"})
 npm WARN opcional SKIPPING DEPENDÊNCIA OPCIONAL: [email protected] (node_modules / oax / node_modules / oax-linux-64):
 npm AVISO notsup PULAR DEPENDÊNCIA OPCIONAL: Plataforma não suportada para [email protected]: queria {"os": "linux", "arch": "x64"} (atual: {"os": "darwin", "arch": "x64"})

 + [email protected]
 adicionou 2 pacotes e auditou 4 pacotes em 1.1s
 encontrou 0 vulnerabilidades

 [email protected] / private / tmp / d
 └─┬ [email protected]
 ├── [email protected]
 ├── DEPENDÊNCIA OPCIONAL UNMET [email protected]
 └── DEPENDÊNCIA OPCIONAL DESCONECTADA [email protected]

 npm WARN prepare removendo node_modules / antes da instalação

 > [email protected] postinstall / private / tmp / d / node_modules / oax
 > node ./postinstall.js

 adicionou 3 pacotes em 0.722s
 [email protected] / private / tmp / d
 └─┬ [email protected]
 ├── [email protected]
 ├── [email protected]
 └── DEPENDÊNCIA OPCIONAL DESCONECTADA [email protected]

Onde

  • n / D

Quão

Comportamento Atual

Atualmente, parece que o npm ci está quebrado para dependências opcionais que usam os campos os e arch de package.json

Passos para reproduzir

$ npm init -y; npm i [email protected]; npm ls; npm ci; npm ls

Você deve ver que npm i funciona corretamente e instala uma única dependência opcional para oax.
Você também deve ver que npm ci funciona incorretamente e instala duas das dependências opcionais para oax, isso nunca deve acontecer, pois cada dependência opcional tem como alvo um sistema operacional e arquitetura diferente, deve ser impossível ter mais de um dos as dependências opcionais instaladas.

Comportamento esperado

deve instalar oax-darwin quando executado em darwin e deve instalar oax-linux quando executado em linux

Quem

  • n / D

Referências

  • n / D
Bug

Comentários muito úteis

Estou surpreso que isso não esteja sendo tratado como um bug mais importante do que é. Isso faz com que não possamos usar "npm ci" em nossos servidores de compilação no Windows. Isso é um grande negócio.

Todos 32 comentários

Eu tive o mesmo problema com o fsevents no Windows, ao instalar dois pacotes que dependem de versões diferentes do fsevents.

npm install chokidar --save

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ [email protected]
added 14 packages from 17 contributors and audited 19 packages in 1.668s
found 0 vulnerabilities

npm install webpack --save-dev

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\watchpack\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ [email protected]
added 327 packages from 195 contributors and audited 4246 packages in 16.581s

O último webpack depende do watchpack que depende de um [email protected] mais [email protected] antigo

Enquanto chokidar mais recente depende de [email protected]

Mas a instalação do npm ignorou corretamente as duas versões do fsevents, pois são incompatíveis com o sistema operacional.

Contudo:

 npm ci
npm WARN prepare removing existing node_modules/ before installation

> [email protected] install K:\SWS\test\node_modules\watchpack\node_modules\fsevents
> node-gyp rebuild


K:\SWS\test\node_modules\watchpack\node_modules\fsevents>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild )  else (node "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" rebuild )
Traceback (most recent call last):
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\gyp_main.py", line 50, in <module>
    sys.exit(gyp.script_main())
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 554, in script_main
    return main(sys.argv[1:])
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 547, in main
    return gyp_main(args)
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 532, in gyp_main
    generator.GenerateOutput(flat_list, targets, data, params)
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 2033, in GenerateOutput
    root_entries = _GatherSolutionFolders(
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 1791, in _GatherSolutionFolders
    return _DictsToFolders('', root, flat)
  File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 1744, in _DictsToFolders
    for folder, contents in bucket.items():
AttributeError: 'MSVSProject' object has no attribute 'items'
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\configure.js:351:16)
gyp ERR! stack     at ChildProcess.emit (events.js:210:5)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Windows_NT 10.0.17134
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd K:\SWS\test\node_modules\watchpack\node_modules\fsevents
gyp ERR! node -v v12.14.0
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok
added 275 packages in 9.344s

E se eu olhar em node_modules, fsevents está lá e não deveria estar.
Além disso, npm ci --no-optional não funciona, isso é relatado aqui: https://github.com/npm/cli/issues/637

Estou usando a instalação do Nó 12 LTS, npm -v => 6.13.4

Se npm ci --no-optional funciona pode depender de fatores adicionais. Consulte https://github.com/npm/cli/issues/637#issuecomment -570813804

Portanto, embora npm ci falhe em meu ambiente, npm ci --no-optional funciona. Meu ambiente:

  • Windows 10
  • Nodejs 12.13.1
  • npm 6.13.4

Depois de atualizar para o nó mais recente e o npm têm o mesmo problema .. todos os projetos onde é fsevent falham ao instalar com npm ci , porque ele está construindo fsevents

  • Windows 10 Pro 1909
  • nó 12.14.1
  • npm 6.13.6

Depois de atualizar para o nó mais recente e o npm têm o mesmo problema .. todos os projetos onde é fsevent falham ao instalar com npm ci , porque ele está construindo fsevents

* Windows 10 Pro 1909

* node 12.14.1

* npm 6.13.6

@padinko Você também tentou a variante com a sinalização adicional --no-optional , ou seja, npm ci --no-optional ? Alguma diferença?

Depois de atualizar para o nó mais recente e o npm têm o mesmo problema .. todos os projetos onde é fsevent falham ao instalar com npm ci , porque ele está construindo fsevents

* Windows 10 Pro 1909

* node 12.14.1

* npm 6.13.6

@padinko Você também tentou a variante com a sinalização adicional --no-optional , ou seja, npm ci --no-optional ? Alguma diferença?

npm ci falham com estes pacotes:

\node_modules\watchpack\node_modules\fsevents
\node_modules\webpack-dev-server\node_modules\fsevents
\node_modules\jest-haste-map\node_modules\fsevents

npm ci --no-optional tem apenas 2 deles:

\node_modules\webpack-dev-server\node_modules\fsevents
\node_modules\jest-haste-map\node_modules\fsevents

então aí está a diferença, mas ainda compilando fsevents

@paulmillr @pipobscure Meu problema (# 658) era uma duplicata deste tíquete. Acompanhe este para se manter atualizado.

Posso confirmar esse bug também no Ubuntu. npm ci instala fsevents que deve ser instalado apenas no MacOS

@mikemimik ou @isaacs , você tem alguma fsevents mudou algo, porque agora este é um problema maior. Mas o problema subjacente ainda é causado pelo NPM e deve ser resolvido aqui.

Parece que a mudança relevante é que fsevents começou a usar node-pre-gyp para extrair um binário pré-compilado, ao invés de construí-lo no local, resultando em um script postinstall que sai sem um erro em todas as plataformas. Uma vez que npm ci apenas tenta fazer o layout do arquivo de bloqueio sem verificar se ele suporta a plataforma, e apenas remove dependências opcionais cujos scripts de instalação falham, resulta na instalação deste dep.

O npm v7 não terá esse problema. (Estou trabalhando no código que fará isso agora.) Não verifiquei o quão envolvido seria corrigir esse problema para o npm v6, mas há uma boa chance de acabar sendo apenas "upgrade para v7 para a correção ". Nesse ínterim, recomendo usar npm install vez de npm ci se isso estiver afetando você.

Sim, fsevents mudou sua tática. Mas é realmente o contrário. Eles costumavam ter binários pré-compilados. A instalação no Windows resultaria em 404 e ignoraria. Agora ele tenta construir e, em seguida, interrompe a construção. Porque a construção não deve nem começar. Independentemente disso: npm ci foi projetado para ambientes de CI. Como devemos usar npm i vez disso? Queremos verificações estritas de bloqueio de pacote em CI.

Além disso: npm@7 pousaria no nó 14, a tempo antes de ser LTS? Estou correto em supor que estamos presos com npm i ou um bloqueio de versão por um ano quando estamos no caminho do LTS?

Desculpe por mudar de tática em você. No entanto, perdemos o acesso ao S3 originalmente usado e ele estava se tornando um problema de segurança cada vez mais sério. É por isso que voltamos a construir conforme necessário. Especialmente considerando que v2.x baseado em NAPI não precisa ser construído para o nó v8.x +

Agora ele tenta construir e, em seguida, interrompe a construção. Porque a construção não deve nem começar.

Oh, isso é estranho. Eu esperaria que npm ci lidasse com uma falha de compilação de um dep opcional como um evento do tipo de aviso não fatal e apenas removesse o dep ofensivo

Independentemente disso: o npm ci foi projetado para ambientes de CI. Por que devemos usar o npm i em vez disso? Queremos verificações estritas de bloqueio de pacote em CI.

Boa pergunta.

"Projetado para ambientes de CI" nem sempre significa "melhor para este ambiente de CI específico, para esta aplicação específica".

Nesse caso, existem dois problemas que o npm ci está enfrentando.

  • Ele não está lidando adequadamente com falhas de construção para dependências opcionais.
  • Não é capaz de pré-filtrar dependências com base nas restrições de os / cpu, porque _apenas_ olha para o pacote-lock.json, onde essa informação não é rastreada. (Ou seja, é mais rápido porque ignora algumas leituras de arquivo geralmente desnecessárias; incluindo, incorretamente, o único arquivo que contém as informações necessárias para evitar adequadamente essa falha.)

Portanto, você deve usar npm i vez de npm ci porque funcionará, evitando os dois bugs.

Queremos verificações estritas de bloqueio de pacote em CI.

Se você está falando sobre o fato de que o bloqueio de pacote fornece as verificações autoritativas de integridade e resolução, boas notícias: npm install faz isso.

Se você está falando sobre a verificação de que package-lock e package.json estão sincronizados um com o outro, você pode adicionar "scripts": { "prepare": "npx lock-verify" } ao seu package.json.

O npm @ 7 pousaria no nó 14, a tempo antes de ser LTS?

Essa é a minha expectativa, sim.

Mas, mesmo que seja LTS, a abordagem no passado era ter uma versão LTS do npm na versão LTS do nó, mesmo que isso signifique que ele mude dentro do período de tempo "congelado" do LTS, enviando npm v6 para 4 anos seria uma ideia profundamente ruim que não acho que Node servirá. E como o npm é realmente algo como um projeto separado, em vez de uma "dependência" de uma forma que afeta o tempo de execução, geralmente não há problema.

Uma vez que o npm v7 terá algumas alterações importantes (embora estejamos tentando minimizá-las o máximo possível), pode ser um problema se não chegarmos lá a tempo, ou podemos fazer algumas concessões para definir configurações padrão ou faça outras coisas para que o npm v7 que vem com o nó 14 LTS seja o mais próximo possível do npm v6.

Ah, acabei de verificar a programação do nó e vi que me enganei sobre o prazo. O lançamento _inicial_ do Nodo 14 é em 3 meses, mas não vai para o LTS até outubro.

Então, sim, devemos estar bem limpos. Espero que a versão inicial do npm v7 esteja disponível a tempo para o nó 14, e mais do que suficientemente estável quando v14 chegar ao LTS. (Últimas palavras famosas e tudo, mas a confiança tem aumentado constantemente conforme nos aproximamos de fazer a integração, e não tenho nenhuma razão para pensar que isso vai mudar em breve.)

Estou surpreso que isso não esteja sendo tratado como um bug mais importante do que é. Isso faz com que não possamos usar "npm ci" em nossos servidores de compilação no Windows. Isso é um grande negócio.

Não apenas no Windows, não consigo usar o npm ci em nenhum sistema

Se você está falando sobre o fato de que o bloqueio de pacote fornece as verificações autoritativas de integridade e resolução, boas notícias: npm install faz isso.

Espere .. tem sido minha experiência que npm install irá potencialmente resultar na atualização do arquivo package-lock.json se novos pacotes estiverem disponíveis que ainda sigam as regras definidas no arquivo package.json.

Esta funcionalidade mudou o @isaacs ?

@tommck acho que ele resolve isso com esta parte:

Se você está falando sobre a verificação de que package-lock e package.json estão sincronizados um com o outro, você pode adicionar "scripts": { "prepare": "npx lock-verify" } ao seu package.json.

Acho que você pode usá-lo como uma implementação pobre de npm ci em seu ambiente de CI. Você executaria npm install ; isso executa o script de preparação que verifica se o package-lock ainda está sincronizado com o seu package.json.

Se não me engano, isso tem dois problemas:

  • Não vejo como isso lida com atualizações para dependências indiretas que satisfaçam as restrições de suas dependências diretas. Eles seriam atualizados e sua construção incluiria um código mais recente.
  • Se o lock-verify detecta mudanças, você está obtendo uma compilação com falha inesperada. Você teria que gerar novamente e confirmar o pacote-lock.json atualizado. Eu gostaria que minhas compilações fossem previsíveis, para não falhar quando alguma dependência fosse liberada.

Então, sim, é um grande problema - felizmente, no nosso caso, fazemos compilações no Linux e elas ainda funcionam para nossa combinação de pacotes ... Outras pessoas têm menos sorte.

@coyoteecd Então ... presumindo que o arquivo de bloqueio estava bom (correto / verificado), executar "npm install" ainda pode modificar o arquivo de bloqueio do pacote com novas dependências?

executando "npm install" ainda pode modificar o arquivo de bloqueio do pacote com novas dependências?

Incorreta. Não vai fazer isso.

Executar npm install sem argumentos não adicionará nenhuma dependência diferente do que está no arquivo de bloqueio.

O que npm install fará, o que npm ci _não_ fará, é _skip_ baixar dependências que estão em node_modules e já correspondem ao que está no arquivo de bloqueio.

Espere .. tem sido minha experiência que npm install resultará potencialmente na atualização do arquivo package-lock.json se novos pacotes estiverem disponíveis que ainda sigam as regras definidas no arquivo package.json.

Esta funcionalidade mudou o @isaacs ?

Adoraria ver um caso em que isso acontecesse. A menos que você esteja explicitamente dizendo a ele para não respeitar o arquivo de bloqueio, ou executando npm update , ou o arquivo de bloqueio é inválido (ou seja, deps não têm suas dependências atendidas pela árvore que define), o arquivo de bloqueio bloqueou npm install desde que foi introduzido no npm v5.

full-icu é um pacote, que às vezes muda o arquivo de bloqueio .. mas acho que é o problema deles, não npm

minhas experiências: quando você tem o node v12 e outro desenvolvedor tem v10, pacote de dados icu full-icu downgrade para o node v10 ..

quando você tem o bloqueio com tudo e nenhum diretório node_modules e executa npm i ele removerá os dados icu do arquivo de bloqueio, você precisa executar npm i segunda vez para adicioná-lo novamente.

estávamos usando o npm ci, por causa desses 2 problemas

Para qualquer outra pessoa que acabe aqui devido a fsevents , esta é a solução npm ci do problema correspondente:

https://github.com/fsevents/fsevents/issues/301#issuecomment -572607085

@jayoungers FWIW, essa solução não funcionou para mim. De alguma forma, uma versão diferente de fsevents ainda está sendo construída com npm ci . Tive que mudar meus processos de construção para usar npm i .

Há alguma atualização sobre isso? Também somos afetados por esse bug.

Não tenho certeza se isso ajuda, mas encontrei esse problema ao executar npm install em um pacote onde package-lock.json já havia sido gerado no Linux (WSL no meu caso). Depois de excluir package-lock.json e executar novamente npm install no Windows, eu estava bem.

Parece que o Serverless Pro CI mudou de npm install para npm ci e este problema também ocorre e interrompe a compilação
Estou cometendo de uma máquina windows

build step: npm ci

> [email protected] postinstall /nuxt-serverless/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"


> [email protected] postinstall /nuxt-serverless/node_modules/ejs
> node ./postinstall.js


> [email protected] install /nuxt-serverless/node_modules/watchpack/node_modules/fsevents
> node-gyp rebuild

gyp
 ERR! build error 
gyp
 ERR! stack Error: not found: make
gyp ERR! stack     at getNotFoundError (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:13:12)
gyp
 ERR! stack     at F (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:68:19)
gyp ERR! stack
     at E (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:80:29)
gyp ERR! stack     at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:89:16
gyp ERR! 
stack     at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/isexe/index.js:42:5
gyp ERR! stack     at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/isexe/mode.js:8:5
gyp 
ERR! stack     at FSReqWrap.oncomplete (fs.js:154:21)
gyp ERR! 
System Linux 4.14.171-105.231.amzn1.x86_64
gyp ERR! command "/root/.nvm/versions/node/v10.13.0/bin/node" "/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /nuxt-serverless/node_modules/watchpack/node_modules/fsevents
gyp ERR!
 node -v v10.13.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 

Usar npm install --no-optional não funciona como uma solução alternativa.

momento é marcado como opcional em package-lock.json :

"moment": {
      "version": "2.29.1",
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
      "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
      "dev": true,
      "optional": true
 }

Quando eu remover o momento de node_modules npm i o colocarei de volta:

rm -rf node_modules/moment
npm install --no-optional

ls node_modules | grep moment 
moment

@Elijen Não acredito que seja o mesmo problema deste tópico, que são alvos de SO para pacotes. Você pode registrar um problema separado, se ainda não existir um.

Ah, a propósito, fsevents não tem mais esse problema desde 5 de maio:
https://github.com/fsevents/fsevents/issues/301

@isaacs Isso npm@7 ?

@paulirwin Talvez você esteja certo. Eu vi vários problemas e postagens de fóruns criados sobre o problema que mencionei e presumi que este é apenas um problema posterior causado por ele.

Adoraria ver um caso em que isso acontecesse. A menos que você esteja explicitamente dizendo a ele para não respeitar o arquivo de bloqueio, ou executando npm update , ou o arquivo de bloqueio é inválido (ou seja, deps não têm suas dependências atendidas pela árvore que define), o arquivo de bloqueio bloqueou npm install desde que foi introduzido no npm v5.

Eu vi dependências de atualização de npm install com um arquivo de bloqueio válido na v6.14.8, quando as versões do pacote são especificadas por tag. Registrado como # 2167.

A boa notícia é que isso não parece estar acontecendo na v7.0.10: +1:

Esta página foi útil?
0 / 5 - 0 avaliações