web-dev-qa-db-fra.com

Dois-je archiver node_modules à git lors de la création d'une application node.js sur Heroku?

J'ai suivi les instructions de base pour démarrer node.js sur Heroku ici:

https://devcenter.heroku.com/categories/nodejs

Ces instructions ne vous demandent pas de créer un noeud_modules .gitignore, et impliquent donc que node_modules doit être enregistré dans git. Lorsque j'inclus node_modules dans git, mon application de démarrage s'exécutait correctement.

Quand j'ai suivi l'exemple le plus avancé sur:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-Ruby-mongodb-socketiohttps://github.com/mongolab/tractorpush-server (source)

Il m'a chargé d'ajouter node_modules à .gitignore. J'ai donc supprimé node_modules de git, ajouté à .gitignore, puis redéployé. Cette fois, le déploiement a échoué comme suit:

-----> Heroku receiving Push
-----> Node.js app detected
-----> Resolving engine versions
       Using Node.js version: 0.8.2
       Using npm version: 1.0.106
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
       Error: npm doesn't work with node v0.8.2
       Required: [email protected] || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Error: npm doesn't work with node v0.8.2
       Required: [email protected] || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Dependencies installed
-----> Discovering process types
       Procfile declares types -> mongod, redis, web
-----> Compiled slug size is 5.0MB
-----> Launching... done, v9

Courir "heroku ps" confirme le crash. Ok, pas de problème, j'ai donc annulé la modification, rajouté node_module dans le référentiel git et l'ai supprimé de .gitignore. Cependant, même après la restauration, le même message d'erreur persiste lors du déploiement, mais l'application s'exécute à nouveau correctement. L'exécution de "heroku ps" m'indique que l'application est en cours d'exécution.

Donc ma question est quelle est la bonne façon de faire cela? Inclure node_modules ou pas? Et pourquoi le message d'erreur persiste-t-il quand je reviens en arrière? Je suppose que le dépôt git est en mauvais état du côté de Heroku?

359
Jason Griffin

Deuxième mise à jour

La FAQ n'est plus disponible.

De la documentation de shrinkwrap :

Si vous souhaitez verrouiller des octets spécifiques inclus dans un package, par exemple pour avoir une confiance totale dans la capacité de reproduire un déploiement ou une construction, vous devez alors vérifier vos dépendances dans le contrôle de source ou utiliser un autre mécanisme permettant de vérifier contenu plutôt que versions.

Shannon et Steven en ont déjà parlé, mais je pense que cela devrait faire partie de la réponse acceptée.


Mise à jour

La source répertoriée pour la recommandation ci-dessous a été mise à jour . Ils ne recommandent plus que le dossier node_modules soit validé.

Habituellement non. Autorisez npm à résoudre les dépendances de vos packages.

Pour les packages que vous déployez, tels que les sites Web et les applications, vous devez utiliser npm shrinkwrap pour verrouiller votre arborescence de dépendances complète:

https://docs.npmjs.com/cli/shrinkwrap


Poste originale

Pour référence, npm FAQ répond clairement à votre question:

Vérifiez node_modules dans git pour les éléments que vous déployez, tels que les sites Web et les applications. Ne vérifiez pas node_modules dans git pour les bibliothèques et les modules destinés à être réutilisés. Utilisez npm pour gérer les dépendances dans votre environnement dev, mais pas dans vos scripts de déploiement.

et pour de bonnes raisons, lisez le post de Mikeal Rogers à ce sujet .


Source: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git

390
Kostia

Ma plus grande préoccupation avec not vérifier node_modules dans Git, c'est que dans 10 ans, lorsque votre application de production sera encore utilisée, npm risque de ne pas être disponible. Ou npm pourrait devenir corrompu; ou les responsables peuvent décider de supprimer de leur référentiel la bibliothèque sur laquelle vous comptez. ou la version que vous utilisez peut être découpée.

Cela peut être atténué par des gestionnaires de référentiels comme maven, car vous pouvez toujours utiliser votre propre Nexus ou Artifactory local pour conserver un miroir avec les packages que vous utilisez. Autant que je sache, un tel système n'existe pas pour npm. Il en va de même pour les gestionnaires de bibliothèques côté client tels que Bower et Jamjs.

Si vous avez affecté les fichiers à votre propre dépôt Git, vous pouvez les mettre à jour quand vous le souhaitez. Vous avez le confort de génération répétable et la certitude que votre application ne sera pas endommagée par une action tierce.

158
Jonathan

Vous devriez ne pas inclure node_modules dans votre .gitignore (ou plutôt vous ) devriez inclure node_modules dans votre source déployé sur Heroku).

Si node_modules:

  • existe alors npm install utilisera ces bibliothèques vendues et reconstruira toutes les dépendances binaires avec npm rebuild.
  • n'existe pas alors npm install devra extraire lui-même toutes les dépendances, ce qui ajoute du temps à l'étape de compilation slug.

Voir le source de buildpack Node.js pour ces étapes exactes

Cependant, l'erreur d'origine semble être une incompatibilité entre les versions de npm et node. C'est une bonne idée de toujours définir explicitement la section engines de votre packages.json selon ce guide pour éviter ces types de situation:

{
  "name": "myapp",
  "version": "0.0.1",
  "engines": {
    "node": "0.8.x",
    "npm":  "1.1.x"
  }
}

Cela garantira parité dev/prod et réduira les risques de telles situations à l’avenir.

67
Ryan Daigle

J'allais laisser ceci après ce commentaire: Dois-je archiver node_modules à git lors de la création d'une application node.js sur Heroku?

Mais stackoverflow le formatait bizarrement. Si vous n'avez pas les mêmes machines et que vous vérifiez node_modules, effectuez un .gitignore sur les extensions natives. Notre .gitignore ressemble à:

# Ignore native extensions in the node_modules folder (things changed by npm rebuild)
node_modules/**/*.node
node_modules/**/*.o
node_modules/**/*.a
node_modules/**/*.mk
node_modules/**/*.gypi
node_modules/**/*.target
node_modules/**/.deps/
node_modules/**/build/Makefile
node_modules/**/**/build/Makefile

Testez cela en vérifiant d'abord tout, puis demandez à un autre développeur de procéder comme suit:

rm -rf node_modules
git checkout -- node_modules
npm rebuild
git status

Assurez-vous qu'aucun fichier n'a changé.

22
ibash

Je crois que npm install ne devrait pas fonctionner dans un environnement de production. Plusieurs problèmes peuvent survenir: panne de npm, téléchargement de nouvelles dépendances (shrinkwrap semble résoudre ce problème) en sont deux.

D'autre part, node_modules ne devrait pas être engagé sur git. Outre leur grande taille, les commits qui les incluent peuvent devenir gênants.

Les meilleures solutions seraient les suivantes: npm install devrait s'exécuter dans un environnement d'infrastructure de configuration similaire à l'environnement de production. Tous les tests seront exécutés et un fichier de version compressé contenant toutes les dépendances sera créé.

10
user2468170

J'utilise à la fois le dossier node_modules et le wrapping rétractable. Les deux solutions ne m'ont pas rendu heureux.

En bref: node_modules engagé ajoute trop de bruit au référentiel.
Et shrinkwrap.json n’est pas facile à gérer et rien ne garantit qu’un projet sous film rétractable sera construit dans quelques années.

J'ai découvert que Mozilla utilisait un référentiel distinct pour l'un de ses projets https://github.com/mozilla-b2g/gaia-node-modules

Donc, cela ne m'a pas pris longtemps pour implémenter cette idée dans un outil CLI de nœud https://github.com/bestander/npm-git-lock

Juste avant chaque construction, ajoutez
npm-git-lock --repo [[email protected]: votre/dédié/node_modules/git/repository.git]

Il calculera le hachage de votre package.json et extraira le contenu de node_modules à partir d'un référentiel distant ou, s'il s'agit d'une première version de ce package.json, effectuera un nettoyage _npm install_ et transmettra les résultats au repo à distance.

8
bestander

Ce qui a bien fonctionné pour moi, c’est d’ajouter explicitement une version de npm à package.json ("npm": "1.1.x") et de ne PAS archiver node_modules dans git. Le déploiement est peut-être plus lent (puisqu'il télécharge les packages à chaque fois), mais je ne pouvais pas les compiler lors de leur enregistrement. Heroku recherchait des fichiers qui n'existaient que sur ma boîte locale.

5
Jason Griffin

Au lieu de vérifier node_modules, créez un fichier package.json pour votre application.

Le fichier package.json spécifie les dépendances de votre application. Heroku peut alors dire à npm d'installer toutes ces dépendances. Le tutoriel que vous avez lié contient une section sur les fichiers package.json.

3
matzahboy

De https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html :

Edit: Le lien d'origine était celui-ci mais il est maintenant mort. Merci @Flavio pour l'avoir signalé.

Récapituler.

  • N'enregistrez que node_modules pour les applications que vous déployez, et non les packages réutilisables que vous maintenez.
  • Toutes les dépendances compilées doivent avoir leur source archivée, et non les cibles de compilation, et $ npm reconstruire lors du déploiement.

Ma partie préférée:

Tous ceux qui ont ajouté node_modules à votre gitignore, supprimez cette merde, aujourd’hui , c’est un artéfact d’une époque que nous sommes trop heureux de laisser derrière nous. L'ère des modules globaux est morte.

3
Benjamin Crouzier

J'utilise cette solution:

  1. Créez un référentiel séparé contenant node_modules. Si vous avez des modules natifs à construire pour une plate-forme spécifique, créez un référentiel distinct pour chaque plate-forme.
  2. Attachez ces référentiels à votre référentiel de projet avec git submodule:

git submodule add .../your_project_node_modules_windows.git node_modules_windows

git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64

  1. Créez un lien entre le répertoire node_modules propre à la plate-forme et le répertoire node_modules, puis ajoutez node_modules à .gitignore.
  2. Exécutez npm install.
  3. Valider les modifications du référentiel de sous-modules.
  4. Validez vos modifications dans le référentiel de projet.

Ainsi, vous pouvez facilement basculer entre node_modules sur différentes plates-formes (par exemple, si vous développez sous OS X et le déployez sous Linux).

3
mixel

http://nodejs.org/api/modules.html

[...] node commence au répertoire parent du module actuel, ajoute /node_modules et tente de charger le module à partir de cet emplacement.

S'il ne s'y trouve pas, , il sera déplacé dans le répertoire parent, et ainsi de suite , jusqu'à ce que la racine de l'arborescence soit atteinte.

Si vous lancez vos propres modules spécifiques à votre application, vous pouvez conserver ceux-ci ( et uniquement ceux-ci ) dans le /node_modules de votre application. Et déplacez toutes les autres dépendances vers le répertoire parent.

Ce cas d'utilisation de vraiment génial, il vous permet de conserver les modules que vous avez créés spécifiquement pour votre application avec votre application, et n'encombre pas votre application avec des dépendances qui peuvent être installées ultérieurement.

2
laggingreflex

scénario 1:

Un scénario: vous utilisez un package qui est supprimé de npm. Si vous avez tous les modules dans le dossier node_modules, alors ce ne sera pas un problème pour vous. Si vous n'avez que le nom du paquet dans le fichier package.json, vous ne pourrez plus le récupérer. Si un colis a moins de 24 heures, vous pouvez facilement le retirer de npm. Si vous avez plus de 24 heures, vous devez les contacter. Mais:

Si vous contactez le support, ils vérifieront si la suppression de cette version de votre package empêcherait d'autres installations. Si c'est le cas, nous ne l'enlèverons pas.

en savoir plus

Donc, les chances pour cela sont faibles, mais il y a le scénario 2 ...


scénario 2:

Voici un autre scénario: vous développez une version d'entreprise de votre logiciel ou un logiciel très important et écrivez dans votre package.json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Vous utilisez la méthode function1(x) de ce paquet.

Maintenant, les développeurs de studpid-package renomment la méthode function1(x)to function2(x) et ils font une erreur ... Ils modifient la version de leur package de 1.0.1 à 1.1.0. C'est un problème parce que lorsque vous appelez npm install la prochaine fois, vous acceptez la version 1.1.0 car vous avez utilisé le tilde ("studpid-package": "~1.0.1").

L'appel de function1(x) peut maintenant causer des erreurs et des problèmes.


Le fait de transférer tout le dossier node_modules (souvent plus de 100 Mo) dans votre référentiel vous coûtera de la mémoire. Quelques ko (package.json uniquement) comparés à des centaines de Mo (package.json & node_modules) ... Pensez-y.

Vous pouvez le faire/devriez y penser si:

  • le logiciel est très important.

  • cela vous coûte de l'argent en cas d'échec.

  • vous ne faites pas confiance au registre npm. npm est centralisé et pourrait théoriquement être arrêté.

Vous n'avez pas besoin de pour publier le dossier node_modules dans 99,9% des cas si:

  • vous développez un logiciel juste pour vous-même.

  • vous avez programmé quelque chose et souhaitez simplement publier le résultat sur GitHub, car quelqu'un d'autre pourrait peut-être s'y intéresser.


Si vous ne voulez pas que les node_modules soient dans votre référentiel, créez simplement un fichier .gitignore et ajoutez la ligne node_modules.

1
ndsvw