¿Cómo implementar la aplicación Node.js con una estructura profunda de node_modules en Windows?

91

Me encontré con un problema curioso: aparentemente, algunos módulos de Node.js tienen jerarquías de carpetas tan profundas que el comando de copia de Windows (o el de PowerShell, Copy-Itemque es lo que realmente estamos usando) llega al infame error de "ruta demasiado larga" cuando la ruta es superior a 250 caracteres de largo.

Por ejemplo, esta es una jerarquía de carpetas que puede crear un solo módulo de nodo:

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

Parece una locura pero es una realidad con los módulos de Node.

Necesitamos usar copiar y pegar durante la implementación (no estamos usando una plataforma de destino "inteligente" como Heroku donde la implementación de Git sería una opción) y esta es una limitación seria en Windows.

¿No hay un comando npm o algo que compacte la node_modulescarpeta o tal vez incluya solo lo que realmente es necesario en tiempo de ejecución? (Los módulos de nodo generalmente contienen testcarpetas, etc. que no necesitamos implementar). ¿Alguna otra idea de cómo solucionarlo? Desafortunadamente, no usar Windows no es una opción :)

Borek Bernard
fuente
1
¿Tu proyecto tiene un set package.jsoncon dependencies? Si es así, ¿podría copiar sin node_modulesy usar npm to installo updatelas dependencias?
Jonathan Lonowski
4
@JonathanLonowski Nuestro entorno de implementación no admite la ejecución npm installen el entorno de destino, funciona creando un "paquete de implementación" localmente (básicamente un ZIP más algunos metadatos) que luego se carga en la máquina de destino, se extrae allí y listo. Entonces necesito incluir node_modulesdirectamente.
Borek Bernard

Respuestas:

24

npm v3 (lanzado recientemente) resuelve este problema nivelando las dependencias. Consulte las notas de la versión aquí en https://github.com/npm/npm/releases/tag/v3.0.0 en la flat flatsección.

Y el último comentario sobre este tema https://github.com/npm/npm/issues/3697

RameshVel
fuente
5
Las notas de la versión de flat flatahora están enterradas en otra página. Aquí hay un enlace directo: github.com/npm/npm/releases/tag/v3.0.0
John-Philip
Gracias @ John-Philip, actualizó la respuesta con el nuevo enlace
RameshVel
62

solo para agregar a esto ... otra cosa que me ayudó fue enumerar todos los módulos instalados con npm ls.

lo que le dará un árbol de módulos y versiones ... a partir de ahí es bastante fácil identificar cuáles son duplicados ... npm dedupeno hizo nada por mí. No estoy seguro si eso es un error o qué (Nodo v 10.16)

Entonces, una vez que identifique un módulo duplicado, instálelo en el directorio raíz node_module usando npm install [email protected] --save-dev. La versión es importante.

después de eso, borré mi directorio node_modules e hice un nuevo npm install.

Version corta

  1. npm ls para obtener una lista de todos los módulos instalados.
  2. revisar esos módulos e identificar módulos duplicados (la versión es importante )
  3. npm install module@version --save-dev para instalar esos módulos en el directorio raíz node_modules y actualizar package.json.
  4. rmdir node_modules para eliminar el directorio node_modules.
  5. npm install para extraer una copia nueva de sus dependencias.

Una vez que hice eso, todo quedó mucho más limpio.

También recomiendo comentar su archivo package.json para mostrar cuáles fueron eliminados para aplanar el árbol node_modules.

Ben Lesh
fuente
Esto funciono muy bien para mi. ¡Gracias! Perdone mi ignorancia, pero ¿por qué no siempre se instalan los módulos en el nivel superior?
Caleb
2
@Caleb probablemente porque diferentes módulos se basan en diferentes versiones del mismo módulo, o tal vez simplemente porque es más fácil obtener lo que se necesita y luego factorizarlo ... No sé.
Ben Lesh
7
Independientemente, gracias por el dato. Acabo de perder unos 1700 archivos duplicados de nuestro proyecto. ¡Eliminar cosas es mi parte favorita de ser desarrollador! Además, para cualquiera que esté buscando cómo agregar comentarios a package.json, aquí está su respuesta: stackoverflow.com/questions/14221579/…
Caleb
github.com/joyent/node/issues/6960 node guy dice que Windows es un ciudadano de primera clase. Ellos dijeron. Pero cerraron el problema y no se solucionó nada. Usuarios afortunados de Windows.
vee
38

No creo que haya ninguna gran solución dadas sus limitaciones, pero aquí hay algunas cosas que pueden ayudar.

  • Intente usar npm dedupepara optimizar la jerarquía de su directorio, lo que puede acortar algunas rutas
  • Úselo npm install --productionpara instalar sin las herramientas de desarrollo
  • Tome algunas de esas dependencias profundamente anidadas (lo suficiente para evitar el problema, sugiero) y muévalas al directorio node_modules de nivel superior. Simplemente realice un seguimiento de ellos para saber cuáles son sus verdaderas dependencias y cuáles son soluciones para este problema.
  • O mueva algunas de esas dependencias profundas al node_modulesdirectorio más alto debajo your_project/node_modules/pkg_with_deep_depsque les permitirá tener rutas lo suficientemente cortas pero aún funcionar. Entonces esto sería your_project/node_modules/pkg_with_deep_deps/node_modules.
    • Creo que requiredebería poder encontrarlos correctamente en tiempo de ejecución. Solo necesitará documentar claramente lo que ha cambiado manualmente, por qué lo ha hecho y mantener sus propias dependencias reales representadas con precisión enpackage.json

Aquí hay una discusión sobre el tema de github que elabora este problema en detalle.

Peter Lyons
fuente
¡Gracias por señalar dedupe(no sabía nada) y --production( npm install -hno mostró esta opción)! Desafortunadamente, usar un archivo ZIP no es una opción, vea un comentario arriba.
Borek Bernard
9
npm dedupe solo aplanará los módulos "comunes" a la ubicación común más baja en la jerarquía. No es suficiente. Una solución adecuada permitiría "forzar el plano" de toda la jerarquía y posiblemente permitir ignorar los directorios test / doc. Una alternativa sería que el nodo admita la lectura de módulos directamente desde un archivo tar.
MMind
3
De acuerdo, algún tipo de distribución "binaria" de paquetes (ZIP, tarball, lo que sea) sería muy útil.
Borek Bernard
11

Escribí un módulo de nodo llamado "npm-flatten" que aplana sus dependencias aquí: https://www.npmjs.org/package/npm-flatten

Si está buscando una distribución, también escribí un paquete NuGet que integrará un entorno node.js completo con su proyecto .NET aquí: http://www.nuget.org/packages/NodeEnv/

Sus comentarios serán bienvenidos.

usuario3602171
fuente
Esto funcionó para nosotros. Tuvimos incluso mejores resultados cuando ejecutamos nmp dedup primero.
Shaun Rowan
1

Algo que me ayudó fue asignar una unidad local a mi carpeta Node.js:

uso neto n: \ computername \ c $ \ users \ myname \ documents \ node.js / persistent: sí

Antes: c: \ users \ myname \ documents \ node.js \ projectname (45 caracteres) Después: n: \ projectname (14 caracteres que son 31 caracteres menos)

En muchos casos esto permitió instalar algunos módulos.

Diré que acabo de redescubrir este problema hoy cuando intentaba hacer una copia de seguridad de todo mi código en una unidad USB.

"C: \ Users \ myname \ 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 es demasiado largo ".

Incluso cuando traté de hacer una copia de seguridad con la letra de unidad N: todavía fallaba en algunos casos debido a la longitud de la ruta, pero fue suficiente para arreglar el anterior.

Michael Blankenship
fuente
1

1) Durante la compilación de la versión, puede evitar que Visual Studio escanee estos archivos / carpetas configurando las propiedades de la carpeta como una carpeta oculta (SOLO configúrelo en node_modules). Referencia: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) Puede excluir archivos o carpetas que se publican durante el empaquetado al incluir el siguiente nodo XML en el archivo 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
fuente
1

He encontrado una solución a partir de Microsoft Node.js Directrices .

  • Comience en una ruta corta (por ejemplo, c: \ src)
  • > npm install -g rimraf eliminar archivos que excedan max_path
  • > npm dedupe mueve paquetes duplicados al nivel superior
  • > npm install -g flatten-packages mueve todos los paquetes al nivel superior, pero puede causar problemas de versiones
  • Actualización a la npm@3que se intenta hacer elnode_modules jerarquía de carpetas sea máximamente plana.
    • Se envía con Node v5
    • O… > npm install –g npm-windows-upgrade
zangw
fuente
0

Esta no es una solución adecuada, sino más bien una solución cuando tiene prisa, pero puede usar 7-Zip para comprimir su carpeta, mover el archivo comprimido y descomprimirlo sin ningún problema.

Usamos esa solución para implementar una aplicación Node.js donde no era posible hacer una instalación npm limpia.

Jason
fuente
Sí. Esto es lo que hago cada vez que necesito instalar mongoose. Tiene código nativo y tengo múltiples / nuevas versiones de Visual Studio = fail. Podría abrir VS, traer cada archivo .sln fallido y reconstruirlo. Pero es más fácil simplemente XCOPY en todo mi conjunto de carpetas node_modules \ mongoose según sea necesario (viendo versiones, por supuesto).
Michael Blankenship