Como implantar o aplicativo Node.js com estrutura profunda node_modules no Windows?

91

Eu me deparei com um problema curioso - aparentemente, alguns módulos Node.js têm hierarquias de pasta tão profundas que o comando de cópia do Windows (ou do PowerShell, Copy-Itemque é o que estamos realmente usando) atinge o erro infame "caminho muito longo" quando o caminho está acima de 250 chars long.

Por exemplo, esta é uma hierarquia de pastas que um único módulo Node pode criar:

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 loucura, mas é uma realidade com os módulos do Node.

Precisamos usar copiar e colar durante a implantação (não estamos usando uma plataforma de destino "inteligente" como Heroku, onde a implantação do Git seria uma opção) e essa é uma limitação séria no Windows.

Não existe um comando npm ou algo que compactaria a node_modulespasta ou talvez incluísse apenas o que é realmente necessário em tempo de execução? (Módulos de nó geralmente contêm testpastas etc. que não precisamos implantar.) Alguma outra ideia de como contornar isso? Não usar o Windows, infelizmente, não é uma opção :)

Borek Bernard
fonte
1
Seu projeto tem um conjunto package.jsoncom dependencies? Em caso afirmativo, você poderia copiar sem node_modulese usar o npm para installou updatenas dependências?
Jonathan Lonowski de
4
@JonathanLonowski Nosso ambiente de implantação não suporta a execução npm installno ambiente de destino, ele funciona criando um "pacote de implantação" localmente (basicamente um ZIP mais alguns metadados) que é então carregado para a máquina de destino, extraído lá e pronto. Portanto, preciso incluir node_modulesdiretamente.
Borek Bernard de

Respostas:

24

O npm v3 (lançado recentemente) resolve esse problema simplificando as dependências. Verifique as notas de versão aqui em https://github.com/npm/npm/releases/tag/v3.0.0 na flat flatseção.

E o último comentário sobre este assunto https://github.com/npm/npm/issues/3697

RameshVel
fonte
5
As notas de lançamento de flat flatagora estão enterradas em outra página. Aqui está um link direto: github.com/npm/npm/releases/tag/v3.0.0
John-Philip,
Obrigado @ John-Philip, atualizou a resposta com o novo link
RameshVel
62

só para adicionar a isso ... outra coisa que me ajudou foi listar todos os módulos instalados com npm ls.

que vai te dar uma árvore de módulos e versões ... a partir daí é muito fácil identificar quais são duplicatas ... npm dedupenão fez nada para mim. Não tenho certeza se isso é um bug ou o quê (Nó v 10.16)

Portanto, depois de identificar um módulo duplicado, instale-o no diretório root node_module usando npm install [email protected] --save-dev. A versão é importante.

depois disso, limpei meu diretório node_modules e fiz um novo npm install.

Versão curta

  1. npm ls para obter uma lista de todos os módulos instalados.
  2. examine esses módulos e identifique os módulos duplicados (a versão é importante )
  3. npm install module@version --save-dev para instalar esses módulos no diretório root node_modules e atualizar o package.json.
  4. rmdir node_modules para excluir o diretório node_modules.
  5. npm install para obter uma nova cópia de suas dependências.

Depois de fazer isso, tudo ficou muito mais limpo.

Também recomendo comentar seu arquivo package.json para mostrar quais foram reduzidos para nivelar a árvore node_modules.

Ben Lesh
fonte
Isso funcionou muito bem para mim. Obrigado! Perdoe minha ignorância, mas por que os módulos nem sempre são instalados no nível superior?
Caleb de
2
@Caleb provavelmente porque diferentes módulos dependem de diferentes versões do mesmo módulo, ou talvez apenas porque é mais fácil apenas obter o que é necessário e então fatorá-lo ... Não sei.
Ben Lesh
7
Apesar de tudo, obrigado pela dica. Acabei de eliminar cerca de 1700 arquivos duplicados de nosso projeto. Excluir coisas é minha parte favorita de ser um desenvolvedor! Além disso, para quem quer saber como adicionar comentários a package.json, aqui está sua resposta: stackoverflow.com/questions/14221579/…
Caleb
github.com/joyent/node/issues/6960 node guy diz que o Windows é um cidadão de primeira classe. Eles disseram. Mas eles resolveram o problema e nada consertou. Usuários sortudos do Windows.
vee
38

Não acho que haja uma grande solução, dadas as suas restrições, mas aqui estão algumas coisas que podem ajudar.

  • Tente usar npm dedupepara otimizar sua hierarquia de diretório, o que pode encurtar alguns caminhos
  • Use npm install --productionpara instalar sem as ferramentas de desenvolvimento
  • Pegue algumas dessas dependências profundamente aninhadas (apenas o suficiente para evitar o problema, eu sugiro) e mova-as para o diretório node_modules de nível superior. Basta controlá-los para saber quais são suas verdadeiras dependências e quais são as soluções alternativas para esse problema.
  • OU mova algumas dessas dependências profundas para o node_modulesdiretório mais alto abaixo, o your_project/node_modules/pkg_with_deep_depsque permitirá que tenham caminhos curtos o suficiente, mas ainda funcionem. Então isso seria your_project/node_modules/pkg_with_deep_deps/node_modules.
    • Eu acho que requiredeve ser capaz de encontrar esses corretamente em tempo de execução. Você só precisará documentar claramente o que alterou manualmente, por que o fez e manter suas próprias dependências verdadeiras representadas com precisão empackage.json

Aqui está uma discussão sobre o problema do github que aborda esse problema em detalhes.

Peter Lyons
fonte
Obrigado por apontar dedupe(não sabia sobre isso) e --production( npm install -hnão mostrei essa opção)! Usar um arquivo ZIP infelizmente não é uma opção, veja um comentário acima.
Borek Bernard de
9
npm dedupe apenas nivelará os módulos "comuns" para o local comum mais baixo na hierarquia. Não esta bom o suficiente. Uma solução apropriada permitiria "nivelar" toda a hierarquia e possivelmente permitir ignorar os diretórios test / doc. Uma alternativa seria que o nó suportasse a leitura de módulos diretamente de um arquivo tar.
MMind
3
Concordo, algum tipo de distribuição "binária" de pacotes (ZIP, tarball, qualquer) seria muito útil.
Borek Bernard
11

Eu escrevi um módulo de nó chamado "npm-flatten" que nivela suas dependências para você aqui: https://www.npmjs.org/package/npm-flatten

Se você está procurando uma distrubção, também escrevi um pacote NuGet que integrará um ambiente node.js completo com seu projeto .NET aqui: http://www.nuget.org/packages/NodeEnv/

O feedback seria bem-vindo.

user3602171
fonte
Isso funcionou para nós. Tivemos resultados ainda melhores quando executamos o nmp dedup primeiro.
Shaun Rowan
1

Algo que me ajudou foi mapear uma unidade local para minha pasta Node.js:

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

Antes: c: \ users \ myname \ documents \ node.js \ projectname (45 caracteres) Depois: n: \ projectname (14 caracteres, que são 31 caracteres a menos)

Em muitos casos, isso permitiu a instalação de alguns módulos.

Direi que redescobri esse problema hoje, quando estava tentando fazer backup de todo o meu código em uma unidade 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 é muito longo. "

Mesmo quando tentei fazer backup deles usando a letra da unidade N: ainda falhou em alguns casos devido ao comprimento do caminho, mas foi apenas o suficiente para corrigir o acima.

Michael Blankenship
fonte
1

1) Durante o lançamento do build, você pode evitar que o Visual Studio escaneie esses arquivos / pasta, definindo as propriedades da pasta como uma pasta Oculta (apenas defina-a como node_modules). Referência: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) Você pode excluir arquivos ou pastas que são publicados durante o empacotamento, incluindo o nó XML a seguir no arquivo 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
fonte
1

Eu encontrei uma solução de Diretrizes Microsoft Node.js .

  • Comece com um caminho curto (por exemplo, c: \ src)
  • > npm install -g rimraf apagar arquivos que excedam max_path
  • > npm dedupe move pacotes duplicados para o nível superior
  • > npm install -g flatten-packages move todos os pacotes para o nível superior, mas pode causar problemas de versão
  • Upgrade para o npm@3qual tenta tornar a node_moduleshierarquia da pasta maximamente plana.
    • É fornecido com o Node v5
    • Ou… > npm install –g npm-windows-upgrade
zangw
fonte
0

Esta não é uma solução adequada, e sim uma solução alternativa quando você está com pressa, mas você pode usar o 7-Zip para compactar sua pasta, mover o arquivo compactado e descompactá-lo sem nenhum problema.

Usamos essa solução para implantar um aplicativo Node.js onde não era possível fazer uma instalação limpa do npm.

Jason
fonte
Sim. Isso é o que eu faço sempre que preciso instalar o mangusto. Ele tem código nativo e eu tenho várias / versões mais recentes do Visual Studio = fail. Eu poderia simplesmente abrir o VS, trazer cada arquivo .sln com falha e reconstruí-lo. Mas é apenas mais fácil apenas executar XCOPY em todo o meu conjunto de pastas node_modules \ mongoose conforme necessário (assistindo às versões, é claro).
Michael Blankenship