Las rutas de archivo de Windows del nodo npm son demasiado largas para instalar paquetes

89

Situación

Quiero usar gulp y las cadenas de herramientas de front-end relacionadas en entornos de desarrollo alojados en Windows. Estoy golpeando una pared tratando de usar complementos de gulp como Browser-Sync, porque el gráfico de la carpeta node_modules se despliega haciendo que las rutas de los archivos de Windows sean demasiado largas para copiar los archivos. Me gustaría un enfoque pragmático para manejar este problema ahora mismo en Windows, independientemente de lo que la comunidad de Node pueda o no pueda proporcionar para mejorar la usabilidad de npm en Windows en el futuro.

2 preguntas

  1. ¿Existe un flujo de trabajo npm para Windows que simplemente funciona de la forma prevista? "ejecutar el comando y los archivos se instalan" (por ejemplo, comparable a npm en OSX, npm en Linux, ruby ​​gems o incluso nuget) No quiero jugar con un montón de ediciones manuales de archivos, enlaces simbólicos, etc. cada vez que uso npm en Windows.

  2. ¿Existe un flujo de trabajo Cygwin estable y bien documentado para la ejecución de npm y nodos para solucionar los límites de la ruta de archivo de la API de Windows?

Detalles sangrientos enumerados a continuación ...

Problema general

  • La ejecución de npm install desde un símbolo del sistema de Windows estándar falla en jerarquías de node_modules profundamente anidadas.
  • Según el subproceso de repositorio github de Joyent, este es un problema reconocido sin soluciones alternativas aceptables para los desarrolladores en entornos centrados en Windows. ( ¿De verdad? )
  • NT Kernel admite longitudes de ruta de archivo de hasta 32.767 caracteres.
  • El MAXPATH de la API de Windows está limitado a 260 caracteres.
  • La API de Windows maneja las operaciones de archivos para todos los shells principales de Windows y todo eso, incluyendo: Explorer, CMD, Powershell, MYSgit bash, etc. (¿ MS realmente? ¿Cuánto tiempo ha existido NTFS? )
  • Cygwin admite rutas de archivo largas, pero npm.cmd no funciona de inmediato debido al formato crlf. Probé la transformación DOS2Unix en npm para que funcione con Cygwin, pero parece que hay otros problemas con esto.

Mi truco actual

  • Cree una carpeta "n" como área de preparación en la raíz de C: \, porque esto acorta la ruta de mi carpeta.
  • Ejecute npm dentro de la carpeta "n" para instalar módulos para lo que necesite.
  • Inicie Cygwin y use cp para copiar la carpeta node_modules en un proyecto de destino.
  • Enjuague y repita cuando cambien las dependencias o cuando necesite poner en marcha un nuevo proyecto.

Otras soluciones alternativas desagradables

Los enlaces simbólicos se pueden utilizar para acortar las rutas de los archivos, pero estos son trucos complicados. A medida que crece el ecosistema npm, las cadenas de dependencia anidadas se volverán demasiado largas y esta solución se volverá inutilizable.

Agregar TODAS las dependencias al archivo package.json de la carpeta raíz se mencionó en un hilo que encontré. Aunque este enfoque aplanará la estructura de carpetas y evitará la carga de módulos duplicados, esta solución no parece natural. También mata la usabilidad, durabilidad y productividad de npm, porque tiene que jugar con archivos y carpetas después de la instalación, ya sea manualmente o con algunos scripts hacky. El enfoque también es vulnerable al mismo destino que el enfoque de Vínculos Simbólicos puede sufrir eventualmente.

Allan McLemore
fuente
Casi pensé que tenía esto resuelto. Obtuve a Cygwin trabajando con npm ejecutando dos2unix util en los siguientes 2 archivos: npm.cmd y npm
Allan McLemore
Las limitaciones de la ruta de la API de Windows hacen que npm sea inutilizable, porque algunos módulos npm usan Visual Studio para compilar archivos. Este es el error que recibo cuando npm Browser-Sync: C: \ Archivos de programa (x86) \ MSBuild \ Microsoft.Cpp \ v4.0 \ V120 \ Microsoft.CppBuild.targets (301,5): error MS B3491: podría no escribir líneas en el archivo "Release \ obj \ validation \ validation.tlog \ validation.lastbuilds tate". La ruta especificada, el nombre de archivo o ambos son demasiado largos. El nombre de archivo completo debe tener menos de 260 caracteres y el nombre del directorio debe tener menos de 248 caracteres.
Allan McLemore
Es posible que tenga un enfoque de "extracción de caramelo" para cargar módulos de nodo con npm en Windows. Implica algunas rondas de lo siguiente: npm install, npm dedupe, npm shrink y rm -r node_modules. Hacer esto repetidamente parece arreglar las rutas de archivo largas hasta cierto punto, pero es como sacar caramelo (p. Ej., No se hace hasta que haya terminado). ¿Alguien codificó esto o escribió una herramienta automatizada para hacer esto más llave en mano?
Allan McLemore
Hablando de "guiones hacky", escribí uno que no encuentro TERRIBLEMENTE hacky. Creé una herramienta llamada fenestrate que puede usar para aplanar programáticamente la estructura de directorios de sus módulos después de la instalación. Puede instalarlo como un enlace postinstall global npm.
zetlen
2
@yoneal Para uso personal y para comenzar rápidamente, fenestrate debe recorrer de forma recursiva su carpeta node_modules, por lo que no debería necesitar ejecutarlo manualmente en dependencias profundas. Sin embargo, sería genial bifurcar esas dependencias; creo que muchos módulos bifurcados con configuraciones simples de fenestrado enviarían un gran mensaje a los mantenedores de npm.
Zetlen

Respuestas:

58

El problema con las carpetas profundamente anidadas en Windows se ha resuelto principalmente a partir de la versión npm 3.x.

Según npm:

.npm @ 3 hace que la instalación sea "máximamente plana" elevando todo lo que puede al nivel superior node_modules. Esto significa que la anidación solo ocurre en conflictos y, como tal, los árboles nunca deben ser muy profundos. Como tal, la limitación de la longitud de la ruta de Windows no se debe ejecutar.

Acabo de instalar npm 3.1.0y lo probé en un paquete que arrojaba el temido The specified path, file name, or both are too longerror.

El problema desapareció.

Puede obtener las últimas compilaciones de npm desde aquí: lanzamientos de npm

biofractal
fuente
4
También tuve éxito con la actualización de npm 3.x en una máquina con Windows. Enchufe desvergonzado: escribí un artículo sobre npm 3 en Windows triplet.fi/blog/…
Tx3
21

Windows 8.1 y 10 tienen una opción para aumentar el límite de ruta de Win32:

  • Abra el Editor de políticas de grupo (presione Windows+ Ry escriba gpedit.mscy presione Enter)
  • Navegue al siguiente directorio: Local Computer Policy\Computer Configuration\Administrative Templates\System\Filesystem
  • Haga doble clic en la opción Habilitar rutas largas de Win32 y habilítela.

ingrese la descripción de la imagen aquí

Marcelo Mason
fuente
La opción no estaba disponible para mí, y fwiw, actualicé de Win 7 Pro, así que esa es una posible causa
Evan Morrison
@EvanMorrison "Sistema de archivos \ NTFS \ Habilitar rutas largas NTFS" fue renombrado a "Sistema de archivos \ Habilitar rutas largas Win32" en versiones posteriores de win10. Actualicé la respuesta para futuras referencias.
Marcelo Mason
1
cualquier idea para Win Server 2012 R2
sairfan
12

Esta es una solución alternativa.

Hay algunos módulos de nodo que aplanan sus dependencias por usted.
Los enlaces están aquí:

Lo que hacen estos módulos también se puede hacer manualmente. Esta es la única solución real que existe a partir de ahora, es decir, tener todos sus módulos en un solo nivel, requiriéndose unos a otros, en lugar de tener copias privadas de sus dependencias anidadas profundamente.

Amol M Kulkarni
fuente
10
Descubrí que los paquetes planos están bien documentados y son fáciles de usar.
StriplingWarrior
3

Allan -

Desde el problema de github que vinculó,

npm agregará dedupe-at-install-time de forma predeterminada. Esto es significativamente más factible que el cambio del sistema de módulos de Node, pero todavía no es exactamente trivial e implica una gran cantidad de reelaboración de algunos patrones arraigados desde hace mucho tiempo.

Esto (finalmente) está actualmente en proceso en npm, con el nombre multi-stage-install, y está dirigido a npm@3. npmEl líder de desarrollo, Forrest Norvell, pasará un tiempo ejecutándose en Windows el año nuevo, así que cree problemas relacionados con Windows en el npmrastreador de problemas < https://github.com/npm/npm/issues >

Sam Mikes
fuente
3

Tengo el mismo problema. Aplanar las dependencias no es una solución completa, ya que es posible que esté utilizando módulos que dependen de diferentes versiones del mismo módulo dependiente. Descubrí que el módulo gulp-run dejó de funcionar después de aplanar (relacionado con las suposiciones del módulo sobre los directorios bin / .bin, sospecho). ¡Maldita sea!

Hay mucha discusión sobre el problema, pero no hay una solución a la vista: https://github.com/joyent/node/issues/6960

https://github.com/npm/npm/issues/3697

Una solución que me funciona es agregar manualmente las dependencias que mi proyecto no necesita explícitamente.

Si desea identificar qué paquetes le están dando problemas, PathLengthChecker me resultó bastante útil. Simplemente extraiga el EXE y ejecute la GUI o la aplicación de línea de comandos. La otra forma en que descubrí el problema es intentar compilar en Visual Studio, pero falla sin decirle qué nombre de directorio es demasiado largo.

Aquí hay un ejemplo de línea de comando de mi solución:

mkdir c:\reallylongdirectorywillbreakinwindows
cd c:\reallylongdirectorywillbreakinwindows
npm init
npm install --save-dev grunt-bower-task
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

Regresé:

261: C: \ reallylongdirectorywillbreakinwindows \ node_modules \ grunt-bower-task \ node_modules \ bower \ node_modules \ update-notifier \ node_modules \ latest-version \ node_modules \ package-json \ no de_modules \ registration-url \ node_modules \ npmconf config-chain \ readme.markdown

[recorte - había 12 de ellos]

Según el comando npm ls :

└─┬ grunt-bower-task@0.4.0
  ├── async@0.1.22
  ├─┬ bower@1.3.12
  │ ├─┬ update-notifier@0.2.0
  │ │ ├─┬ latest-version@0.2.0
  │ │ │ └─┬ package-json@0.2.0
  │ │ │   └─┬ registry-url@0.1.1
  │ │ │     └─┬ npmconf@2.1.1
  │ │ │       ├─┬ once@1.3.1
  │ │ │       │ └── wrappy@1.0.1

Vamos con npmconf: es el contenedor de todos los archivos de gran tamaño que están causando problemas. Necesitamos npmconf 2.1.1.

npm install --save-dev npmconf@2.1.1
(now delete the node_modules directory - you may have to use Windows Explorer if you can't do it with rmdir /s)
npm install
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

Sin resultados: ¡todos los archivos están dentro de los límites!

La advertencia obvia aquí es que solo funciona una vez por paquete: las dependencias en diferentes versiones del mismo módulo no se pueden instalar en el nivel raíz node_modules porque el nodo no tiene en cuenta las versiones en la estructura del directorio.

Esta solución no es perfecta, pero resuelve mis objetivos principales de que el nodo funcione en Windows, y dado que la resolución es correcta en package.json, la solución funciona para otros desarrolladores y servidores de compilación sin ningún problema manual o global.

Stefan Mohr
fuente
2

Si está de acuerdo con instalarlo globalmente, esto podría ser una solución alternativa:

Puede ajustar la ruta donde npm está instalando los módulos globales a algo muy corto (generalmente lo es :) c:\users\\{username}\AppData\Roaming\npm\npm_modulesque ya toma muchos caracteres.

Para ajustarlo, consulte aquí: ¿ Cambiar el directorio de instalación global predeterminado para los módulos node.js en Windows?

Si lo ajusta, por ejemplo, c:\n\en algunos casos, podría resolver el problema.

gwildu
fuente
1

Esto es lo que finalmente lo arregló para mí ...

Después de instalar gulp y recibir errores, ejecute ... gulp

Cuando vea que un paquete falla, instálelo manualmente con --no-bin-link.

sudo npm install {package} --no-bin-link

Donde {paquete} es el paquete que tiene problemas.

Después de todo esto, recibí un error en el complemento 'gulp-notificar' Mensaje: no encontrado: notificar-enviar.

Esto se debió a un problema de complemento con Vagrant. Puede desactivar las notificaciones ...

export DISABLE_NOTIFIER=true;

O instale el complemento con Vagrant .

Mucha suerte ... Pasé mucho tiempo en esto, incluso después de seguir las recomendaciones de muchas personas.

Brandon

usuario3310182
fuente
0

En ventanas:

  1. Usando su explorador de Windows, navegue a su carpeta compartida vagabundo (estoy usando scotchbox por cierto) eg C:\scotchbox/public/gulpProject
  2. En la barra de direcciones de la carpeta, escriba cmdy presioneEnter
  3. Haz tu instalación gulp npm install
Justis Matotoka
fuente
1
Evite copiar y pegar la misma respuesta . En su lugar, debería marcar como duplicado. Además, no jure en su publicación.
Tunaki
0

npm install --no-bin-link. Tendrás todo un aplanado node_modules

Kenberkeley
fuente