Cli: [BUG] npm ci installe une dépendance facultative qui cible un système d'exploitation différent de celui de l'hôte

Créé le 5 déc. 2019  ·  32Commentaires  ·  Source: npm/cli

Quoi / Pourquoi

npm ci semble installer une dépendance facultative pour le système d'exploitation Linux lors de l'exécution sur un mac et semble installer la dépendance facultative pour mac lors de l'exécution sous Linux.

Quand

$ npm init -y; npm i [email protected]; npm ls; npm ci; npm ls
cliquez pour afficher la sortie de la commande ci-dessus
 Écrit dans /private/tmp/d/package.json:

 {
 "nommé",
 "version": "1.0.0",
 "la description": "",
 "main": "index.js",
 "scripts": {
 "test": "echo \" Erreur: aucun test spécifié \ "&& exit 1"
 },
 "mots clés": [],
 "auteur": "",
 "licence": "ISC"
 }



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

 npm a créé un fichier de verrouillage sous le nom package-lock.json. Vous devez valider ce fichier.
 npm WARN [email protected] Aucune description
 npm WARN [email protected] Aucun champ de référentiel.
 npm WARN optionnel SAUT DEPENDANCE OPTIONNELLE: [email protected] (node_modules / oax / node_modules / oax-windows-64):
 npm WARN notsup SAUT DEPENDANCE OPTIONNELLE: Plate-forme non prise en charge pour [email protected]: voulu {"os": "win32", "arch": "x64"} (actuel: {"os": "darwin", "arch": "x64"})
 npm WARN optionnel SAUT DEPENDANCE OPTIONNELLE: [email protected] (node_modules / oax / node_modules / oax-linux-64):
 npm WARN notsup SAUT DEPENDANCE OPTIONNELLE: Plate-forme non prise en charge pour [email protected]: voulu {"os": "linux", "arch": "x64"} (actuel: {"os": "darwin", "arch": "x64"})

 + [email protected]
 ajouté 2 packages et audité 4 packages en 1.1s
 trouvé 0 vulnérabilités

 [email protected] / privé / tmp / d
 └─┬ [email protected]
 ├── [email protected]
 ├── DÉPENDANCE OPTIONNELLE INÉGALÉE [email protected]
 └── DÉPENDANCE OPTIONNELLE INÉGALÉE [email protected]

 npm WARN prépare la suppression des node_modules existants / avant l'installation

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

 ajouté 3 paquets en 0.722s
 [email protected] / privé / tmp / d
 └─┬ [email protected]
 ├── [email protected]
 ├── [email protected]
 └── DÉPENDANCE OPTIONNELLE INÉGALÉE [email protected]

  • n / a

Comment

Comportement actuel

actuellement, il semble que npm ci est cassé pour les dépendances optionnelles qui utilisent les champs os et arch de package.json

Étapes à suivre pour reproduire

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

Vous devriez voir que npm i fonctionne correctement et installe une seule dépendance facultative pour oax.
Vous devriez également voir que npm ci fonctionne pas correctement et installe deux des dépendances facultatives pour oax, cela ne devrait jamais arriver car chaque dépendance facultative cible un système d'exploitation et une architecture différents, il devrait être impossible d'avoir plus d'un les dépendances facultatives installées.

Comportement prévisible

il devrait installer oax-darwin lors de l'exécution sur darwin et devrait installer oax-linux lors de l'exécution sous linux

Qui

  • n / a

Références

  • n / a
Bug

Commentaire le plus utile

Je suis surpris que cela ne soit pas traité comme un bug plus important que ce soit. Cela fait que nous ne pouvons pas utiliser "npm ci" sur nos serveurs de build dans Windows. C'est un gros problème.

Tous les 32 commentaires

J'ai rencontré le même problème avec fsevents sous Windows, lors de l'installation de deux packages qui dépendent de différentes versions de 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

Le dernier webpack dépend de watchpack qui dépend d'un ancien [email protected] qui dépend d'un ancien [email protected].

Alors que le dernier chokidar dépend de [email protected]

Mais npm install a sauté correctement les deux versions de fsevents car elles sont incompatibles avec le système d'exploitation.

Toutefois:

 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

Et si je regarde dans node_modules, fsevents est là et ça ne devrait pas être.
De plus, npm ci --no-optional ne fonctionne pas, cela est signalé ici: https://github.com/npm/cli/issues/637

J'utilise l'installation de Node 12 LTS, npm -v => 6.13.4

Le fonctionnement de npm ci --no-optional peut dépendre de facteurs supplémentaires. Voir https://github.com/npm/cli/issues/637#issuecomment -570813804

Ainsi, alors que npm ci échoue dans mon environnement, npm ci --no-optional fonctionne. Mon environnement:

  • Windows 10
  • Nodejs 12.13.1
  • npm 6.13.4

Après la mise à jour vers le dernier nœud et npm ont le même problème .. tous les projets où il est fsevent échouent à s'installer avec npm ci , car il construit fsevents

  • Windows 10 Professionnel 1909
  • nœud 12.14.1
  • npm 6.13.6

Après la mise à jour vers le dernier nœud et npm ont le même problème .. tous les projets où il est fsevent échouent à s'installer avec npm ci , car il construit fsevents

* Windows 10 Pro 1909

* node 12.14.1

* npm 6.13.6

@padinko Avez-vous également essayé la variante avec l'indicateur supplémentaire --no-optional , c'est- npm ci --no-optional dire

Après la mise à jour vers le dernier nœud et npm ont le même problème .. tous les projets où il est fsevent échouent à s'installer avec npm ci , car il construit fsevents

* Windows 10 Pro 1909

* node 12.14.1

* npm 6.13.6

@padinko Avez-vous également essayé la variante avec l'indicateur supplémentaire --no-optional , c'est- npm ci --no-optional dire

npm ci échouent avec ces packages:

\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 n'en ont que 2:

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

donc là c'est la différence, mais toujours en compilant fsevents

@paulmillr @pipobscure Mon problème (# 658) était un double de ce ticket. Suivez celui-ci pour rester à jour.

Je peux également confirmer ce bogue sur Ubuntu. npm ci installe fsevents qui ne devrait être installé que sur MacOS

@mikemimik ou @isaacs , avez-vous des commentaires sur ce bogue? Oui, fsevents changé quelque chose pourquoi c'est maintenant un problème plus important. Mais le problème sous-jacent est toujours causé par NPM et doit être résolu ici.

Il semble que le changement pertinent est que fsevents a commencé à utiliser node-pre-gyp pour extraire un binaire précompilé, plutôt que de le construire en place, ce qui entraîne un script postinstall qui se termine sans erreur sur toutes les plates-formes. Puisque npm ci essaie simplement de mettre en page tout ce qui se trouve dans le fichier de verrouillage sans vérifier s'il prend en charge la plate-forme, et ne supprime que les deps facultatifs dont les scripts d'installation échouent, cela entraîne l'installation de ce dépôt.

npm v7 n'aura pas ce problème. (Je travaille dans le code qui fera cela maintenant.) Je n'ai pas vérifié dans quelle mesure il serait impliqué de résoudre ce problème pour npm v6, mais il y a de fortes chances que cela finisse par être "mise à jour à la v7 pour le correctif ". En attendant, je vous recommande d'utiliser npm install au lieu de npm ci si cela vous affecte.

Oui, fsevents changé sa tactique. Mais c'est en fait l'inverse. Ils avaient l'habitude d'avoir des binaires précompilés. L'installation sur Windows donnerait un 404, et sauter. Maintenant, il essaie de construire, puis interrompt la génération. Parce que la construction ne devrait même pas commencer. Indépendamment: npm ci est conçu pour les environnements CI. Comment devrions-nous alors utiliser npm i place? Nous voulons les contrôles stricts de verrouillage des paquets dans CI.

Aussi: Est-ce que npm@7 atterrirait dans le nœud 14, à temps avant qu'il ne soit LTS? Ai-je raison de supposer que nous sommes bloqués avec npm i ou un verrouillage de version pendant un an lorsque nous sommes sur la piste LTS?

Désolé d'avoir changé de tactique contre vous. Cependant, nous avons perdu l'accès au S3 utilisé à l'origine et cela devenait un problème de sécurité de plus en plus sérieux. C'est pourquoi nous sommes retournés à la construction au besoin. Surtout étant donné que la v2.x basée sur NAPI n'a pas du tout besoin de construire pour le nœud v8.x +

Maintenant, il essaie de construire, puis interrompt la génération. Parce que la construction ne devrait même pas commencer.

Oh, c'est bizarre. Je m'attendrais à ce que npm ci gère un échec de construction d'un dépôt facultatif en tant qu'événement de type d'avertissement non fatal, et supprime simplement le dépôt incriminé.

Quoi qu'il en soit: npm ci est conçu pour les environnements CI. Pourquoi devrions-nous alors utiliser npm i à la place? Nous voulons les contrôles stricts de verrouillage des paquets dans CI.

Bonne question.

«Conçu pour les environnements CI» ne signifie pas toujours «meilleur pour cet environnement CI particulier, pour cette application particulière».

Dans ce cas, il existe deux problèmes rencontrés par npm ci.

  • Il ne gère pas correctement les échecs de compilation pour les deps facultatifs.
  • Il n'est pas capable de pré-filtrer les déps en fonction des restrictions os / cpu, car il ne regarde que le package-lock.json, où ces informations ne sont pas suivies. (Autrement dit, il est plus rapide car il ignore certaines lectures de fichiers généralement inutiles; y compris, à tort, le seul fichier contenant les informations nécessaires pour éviter correctement cet échec.)

Donc, vous devriez utiliser npm i plutôt que npm ci car cela fonctionnera, évitant les deux bogues.

Nous voulons les contrôles stricts de verrouillage des paquets dans CI.

Si vous parlez du fait que package-lock fournit les vérifications d'intégrité et de résolution faisant autorité, alors bonne nouvelle: npm install fait également.

Si vous parlez de vérifier que package-lock et package.json sont synchronisés l'un avec l'autre, vous pouvez ajouter "scripts": { "prepare": "npx lock-verify" } à votre package.json.

Est-ce que npm @ 7 atterrirait dans le nœud 14, à temps avant d'être LTS?

Telle est mon attente, oui.

Mais, même s'il s'agit de LTS, l'approche dans le passé consistait à avoir une version LTS de npm dans la version LTS du nœud, même si cela signifie qu'elle change dans le laps de temps LTS "gelé", donc expédier npm v6 pour 4 années serait une très mauvaise idée que je ne pense pas que Node fera. Et comme npm est vraiment quelque chose d'un projet séparé, plutôt qu'une "dépendance" d'une manière qui affecte le temps d'exécution, c'est généralement bien.

Étant donné que npm v7 aura des changements de rupture (bien que nous essayions de les minimiser autant que possible), cela peut être un problème si nous ne les obtenons pas à temps, ou nous pouvons faire des concessions pour définir les configurations par défaut ou faire d'autres choses pour que le npm v7 livré avec le nœud 14 LTS soit aussi proche que possible de npm v6.

Oh, je viens de vérifier le calendrier du nœud et de voir que je me suis trompé sur le calendrier. La sortie _initial_ de Node 14 est dans 3 mois, mais elle ne passera pas LTS avant octobre.

Alors oui, nous devrions être bien en clair. Je m'attends à ce que la version initiale de npm v7 soit disponible à temps pour le nœud 14, et plus que suffisamment stable au moment où la v14 atteindra LTS. (Derniers mots célèbres et tout, mais la confiance augmente régulièrement à mesure que nous nous rapprochons de l'intégration, et je n'ai aucune raison de penser que cela changera bientôt.)

Je suis surpris que cela ne soit pas traité comme un bug plus important que ce soit. Cela fait que nous ne pouvons pas utiliser "npm ci" sur nos serveurs de build dans Windows. C'est un gros problème.

Pas seulement Windows, je ne peux utiliser npm ci sur aucun système

Si vous parlez du fait que package-lock fournit les vérifications d'intégrité et de résolution faisant autorité, alors bonne nouvelle: npm install fait également.

Attendez ... d'après mon expérience, npm install entraînera potentiellement la mise à jour du fichier package-lock.json si de nouveaux packages sont disponibles qui respectent toujours les règles définies dans le fichier package.json.

Cette fonctionnalité a-t-elle changé @isaacs ?

@tommck Je pense qu'il aborde cela avec cette partie:

Si vous parlez de la vérification que le package-lock et package.json sont synchronisés l'un avec l'autre, vous pouvez ajouter "scripts": { "prepare": "npx lock-verify" } à votre package.json.

Je suppose que vous pouvez l'utiliser comme une implémentation par un homme pauvre de npm ci dans votre environnement CI. Vous exécuteriez npm install ; cela exécute le script de préparation qui vérifie si le verrou de package est toujours synchronisé avec votre package.json.

Si je ne me trompe pas, cela pose deux problèmes:

  • Je ne vois pas comment cela gère les mises à jour des dépendances indirectes qui satisfont les contraintes de vos dépendances directes. Ceux-ci seraient mis à jour et votre build inclurait du code plus récent.
  • Si lock-verify détecte des changements, vous obtenez une compilation échouée à l'improviste. Vous devrez recréer et valider le package-lock.json mis à jour. J'aimerais que mes builds soient prévisibles, qu'ils n'échouent pas lorsqu'une dépendance est libérée.

Donc oui, c'est un gros problème - heureusement dans notre cas, nous construisons sur Linux et ils fonctionnent toujours pour notre combinaison de paquets ... D'autres personnes ont moins de chance.

@coyoteecd Donc ... en supposant que le fichier de verrouillage était correct (correct / vérifié), l'exécution de "npm install" pourrait encore modifier le fichier de verrouillage du package avec de nouvelles dépendances?

l'exécution de "npm install" peut encore modifier le fichier de verrouillage du package avec de nouvelles dépendances?

Incorrect. Il ne fera pas cela.

L'exécution de npm install sans argument n'ajoutera aucune dépendance différente de ce qui se trouve dans le fichier de verrouillage.

Ce que npm install fera, ce que npm ci ne fera _pas_, c'est _skip_ télécharger les dépendances qui sont dans node_modules et correspondent déjà à ce qui est dans le fichier de verrouillage.

Attendez ... d'après mon expérience, l'installation de npm entraînera potentiellement la mise à jour du fichier package-lock.json si de nouveaux packages sont disponibles qui respectent toujours les règles définies dans le fichier package.json.

Cette fonctionnalité a-t-elle changé @isaacs ?

J'aimerais voir un cas où cela se produit. À moins que vous dites explicitement de ne pas respecter le lockfile, ou en cours d' exécution npm update , ou lockfile est invalide (c. -à- DEPS n'ont pas leurs dépendances remplies par l'arbre qu'il définit), le lockfile a verrouillé npm install depuis son introduction dans npm v5.

full-icu est un package, qui change parfois le fichier de verrouillage .. mais je pense que c'est leur problème, pas npm

mes expériences: lorsque vous avez node v12 et qu'un autre développeur a v10, package de données icu downgrade full-icu pour node v10 ..

lorsque vous avez verrouillé avec tout et pas node_modules répertoire npm i cela supprimera les données icu du fichier de verrouillage, vous devez exécuter npm i deuxième fois pour l'ajouter à nouveau.

nous utilisions npm ci, à cause de ces 2 problèmes

Pour tous ceux qui se retrouvent ici en raison de fsevents , voici la solution npm ci de leur problème correspondant:

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

@jayoungers FWIW, cette solution n'a pas fonctionné pour moi. D'une manière ou d'une autre, une version différente de fsevents est toujours en cours de construction avec npm ci . J'ai dû changer mes processus de construction pour utiliser npm i place.

Y a-t-il des mises à jour à ce sujet? Nous sommes également affectés par ce bug.

Je ne sais pas si cela aide, mais j'ai rencontré ce problème lors de l'exécution de npm install dans un package où package-lock.json avait déjà été généré sous Linux (WSL dans mon cas). Après avoir supprimé package-lock.json et relancé npm install sous Windows, tout allait bien.

Semble Serverless Pro CI changé de npm install à npm ci et ce problème se produit également et interrompt la construction
Je commets depuis une machine 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 

L'utilisation de npm install --no-optional ne fonctionne pas comme solution de contournement.

moment est marqué comme facultatif dans 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
 }

Quand je supprime le moment de node_modules npm i remettra:

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

ls node_modules | grep moment 
moment

@Elijen Je ne pense pas que ce soit le même problème que ce fil de discussion, à savoir les cibles du système d'exploitation pour les packages. Vous souhaiterez peut-être déposer un problème distinct s'il n'en existe pas déjà un.

Oh, et au fait, fsevents n'a plus ce problème depuis le 5 mai:
https://github.com/fsevents/fsevents/issues/301

@isaacs Est-ce que cela atterrit en npm@7 ?

@paulirwin Peut-être que vous avez raison. J'ai vu plusieurs problèmes et messages de forum créés sur le problème que j'ai mentionné et j'ai supposé que celui-ci n'était qu'un problème en aval causé par celui-ci.

J'aimerais voir un cas où cela se produit. À moins que vous dites explicitement de ne pas respecter le lockfile, ou en cours d' exécution npm update , ou lockfile est invalide (c. -à- DEPS n'ont pas leurs dépendances remplies par l'arbre qu'il définit), le lockfile a verrouillé npm install depuis son introduction dans npm v5.

J'ai vu npm install mettre

La bonne nouvelle est que cela ne semble pas se produire dans la v7.0.10: +1:

Cette page vous a été utile?
0 / 5 - 0 notes