Comment déployer l'application Node.js avec une structure profonde node_modules sous Windows?

91

J'ai rencontré un problème curieux - apparemment, certains modules Node.js ont des hiérarchies de dossiers si profondes que la commande de copie de Windows (ou PowerShell, Copy-Itemqui est ce que nous utilisons réellement) rencontre la tristement célèbre erreur "chemin trop long" lorsque le chemin est supérieur à 250 caractères longs.

Par exemple, il s'agit d'une hiérarchie de dossiers qu'un seul module Node peut créer:

node_modules\nodemailer\node_modules\simplesmtp\node_modules\
xoauth2\node_modules\request\node_modules\form-data\node_modules\
combined-stream\node_modules\delayed-stream\...

Cela semble fou mais c'est une réalité avec les modules Node.

Nous devons utiliser le copier-coller pendant le déploiement (nous n'utilisons pas une plate-forme cible "intelligente" comme Heroku où le déploiement de Git serait une option) et c'est une limitation sérieuse sur Windows.

N'existe-t-il pas une commande npm ou quelque chose qui compacterait le node_modulesdossier ou n'inclurait peut-être que ce qui est réellement nécessaire au moment de l'exécution? (Les modules de nœud contiennent généralement des testdossiers, etc. que nous n'avons pas besoin de déployer.) Avez-vous d'autres idées pour contourner ce problème? Ne pas utiliser Windows n'est malheureusement pas une option :)

Borek Bernard
la source
1
Votre projet a-t-il un ensemble package.jsonavec dependencies? Si tel est le cas, pouvez-vous copier sans node_moduleset utiliser npm vers installou updateles dépendances?
Jonathan Lonowski
4
@JonathanLonowski Notre environnement de déploiement ne prend pas en charge l'exécution npm installdans l'environnement cible, il fonctionne en créant un "package de déploiement" localement (essentiellement un ZIP plus quelques métadonnées) qui est ensuite téléchargé sur la machine cible, extrait là-bas et c'est tout. J'ai donc besoin d'inclure node_modulesdirectement.
Borek Bernard

Réponses:

24

npm v3 (publié récemment) résout ce problème en aplatissant les dépendances. Consultez les notes de version ici dans https://github.com/npm/npm/releases/tag/v3.0.0 sous la flat flatsection.

Et le dernier commentaire sur ce numéro https://github.com/npm/npm/issues/3697

RameshVel
la source
5
Les notes de version pour flat flatsont maintenant enterrées dans une autre page. Voici un lien direct: github.com/npm/npm/releases/tag/v3.0.0
John-Philip
Merci @ John-Philip, a mis à jour la réponse avec le nouveau lien
RameshVel
62

juste pour ajouter à cela ... une autre chose qui m'a aidé a été de lister tous les modules installés avec npm ls.

ce qui vous donnera un arbre de modules et de versions ... à partir de là, il est assez facile d'identifier ceux qui sont des doublons ... npm dedupen'a rien fait pour moi. Je ne sais pas si c'est un bogue ou quoi (Node v 10.16)

Donc, une fois que vous avez identifié un module en double, installez-le dans le répertoire racine node_module en utilisant npm install [email protected] --save-dev. La version est importante.

après cela, j'ai effacé mon répertoire node_modules et j'ai fait un nouveau npm install.

Version courte

  1. npm ls pour obtenir une liste de tous les modules installés.
  2. parcourez ces modules et identifiez les modules en double (la version est importante )
  3. npm install module@version --save-dev pour installer ces modules dans le répertoire racine node_modules et mettre à jour package.json.
  4. rmdir node_modules pour supprimer le répertoire node_modules.
  5. npm install pour extraire une nouvelle copie de vos dépendances.

Une fois que j'ai fait cela, tout était beaucoup plus propre.

Je recommande également de commenter votre fichier package.json pour montrer ceux qui ont été supprimés pour aplatir l'arborescence node_modules.

Ben Lesh
la source
Cela a très bien fonctionné pour moi. Je vous remercie! Pardonnez mon ignorance, mais pourquoi les modules ne sont-ils pas toujours installés au plus haut niveau?
Caleb
2
@Caleb probablement parce que différents modules reposent sur différentes versions du même module, ou peut-être simplement parce qu'il est plus facile d'obtenir tout ce qui est nécessaire, puis factorisez-le ... Je ne sais pas.
Ben Lesh
7
Quoi qu'il en soit, merci pour la pointe. Je viens de souffler environ 1700 fichiers en double de notre projet. Supprimer des choses est ce que je préfère en tant que développeur! Aussi, pour tous ceux qui cherchent comment ajouter des commentaires à package.json, voici votre réponse: stackoverflow.com/questions/14221579/...
Caleb
github.com/joyent/node/issues/6960 node guy dit que Windows est un citoyen de première classe. Ils ont dit. Mais ils ont résolu le problème et rien n'a été corrigé. Utilisateurs Windows chanceux.
vee
38

Je ne pense pas qu'il y ait de bonne solution compte tenu de vos contraintes, mais voici quelques éléments qui pourraient vous aider.

  • Essayez d'utiliser npm dedupepour optimiser votre hiérarchie de répertoires, ce qui peut raccourcir certains chemins
  • Utilisez npm install --productionpour installer sans les outils de développement
  • Prenez certaines de ces dépendances profondément imbriquées (juste assez pour éviter le problème, je suggère) et déplacez-les vers le répertoire node_modules de niveau supérieur. Gardez-en simplement une trace pour savoir quelles sont vos véritables dépendances et quelles sont les solutions de contournement à ce problème.
  • OU déplacez certaines de ces dépendances profondes vers le node_modulesrépertoire le plus élevé sous your_project/node_modules/pkg_with_deep_depsce qui leur permettra d'avoir des chemins suffisamment courts tout en fonctionnant. Donc ce serait your_project/node_modules/pkg_with_deep_deps/node_modules.
    • Je pense que requiredevrait être en mesure de les trouver correctement au moment de l'exécution. Vous aurez juste besoin de documenter clairement ce que vous avez modifié manuellement, pourquoi vous l'avez fait, et de conserver vos propres dépendances réelles représentées avec précision danspackage.json

Voici une discussion sur la question github qui développe ce problème en détail.

Peter Lyons
la source
Merci d'avoir souligné dedupe(je ne savais pas du tout à ce sujet) et --production( npm install -hn'a pas montré cette option)! L'utilisation d'une archive ZIP n'est malheureusement pas une option, voir un commentaire ci-dessus.
Borek Bernard
9
npm dedupe n'aplatira que les modules "communs" à l'emplacement commun le plus bas de la hiérarchie. Pas assez bon. Une bonne solution permettrait de "forcer à plat" toute la hiérarchie et éventuellement d'ignorer les répertoires test / doc. Une alternative serait que le nœud prenne en charge la lecture des modules directement à partir d'un fichier tar.
MMind
3
D'accord, une sorte de distribution "binaire" de paquets (ZIP, tarball, peu importe) serait très utile.
Borek Bernard
11

J'ai écrit un module de nœud appelé "npm-flatten" qui aplatit vos dépendances pour vous ici: https://www.npmjs.org/package/npm-flatten

Si vous cherchez une distribution, j'ai également écrit un package NuGet qui intégrera un environnement node.js complet à votre projet .NET ici: http://www.nuget.org/packages/NodeEnv/

Les commentaires seraient les bienvenus.

user3602171
la source
Cela a fonctionné pour nous. Nous avons obtenu des résultats encore meilleurs lorsque nous avons d'abord exécuté nmp dedup.
Shaun Rowan
1

Quelque chose qui m'a aidé a été de mapper un lecteur local à mon dossier Node.js:

net use n: \ computername \ c $ \ users \ myname \ documents \ node.js / persistent: oui

Avant: c: \ users \ myname \ documents \ node.js \ projectname (45 caractères) Après: n: \ projectname (14 caractères soit 31 caractères de moins)

Dans de nombreux cas, cela a permis d'installer certains modules.

Je dirai que je viens de redécouvrir ce problème aujourd'hui lorsque j'essayais de sauvegarder tout mon code sur une clé USB.

"C: \ Users \ mon nom \ Documents \ Node.js \ angular-phonecat \ node_modules \ karma \ node_modules \ chokidar \ node_modules \ anymatch \ node_modules \ micromatch \ node_modules \ regex-cache \ node_modules \ benchmarked \ node_modules \ file-reader node_modules \ extend-shallow \ benchmark \ fixtures est trop long. "

Même lorsque j'ai essayé de les sauvegarder en utilisant la lettre de lecteur N:, cela échouait toujours dans certains cas en raison de la longueur du chemin, mais c'était juste assez pour corriger celui ci-dessus.

Michael Blankenship
la source
1

1) Pendant la construction de la version, vous pouvez empêcher Visual Studio de scanner ces fichiers / dossiers en définissant les propriétés du dossier en tant que dossier caché (il suffit de le définir sur node_modules). Référence: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) Vous pouvez exclure des fichiers ou des dossiers publiés lors de l'empaquetage en incluant le nœud XML suivant dans le fichier CsProject.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
  <OutputPath>bin\</OutputPath>
   <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  <ExcludeFilesFromDeployment>File1.aspx;File2.aspx</ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>Folder1;Folder2</ExcludeFoldersFromDeployment>
</PropertyGroup>
David Chelliah
la source
1

J'ai trouvé une solution de Microsoft Node.js lignes directrices .

  • Commencez par un chemin court (par exemple c: \ src)
  • > npm install -g rimraf supprimer les fichiers qui dépassent max_path
  • > npm dedupe déplace les packages en double vers le niveau supérieur
  • > npm install -g flatten-packages déplace tous les packages vers le niveau supérieur, mais peut entraîner des problèmes de version
  • Mise à niveau vers npm@3laquelle tente de rendre la node_moduleshiérarchie des dossiers au maximum plate.
    • Livré avec Node v5
    • Ou… > npm install –g npm-windows-upgrade
zangw
la source
0

Ce n'est pas une solution appropriée, mais plutôt une solution lorsque vous êtes pressé, mais vous pouvez utiliser 7-Zip pour compresser votre dossier, déplacer le fichier compressé et le décompresser sans aucun problème.

Nous avons utilisé cette solution pour déployer une application Node.js où il n'était pas possible de faire une installation npm propre.

Jason
la source
Oui. C'est ce que je fais à chaque fois que j'ai besoin d'installer mangouste. Il contient du code natif et j'ai plusieurs versions plus récentes de Visual Studio = fail. Je pourrais simplement ouvrir VS, importer chaque fichier .sln échoué et le faire reconstruire. Mais il est juste plus facile de simplement XCOPY sur tout mon ensemble de dossiers node_modules \ mongoose si nécessaire (en regardant les versions bien sûr).
Michael Blankenship