Os caminhos de arquivo do Windows npm do nó são muito longos para instalar pacotes

87

Situação

Quero usar o gulp e as cadeias de ferramentas de front-end relacionadas em ambientes de desenvolvimento hospedados no Windows. Eu estou batendo uma parede tentando usar plug-ins gulp como o Browser-Sync, porque o gráfico da pasta node_modules se espalha tornando os caminhos de arquivo do Windows muito longos para copiar os arquivos. Eu gostaria de uma abordagem pragmática para lidar com esse problema agora no Windows, independentemente do que a comunidade do Node possa ou não fornecer para melhorar a usabilidade do npm no Windows no futuro.

2 perguntas

  1. Existe um fluxo de trabalho npm para Windows que funciona da maneira pretendida? "execute o comando e a instalação dos arquivos" (por exemplo, comparável a npm no OSX, npm no Linux, ruby ​​gems ou mesmo nuget) Eu não quero mexer com um monte de edições manuais de arquivos, links simbólicos, etc. toda vez que eu uso npm no Windows.

  2. Existe um fluxo de trabalho Cygwin estável e bem documentado para npm e execução de nó para contornar os limites de caminho de arquivo da API do Windows?

Detalhes sangrentos listados abaixo ...

Problema geral

  • A execução do npm install a partir de um prompt de comando padrão do Windows falha em hierarquias node_modules profundamente aninhadas.
  • De acordo com o thread de repositório do github de Joyent, esse é um problema reconhecido, sem soluções alternativas palatáveis ​​para desenvolvedores em ambientes centrados no Windows. (É mesmo ? )
  • O kernel do NT suporta comprimentos de caminho de arquivo de até 32.767 caracteres.
  • MAXPATH da API do Windows é limitado a 260 caracteres.
  • A API do Windows lida com operações de arquivo para todos os principais shells do Windows e outros enfeites, incluindo: Explorer, CMD, Powershell, MYSgit bash, etc. ( MS realmente? Há quanto tempo o NTFS existe? )
  • Cygwin oferece suporte a caminhos de arquivo longos, mas npm.cmd não funciona imediatamente devido à formatação crlf. Eu tentei a transformação DOS2Unix no npm para fazê-la funcionar com o Cygwin, mas parece haver outros problemas com isso.

Meu hack atual

  • Crie uma pasta "n" como uma área de teste na raiz de C: \, porque isso encurta o caminho da minha pasta.
  • Execute o npm dentro da pasta "n" para instalar os módulos de acordo com as necessidades.
  • Abra o Cygwin e use cp para copiar a pasta node_modules em um projeto de destino.
  • Enxágue e repita quando as dependências mudarem ou quando eu precisar ativar um novo projeto.

Outras soluções alternativas desagradáveis

Links simbólicos podem ser usados ​​para encurtar caminhos de arquivo, mas esses são hacks malucos. Conforme o ecossistema npm cresce, as cadeias de dependência aninhadas se tornam muito longas e essa solução alternativa se torna inutilizável.

Adicionar TODAS as dependências ao arquivo package.json da pasta raiz foi mencionado em um tópico que encontrei. Embora essa abordagem aplaine a estrutura de pastas e evite o carregamento de módulos duplicados, essa solução alternativa parece pouco natural. Ele também mata a usabilidade, durabilidade e produtividade do npm, porque você tem que mexer com arquivos e pastas pós-instalação manualmente ou com alguns scripts hacky. A abordagem também é vulnerável ao mesmo destino que a abordagem de Links Simbólicos pode eventualmente sofrer.

Allan McLemore
fonte
Quase pensei que tinha resolvido. Eu coloquei o Cygwin funcionando com o npm executando dos2unix util nos 2 arquivos a seguir: npm.cmd e npm
Allan McLemore
As limitações de caminho da API do Windows tornam o npm inutilizável, porque alguns módulos npm usam o Visual Studio para criar arquivos. Este é o erro que recebo quando I npm Browser-Sync: C: \ Program Files (x86) \ MSBuild \ Microsoft.Cpp \ v4.0 \ V120 \ Microsoft.CppBuild.targets (301,5): erro MS B3491: Pode não grava linhas no arquivo "Release \ obj \ validation \ validation.tlog \ validation.lastbuilds tate". O caminho especificado, o nome do arquivo ou ambos são muito longos. O nome completo do arquivo deve ter menos de 260 caracteres e o nome do diretório deve ter menos de 248 caracteres.
Allan McLemore
Posso ter uma abordagem de "puxar taffy" para carregar os módulos de nó com npm no Windows. Isso envolve algumas rodadas do seguinte: npm install, npm dedupe, npm shrink e rm -r node_modules. Fazer isso repetidamente parece acertar os caminhos de arquivos longos até certo ponto, mas é como puxar o caramelo (por exemplo, não é feito antes de terminar). Alguém codificou isso ou escreveu uma ferramenta automatizada para torná-lo mais chave na mão?
Allan McLemore
Falando em "scripts hacky", escrevi um que não acho TERRIVELMENTE hacky. Eu criei uma ferramenta chamada fenestrate que você pode usar para nivelar programaticamente a estrutura de diretório de seus módulos após a instalação. Você pode instalá-lo como um gancho de pós-instalação do npm global.
zetlen
2
@yoneal Para uso pessoal e para começar rapidamente, o fenestrate deve percorrer recursivamente sua pasta node_modules, portanto, você não deve precisar executá-lo manualmente em dependências profundas. No entanto, seria ótimo bifurcar essas dependências - acho que muitos módulos bifurcados com configurações simples de fenestrate enviariam uma ótima mensagem para os mantenedores do npm.
zetlen

Respostas:

58

O problema com pastas profundamente aninhadas no Windows foi resolvido principalmente a partir da versão npm 3.x.

De acordo com o npm:

.npm @ 3 torna a instalação "maximamente plana" elevando tudo o que pode para os node_modules de nível superior. Isso significa que o aninhamento ocorre apenas em conflitos e, como tal, as árvores nunca devem ficar muito profundas. Como tal, a limitação do comprimento do caminho do Windows não deve ser executada.

Acabei de instalar o npm 3.1.0e testei em um pacote que estava gerando o The specified path, file name, or both are too longerro temido .

O problema foi embora.

Você pode obter as compilações de npm mais recentes aqui: lançamentos de npm

biofractal
fonte
4
Também tive sucesso com a atualização do npm 3.x na máquina Windows. Plugue sem vergonha: escrevi um artigo sobre o npm 3 no Windows triplet.fi/blog/…
Tx3
21

O Windows 8.1 e 10 têm a opção de aumentar o limite de caminho do Win32:

  • Abra o Editor de Política de Grupo (pressione Windows+ Re digite gpedit.msce pressione Enter)
  • Navegue até o seguinte diretório: Local Computer Policy\Computer Configuration\Administrative Templates\System\Filesystem
  • Clique duas vezes na opção Habilitar caminhos longos Win32 e habilite-a.

insira a descrição da imagem aqui

Marcelo Mason
fonte
a opção não estava disponível para mim, e fwiw, eu atualizei do win 7 pro, então essa é uma causa possível
Evan Morrison
@EvanMorrison "Filesystem \ NTFS \ Enable NTFS long path" foi renomeado para "FileSystem \ Enable Win32 long path" em compilações win10 posteriores. Eu atualizei a resposta para referência futura.
Marcelo Mason
1
alguma ideia para Win Server 2012 R2
sairfan
12

Esta é uma solução alternativa.

Existem alguns módulos de nó que simplificam suas dependências para você.
Os links estão aqui:

O que esses módulos estão fazendo também pode ser feito manualmente. Esta é a única solução real existente até agora, ou seja, ter todos os seus módulos em um único nível, exigindo uns dos outros, em vez de todos terem cópias privadas de suas dependências aninhadas profundamente.

Amol M Kulkarni
fonte
10
Eu descobri que os pacotes planos são bem documentados e fáceis de usar.
StriplingWarrior de
3

Allan -

Do problema do github que você vinculou,

O npm adicionará dedupe-at-install-time por padrão. Isso é significativamente mais viável do que a mudança do sistema de módulo do Node, mas ainda não é exatamente trivial e envolve muitos retrabalhos de alguns padrões há muito estabelecidos.

Este está (finalmente) em andamento às npm, atendendo pelo nome multi-stage-install, e é direcionado para npm@3. npmForrest Norvell, líder de desenvolvimento, vai passar algum tempo executando no Windows no ano novo, então crie problemas relacionados ao Windows no npmrastreador de problemas < https://github.com/npm/npm/issues >

Sam Mikes
fonte
3

Eu tenho o mesmo problema. Achatar as dependências não é uma solução completa, pois você pode usar módulos que dependem de diferentes versões do mesmo módulo dependente. Descobri que o módulo gulp-run parou de funcionar após o achatamento (relacionado às suposições do módulo sobre diretórios bin / .bin, eu suspeito). Droga!

Há muita discussão sobre o problema, mas nenhuma solução à vista: https://github.com/joyent/node/issues/6960

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

Uma solução alternativa que está funcionando para mim é adicionar manualmente dependências que meu projeto não precisa explicitamente.

Se você quiser identificar quais pacotes estão causando problemas, achei o PathLengthChecker bastante útil. Basta extrair o EXE e executar a GUI ou o aplicativo de linha de comando. A outra maneira que descobri o problema é tentar compilar no Visual Studio, mas ele falha sem informar qual nome de diretório é muito longo.

Aqui está um exemplo de linha de comando da minha solução alternativa:

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

Eu voltei:

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

[recorte - havia 12 deles]

De acordo com o 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 com o npmconf - é o contêiner para todos os arquivos extensos que estão causando problemas. Precisamos do 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

Nenhum resultado - todos os arquivos estão dentro dos limites!

A advertência óbvia aqui é que ele funciona apenas uma vez por pacote - dependências em diferentes versões do mesmo módulo não podem ser instaladas no nível root node_modules porque o node não leva em conta as versões na estrutura de diretório.

Essa solução alternativa não é perfeita, mas resolve meus objetivos principais de fazer o nó funcionar no Windows e, uma vez que a resolução está correta no package.json, a solução alternativa funciona para outros desenvolvedores e constrói servidores sem qualquer problema manual ou global.

Stefan Mohr
fonte
2

Se você concordar em instalá-lo globalmente, isso pode ser uma solução alternativa:

Você pode ajustar o caminho onde o npm está instalando os módulos globais para algo muito curto (geralmente é:) c:\users\\{username}\AppData\Roaming\npm\npm_modulesque já leva muitos caracteres.

Para ajustá-lo, consulte aqui: Alterar o diretório de instalação global padrão para módulos node.js no Windows?

Se você ajustar para, por exemplo, c:\n\em alguns casos, pode resolver o problema.

gwildu
fonte
1

Isso é o que finalmente consertou para mim ...

Depois de instalar o gulp e receber erros, execute ... gulp

Quando você vir um pacote falhando, instale-o manualmente com --no-bin-link.

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

Onde {pacote} é o pacote que está tendo problemas.

Depois de tudo isso, estava recebendo um Erro no plugin 'gulp-notificar' Mensagem: não encontrado: notificar-enviar.

Isso ocorreu devido a um problema de plug-in com o Vagrant. Você pode desativar as notificações ..

export DISABLE_NOTIFIER=true;

Ou instale o plugin com o Vagrant .

Boa sorte .. Passei muito tempo nisso, mesmo depois de seguir as recomendações de muitas pessoas.

Brandon

user3310182
fonte
0

No Windows:

  1. Usando o Windows Explorer, navegue até a pasta compartilhada do vagrant (estou usando o scotchbox, por exemplo). C:\scotchbox/public/gulpProject
  2. Na barra de endereço da pasta, digite cmde pressioneEnter
  3. Faça sua instalação gulp npm install
Justis Matotoka
fonte
1
Evite copiar e colar a mesma resposta . Você deve sinalizar como duplicado. Além disso, não xingue em sua postagem.
Tunaki
0

npm install --no-bin-link. Você terá um achatado inteiro node_modules

Kenberkeley
fonte