Come distribuire l'applicazione Node.js con la struttura deep node_modules su Windows?


91

Ho riscontrato un problema curioso: apparentemente alcuni moduli Node.js hanno gerarchie di cartelle così profonde che il comando di copia di Windows (o PowerShell, Copy-Itemche è quello che stiamo effettivamente utilizzando) colpisce il famigerato errore "percorso troppo lungo" quando il percorso è superiore a 250 caratteri lunghi.

Ad esempio, questa è una gerarchia di cartelle che un singolo modulo Node può creare:

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

Sembra folle ma è una realtà con i moduli Node.

Dobbiamo usare il copia-incolla durante la distribuzione (non stiamo usando una piattaforma di destinazione "intelligente" come Heroku dove la distribuzione di Git sarebbe un'opzione) e questa è una grave limitazione su Windows.

Non esiste un comando npm o qualcosa che compatterebbe la node_modulescartella o forse includerebbe solo ciò che è effettivamente necessario in fase di esecuzione? (I moduli del nodo di solito contengono testcartelle ecc. Che non è necessario distribuire.) Altre idee su come aggirarlo? Sfortunatamente non usare Windows non è un'opzione :)


1
Il vostro progetto ha un package.jsoncon dependenciesset? In tal caso, potresti copiare senza node_modulese utilizzare npm in installo updatele dipendenze?
Jonathan Lonowski

4
@JonathanLonowski Il nostro ambiente di distribuzione non supporta l'esecuzione npm installnell'ambiente di destinazione, funziona creando un "pacchetto di distribuzione" localmente (fondamentalmente uno ZIP più alcuni metadati) che viene quindi caricato sulla macchina di destinazione, estratto lì e il gioco è fatto. Quindi devo includere node_modulesdirettamente.
Borek Bernard

Risposte:


24

npm v3 (rilasciato di recente) risolve questo problema appiattendo le dipendenze .. Controlla le note di rilascio qui in https://github.com/npm/npm/releases/tag/v3.0.0 nella flat flatsezione.

E l'ultimo commento su questo problema https://github.com/npm/npm/issues/3697


5
Le note di rilascio per flat flatsono ora sepolte in un'altra pagina. Ecco un link diretto: github.com/npm/npm/releases/tag/v3.0.0
John-Philip

Grazie @ John-Philip, aggiornato la risposta con il nuovo link
RameshVel

62

solo per aggiungere a questo ... un'altra cosa che mi ha aiutato è stato elencare tutti i moduli installati con npm ls.

che ti darà un albero di moduli e versioni ... da lì è abbastanza facile identificare quali sono i duplicati ... npm dedupenon ha fatto nulla per me. Non sono sicuro se sia un bug o cosa (Nodo v 10.16)

Quindi, una volta identificato un modulo duplicato, installalo nella directory root node_module utilizzando npm install dupemodule@1.2.3 --save-dev. La versione è importante.

dopo di che, ho cancellato la mia directory node_modules e ho fatto un nuovo file npm install.

Versione breve

  1. npm ls per ottenere un elenco di tutti i moduli installati.
  2. guarda attraverso quei moduli e identifica i moduli duplicati (la versione è importante )
  3. npm install module@version --save-dev per installare quei moduli nella directory root node_modules e aggiornare package.json.
  4. rmdir node_modules per eliminare la directory node_modules.
  5. npm install per estrarre una nuova copia delle tue dipendenze.

Una volta fatto ciò, tutto era molto più pulito.

Consiglio anche di commentare il file package.json per mostrare quali sono stati abbassati per appiattire l'albero node_modules.


Questo ha funzionato benissimo per me. Grazie! Perdona la mia ignoranza, ma perché i moduli non vengono sempre installati al livello più alto?
Caleb

2
@Caleb probabilmente perché moduli diversi si basano su versioni diverse dello stesso modulo, o forse solo perché è più facile ottenere solo ciò che è necessario, quindi scomporlo ... Non lo so.
Ben Lesh

7
Comunque, grazie per il suggerimento. Ho appena spazzato via circa 1700 file duplicati dal nostro progetto. Eliminare le cose è la mia parte preferita dell'essere uno sviluppatore! Inoltre, per chiunque stia cercando come aggiungere commenti a package.json, ecco la tua risposta: stackoverflow.com/questions/14221579/…
Caleb

github.com/joyent/node/issues/6960 node guy afferma che Windows è un cittadino di prima classe. Loro hanno detto. Ma hanno chiuso il problema e non è stato risolto nulla. Fortunati utenti di Windows.
vee

38

Non penso che ci sia una grande soluzione visti i tuoi vincoli, ma qui ci sono alcune cose che potrebbero aiutarti.

  • Prova a utilizzare npm dedupeper ottimizzare la gerarchia di directory che potrebbe abbreviare alcuni percorsi
  • Utilizzare npm install --productionper installare senza gli strumenti di sviluppo
  • Prendi alcune di quelle dipendenze profondamente nidificate (quanto basta per evitare il problema, suggerisco) e spostale nella directory node_modules di primo livello. Tienine traccia in modo da sapere quali sono le tue vere dipendenze e quali sono le soluzioni alternative per questo problema.
  • OPPURE spostare alcune di queste dipendenze profonde nella node_modulesdirectory più alta sotto your_project/node_modules/pkg_with_deep_depsche consentirà loro di avere percorsi abbastanza brevi ma funzioneranno comunque. Quindi questo sarebbeyour_project/node_modules/pkg_with_deep_deps/node_modules .
    • Penso che requiredovrebbe essere in grado di trovarli correttamente in fase di esecuzione. Dovrai solo documentare chiaramente cosa hai modificato manualmente, perché lo hai fatto e mantenere le tue vere dipendenze rappresentate accuratamente inpackage.json

Ecco una discussione sul problema di GitHub che elabora questo problema in dettaglio.


Grazie per aver sottolineato dedupe(non lo sapevo affatto) e --production( npm install -hnon mostrato questa opzione)! L'utilizzo di un archivio ZIP purtroppo non è un'opzione, vedere un commento sopra.
Borek Bernard

9
npm deduplica appiattirà solo i moduli "comuni" nella posizione comune più bassa nella gerarchia. Non buono abbastanza. Una soluzione adeguata permetterebbe di "forzare" l'intera gerarchia e possibilmente permetterebbe di ignorare le directory test / doc. Un'alternativa sarebbe che il nodo supportasse la lettura dei moduli direttamente da un file tar.
MMind

3
D'accordo, una sorta di distribuzione "binaria" di pacchetti (ZIP, tarball, qualunque cosa) sarebbe molto utile.
Borek Bernard

11

Ho scritto un modulo nodo chiamato "npm-flatten" che appiattisce le tue dipendenze qui: https://www.npmjs.org/package/npm-flatten

Se stai cercando una distrubtion, ho anche scritto un pacchetto NuGet che integrerà un ambiente node.js completo con il tuo progetto .NET qui: http://www.nuget.org/packages/NodeEnv/

Il feedback sarebbe il benvenuto.


Questo ha funzionato per noi. Abbiamo ottenuto risultati ancora migliori quando abbiamo eseguito prima la deduplicazione nmp.
Shaun Rowan

1

Qualcosa che mi ha aiutato è stato mappare un'unità locale alla mia cartella Node.js:

uso netto n: \ nomecomputer \ c $ \ utenti \ nomeutente \ documenti \ node.js / persistente: sì

Prima: c: \ users \ myname \ documents \ node.js \ projectname (45 caratteri) Dopo: n: \ projectname (14 caratteri che sono 31 caratteri in meno)

In molti casi questo ha permesso l'installazione di alcuni moduli.

Dirò che ho appena riscoperto questo problema oggi quando stavo tentando di eseguire il backup di tutto il mio codice su un'unità 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 \ extended-shallow \ benchmark \ fixtures è troppo lungo. "

Anche quando ho provato a eseguirne il backup utilizzando la lettera di unità N: in alcuni casi non è riuscito ancora a causa della lunghezza del percorso, ma è stato sufficiente per correggere quello sopra.


1

1) Durante la compilazione del rilascio, è possibile impedire a Visual Studio di eseguire la scansione di questi file / cartelle impostando le proprietà della cartella come cartella nascosta (è sufficiente impostarla su node_modules). Riferimento: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) È possibile escludere file o cartelle pubblicati durante la creazione del pacchetto includendo il seguente nodo XML nel file 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>

1

Ho trovato una soluzione da Microsoft Node.JS Linee Guida .

  • Inizia in un percorso breve (ad es. C: \ src)
  • > npm install -g rimraf eliminare i file che superano max_path
  • > npm dedupe sposta i pacchetti duplicati al livello superiore
  • > npm install -g flatten-packages sposta tutti i pacchetti al livello superiore, ma può causare problemi di controllo delle versioni
  • Aggiornamento a npm@3cui tenta di rendere la node_modulesgerarchia delle cartelle al massimo piatta.
    • Viene fornito con Node v5
    • O… > npm install –g npm-windows-upgrade

0

Questa non è una soluzione adeguata, piuttosto una soluzione quando si è di fretta, ma è possibile utilizzare 7-Zip per comprimere la cartella, spostare il file zippato e decomprimerlo senza problemi.

Abbiamo utilizzato quella soluzione per distribuire un'applicazione Node.js in cui non era possibile eseguire un'installazione npm pulita.


Sì. Questo è quello che faccio ogni volta che devo installare la mangusta. Ha un codice nativo e ho versioni multiple / più recenti di Visual Studio = fail. Potrei semplicemente aprire VS, inserire ogni file .sln fallito e ricostruirlo. Ma è solo più semplice XCOPY sull'intero set di cartelle node_modules \ mongoose se necessario (guardando le versioni ovviamente).
Michael Blankenship
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.