Devo controllare node_modules per git quando creo un'app node.js su Heroku?


368

Ho seguito le istruzioni di base per iniziare per node.js su Heroku qui:

https://devcenter.heroku.com/categories/nodejs

Queste istruzioni non ti dicono di creare un .gitignore node_modules, e quindi implicano che node_modules dovrebbe essere archiviato su git. Quando includo node_modules in git, la mia applicazione introduttiva è stata eseguita correttamente.

Quando ho seguito l'esempio più avanzato in:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server (fonte)

Mi ha detto di aggiungere node_modules a .gitignore. Quindi ho rimosso node_modules da git, l'ho aggiunto a .gitignore, quindi ri-distribuito. Questa volta la distribuzione non è riuscita in questo modo:

-----> Heroku receiving push
-----> Node.js app detected
-----> Resolving engine versions
       Using Node.js version: 0.8.2
       Using npm version: 1.0.106
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
       Error: npm doesn't work with node v0.8.2
       Required: node@0.4 || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Error: npm doesn't work with node v0.8.2
       Required: node@0.4 || 0.5 || 0.6
           at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
           at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
           at Module._compile (module.js:449:26)
           at Object.Module._extensions..js (module.js:467:10)
           at Module.load (module.js:356:32)
           at Function.Module._load (module.js:312:12)
           at Module.require (module.js:362:17)
           at require (module.js:378:17)
           at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
           at Module._compile (module.js:449:26)
       Dependencies installed
-----> Discovering process types
       Procfile declares types -> mongod, redis, web
-----> Compiled slug size is 5.0MB
-----> Launching... done, v9

L'esecuzione di "heroku ps" conferma l'incidente. Ok, nessun problema, quindi ho ripristinato la modifica, ho aggiunto node_module al repository git e l'ho rimosso da .gitignore. Tuttavia, anche dopo il ripristino, visualizzo ancora lo stesso messaggio di errore durante la distribuzione, ma ora l'applicazione funziona di nuovo correttamente. L'esecuzione di "heroku ps" mi dice che l'applicazione è in esecuzione.

Quindi la mia domanda è qual è il modo giusto per farlo? Includi node_modules o no? E perché dovrei ancora ricevere il messaggio di errore quando eseguo il rollback? Suppongo che il repository git sia in cattivo stato dal lato Heroku?


10
Sono il proprietario della lingua del nodo su Heroku e la risposta è semplice: No. Non node_modulesaccedere alle app Heroku.
hunterloft è il

@hunterloftis 'Non archiviare node_modules in ' o 'Non archiviare node_modules in '? Per chiarire, come proprietario della lingua del nodo su Heroku, vuoi che cariciamo i nostri interi node_modules tramite il nostro git push o no? Preferisco non a causa dello spreco di larghezza di banda e del fatto che Heroku li porterà sul backend della mia spinta git; tuttavia, ho dovuto modificare manualmente i file nei miei node_modules per fare in modo che Heroku caricasse la mia app. Ho dovuto quindi ignorare node_modules meno l'intero modulo che includeva il mio file modificato per farlo funzionare.
ZStoneDPM

Risposte:


400

Secondo aggiornamento

Le FAQ non sono più disponibili.

Dalla documentazione di shrinkwrap:

Se si desidera bloccare i byte specifici inclusi in un pacchetto, ad esempio per avere il 100% di fiducia nella capacità di riprodurre una distribuzione o compilazione, è necessario controllare le proprie dipendenze nel controllo del codice sorgente o perseguire altri meccanismi che possano verificare contenuti piuttosto che versioni.

Shannon e Steven ne hanno parlato prima, ma penso che dovrebbe essere parte della risposta accettata.


Aggiornare

La fonte elencata per la raccomandazione seguente è stata aggiornata . Non stanno più raccomandando il node_modulescommit della cartella.

Di solito no. Consenti a npm di risolvere le dipendenze per i tuoi pacchetti.

Per i pacchetti distribuiti, come siti Web e app, è necessario utilizzare npm shrinkwrap per bloccare l'intero albero delle dipendenze:

https://docs.npmjs.com/cli/shrinkwrap


Posta originale

Per riferimento, npm FAQ risponde chiaramente alla tua domanda:

Controlla node_modules in git per le cose che distribuisci, come siti Web e app. Non controllare node_modules in git per le librerie e i moduli destinati a essere riutilizzati. Utilizzare npm per gestire le dipendenze nel proprio ambiente di sviluppo, ma non negli script di distribuzione.

e per una buona logica per questo, leggi il post di Mikeal Rogers su questo .


Fonte: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git


13
Questo non è corretto - in realtà è una pessima idea. Se si sta sviluppando su Windows, quindi distribuendolo su Linux, sarà necessario ricostruire node_modules durante la distribuzione. Il che significa - caos. Molti file modificati e non ho idea di cosa fare.
user3690202

8
Questo non è possibile: alcuni dei nostri sviluppatori sviluppano il targeting per windows, altri il targeting per Linux, ma la stessa base di codice. L'approccio migliore sarebbe quello di non eseguire il commit dei moduli nodo - oops.
user3690202

7
@ user3690202 Sembra che tu abbia un caso molto non convenzionale, piuttosto che la norma, quindi dire "questo non è corretto" è probabilmente una sopravvalutazione. Detto questo, non sono sicuro di quale sia esattamente il tuo caso d'uso, ma non riesco a pensare a nessun motivo per utilizzare Windows e Linux per lo sviluppo. Attenersi a uno ed eseguire test o QA su tutte le piattaforme il proprio supporto.
Kostia,

16
@Kostia Il nostro caso d'uso è piuttosto comune. Siamo volontari e utilizziamo le nostre macchine, non quelle aziendali. Sembra una situazione abbastanza comune per l'open source.
Adam,

4
@Adam tangenzialmente, potresti aggiungere i file in fase di compilazione .gitignore? In questo modo, l'origine è in git e tutti i componenti compilati non lo sono, analogamente a come disto le outputcartelle sono gitignored in progetti grunt e gulp.
Kostia,

160

La mia più grande preoccupazione per non controllarenode_modules git è che 10 anni dopo, quando l'applicazione di produzione è ancora in uso, npm potrebbe non essere in circolazione. Oppure npm potrebbe essere danneggiato; oppure i manutentori potrebbero decidere di rimuovere la libreria su cui si fa affidamento dal loro repository; oppure la versione utilizzata potrebbe essere ritagliata.

Questo può essere mitigato con gestori di pronti contro termine come Maven, perché puoi sempre usare il tuo Nexus o Artifactory locale per mantenere un mirror con i pacchetti che usi. Per quanto ho capito, un tale sistema non esiste per npm. Lo stesso vale per i gestori di librerie lato client come Bower e Jamjs.

Se hai eseguito il commit dei file nel tuo repository git, puoi aggiornarli quando vuoi e hai il conforto di build ripetibili e la consapevolezza che la tua app non si romperà a causa di un'azione di terze parti.


10
Molte opzioni oggi: Nexus ( issues.sonatype.org/browse/NEXUS-5852 ), Artifactory ( jfrog.com/jira/browse/RTFACT-5143 ), npm_lazy ( github.com/mixu/npm_lazy ), npm-lazy- mirror ( npmjs.org/package/npm-lazy-mirror ), ecc.
Johann,

4
Citazione dalle domande frequenti su npmjs: "Se sei paranoico a seconda dell'ecosistema npm, dovresti eseguire un mirror npm privato o una cache privata". Penso che questo punti al problema a cui ti stai riferendo, giusto?
Taylan,


2
L'Npm non scomparirà durante la notte, quindi il vantaggio non si abbina davvero bene alla perdita di chiarezza nella cronologia del commit e alle dimensioni del pacchetto enorme. Se qualcuno sta sviluppando un'applicazione che pensa sarà ancora attiva tra 10 anni, è ragionevole aspettarsi che riceverà molta manutenzione lungo la strada. Il punto sulle interruzioni di NPM è un argomento molto migliore, anche se probabilmente ci sono modi migliori per mitigare questo rischio piuttosto che impegnarsi alla fonte.
Sam P

3
Anche un mese lungo la strada è pericoloso se non si commettono le proprie dipendenze (preferibilmente in un repository separato però). Come ho scoperto una mattina quando ho clonato uno dei miei progetti e ho scoperto che una versione del pacchetto era stata rimossa da npm. Ho trascorso mezza giornata a cambiare tutte le mie versioni delle dipendenze a cascata per far funzionare e ricostruire l'aggiornamento npm.
Richard,

67

Si dovrebbe non includere node_modules nella vostra .gitignore(o meglio si dovrebbe includere node_modules nella vostra fonte schierato a Heroku).

Se node_modules:

  • esiste quindi npm installutilizzerà quelle librerie vendute e ricostruirà eventuali dipendenze binarie con npm rebuild.
  • non esiste quindi npm installdovrà recuperare tutte le dipendenze stesse che aggiungono tempo al passo di compilazione della lumaca.

Vedi l'origine buildpack di Node.js per questi esatti passaggi

Tuttavia, l'errore originale sembra essere un'incompatibilità tra le versioni di npme node. È una buona idea impostare sempre esplicitamente la enginessezione del tuo in packages.jsonbase a questa guida per evitare questo tipo di situazioni:

{
  "name": "myapp",
  "version": "0.0.1",
  "engines": {
    "node": "0.8.x",
    "npm":  "1.1.x"
  }
}

Ciò garantirà la parità di sviluppo / produzione e ridurrà la probabilità di tali situazioni in futuro.


Grazie per l'aiuto Ryan. Ciò mi ha fatto superare l'errore della versione di npm ma ora non riesce durante la compilazione del pacchetto redis. Il messaggio di errore è "OSError: [Errno 2] Nessun file o directory: '/ Users / Jason / tastemade / tastebase / node_modules / redis-url / node_modules / redis / node_modules / hiredis / build'". Sembra che stia usando un percorso dalla mia casella locale sui server heroku. Ci sono alcuni file nei node_modules che devo aggiungere a .gitignore?
Jason Griffin,

Non sono sicuro di cosa stia succedendo con quella particolare libreria, ma in questo caso proverei a escludere node_modules da git e vedere se ciò aiuta (forzando npm a recuperare tutto da solo e garantendo un nuovo ambiente di build).
Ryan Daigle,

@RyanDaigle Best practice now (Nov 2013) raccomandato sia da npm ( npmjs.org/doc/… ) sia da heroku ( devcenter.heroku.com/articles/… ) è il check in node_modules per git. Aggiorneresti la tua risposta (dato che ha la fatturazione principale)?
Tim Diggins,

Spingendo su heroku otterrai l'output "-----> Caching nella directory node_modules per build future". Questo per abbreviare la futura compilazione di lumache.
ph3nx,

Ho un problema che il percorso del file node_modules è troppo lungo da impegnare. Git non troverà i file.
Codice Faraone,

22

Stavo per lasciare questo dopo questo commento: dovrei controllare node_modules per git quando creo un'app node.js su Heroku?

Ma StackOverflow lo stava formattando in modo strano. Se non hai macchine identiche e stai effettuando il check in node_modules, esegui un .gitignore sulle estensioni native. Il nostro .gitignore si presenta come:

# Ignore native extensions in the node_modules folder (things changed by npm rebuild)
node_modules/**/*.node
node_modules/**/*.o
node_modules/**/*.a
node_modules/**/*.mk
node_modules/**/*.gypi
node_modules/**/*.target
node_modules/**/.deps/
node_modules/**/build/Makefile
node_modules/**/**/build/Makefile

Prova questo controllando prima tutto e poi un altro sviluppatore procedi come segue:

rm -rf node_modules
git checkout -- node_modules
npm rebuild
git status

Assicurarsi che nessun file sia cambiato.


Ho appena aggiunto questo. Risolto il mio problema Il github di Windows continuava a bloccarsi cercando di andare oltre 7000+ file node_module: /
Batman

10

credo che npm install non dovrebbe funzionare in un ambiente di produzione. Ci sono diverse cose che possono andare storte: l'interruzione di npm, il download di dipendenze più recenti (il restringimento sembra aver risolto questo problema) sono due.

D'altro canto, node_modules non dovrebbe essere impegnato su Git. A parte le loro grandi dimensioni, gli impegni inclusi loro possono diventare fonte di distrazione.

Le migliori soluzioni sarebbero queste: npm installdovrebbero essere eseguite in un ambiente CI simile all'ambiente di produzione. Verranno eseguiti tutti i test e verrà creato un file di rilascio zippato che includerà tutte le dipendenze.


Perché dovresti avere un passaggio che gira su CI che non verrebbe eseguito come parte della tua distribuzione? Questo significa che non hai la parità tra i 2 sistemi! Come dice la risposta sopra - commetti la cartella semplicemente ignora le estensioni native, in questo modo sei coperto per cose come interruzioni
npm

1
Grazie per il tuo commento. Credo che i node_modules che girano nel tuo server di produzione dovrebbero essere generati da un'installazione npm, non da qualunque cosa gli sviluppatori abbiano commesso. La cartella node_modules di dev non corrisponde necessariamente al contenuto package.json.
user2468170

8

Ho usato sia il commit della cartella node_modules sia il restringimento. Entrambe le soluzioni non mi hanno reso felice.

In breve: commit node_modules aggiunge troppo rumore al repository.
E shrinkwrap.json non è facile da gestire e non vi è alcuna garanzia che un progetto ristretto verrà realizzato in pochi anni.

Ho scoperto che Mozilla stava usando un repository separato per uno dei loro progetti https://github.com/mozilla-b2g/gaia-node-modules

Quindi non mi ci è voluto molto per implementare questa idea in uno strumento CLI nodo https://github.com/bestander/npm-git-lock

Poco prima di ogni build aggiungi
npm-git-lock --repo [git@bitbucket.org: tuo / dedicato / node_modules / git / repository.git]

Calcolerà l'hash di package.json e verificherà il contenuto di node_modules da un repository remoto oppure, se si tratta di una prima build per questo package.json, eseguirà una pulizia npm installe invierà i risultati al repository remoto.


5

Ciò che ha funzionato per me è stato l'aggiunta esplicita di una versione npm a package.json ("npm": "1.1.x") e NON il controllo in node_modules per git. La distribuzione potrebbe essere più lenta (poiché scarica i pacchetti ogni volta), ma non sono riuscito a compilare i pacchetti quando sono stati archiviati. Heroku stava cercando i file che esistevano solo nella mia casella locale.


Se ritieni che la mia risposta sia stata quella corretta, per favore accettala? Grazie!
Ryan Daigle,

Nel caso in cui questo sia ancora in discussione, darei un'occhiata a questo post di StackOverflow che è quasi un duplicato della tua domanda sopra: stackoverflow.com/questions/11459733/… Fondamentalmente, sembra che la convenzione sia di controllare in node_modules, e gestire le versioni di tali moduli localmente. Sembra abbastanza ragionevole, e forse la spiegazione più succinta è questa: mikealrogers.com/posts/nodemodules-in-git.html Buona fortuna!
Warriorpostman,

3

Invece di archiviare node_modules, crea un file package.json per la tua app.

Il file package.json specifica le dipendenze dell'applicazione. Heroku può quindi dire a npm di installare tutte queste dipendenze. L'esercitazione a cui si è collegati contiene una sezione sui file package.json.


Ho un package.json. Ha il seguente: {"name": "node-example", "version": "0.0.1", "dependencies": {"express": "2.5.x", "redis-url": "0.1. 0 "," mongodb ":"> = 0.9.9 "}," motori ": {" nodo ":" 0.8.x "}}
Jason Griffin,

Ho fatto sulla mia casella locale per creare la directory node_modules. È quello che ho fatto il check-in, quindi rimosso, quindi aggiunto di nuovo.
Jason Griffin,

Dopo aver esaminato maggiormente il tutorial, sembra che stiano commettendo node_modules. In tal caso, non sono sicuro se esiste un modo per non eseguire il commit di node_modules. Siamo spiacenti
matzahboy il

3

Sto usando questa soluzione:

  1. Crea un repository separato che contiene node_modules. Se si dispone di moduli nativi che devono essere compilati per una piattaforma specifica, creare un repository separato per ciascuna piattaforma.
  2. Allegare questi repository al repository del progetto con git submodule:

git submodule add .../your_project_node_modules_windows.git node_modules_windows

git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64

  1. Crea un collegamento dalla piattaforma specifica node_modulesalla node_modulesdirectory e aggiungi node_modulesa.gitignore .
  2. Corri npm install.
  3. Apporta modifiche al repository del sottomodulo.
  4. Apporta le modifiche al repository del tuo progetto.

Quindi puoi facilmente passare node_modulesda una piattaforma all'altra (ad esempio se stai sviluppando su OS X e eseguendo la distribuzione su Linux).


3

Da https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html :

Modifica: il link originale era questo ma ora è morto. Grazie @ Flavio per averlo segnalato.

Ricapitolando.

  • Controlla solo node_modules per le applicazioni che distribuisci, non i pacchetti riutilizzabili che gestisci.
  • Tutte le dipendenze compilate dovrebbero avere il loro sorgente registrato, non le destinazioni di compilazione, e dovrebbero essere ricostruite $ npm al momento della distribuzione.

La mia parte preferita:

Tutti voi che avete aggiunto node_modules al vostro gitignore, rimuovete quella merda, oggi è un artefatto di un'era che siamo tutti troppo felici di lasciarci alle spalle. L'era dei moduli globali è morta.


Il sito che hai collegato sembra essere scaduto e ora pieno di pubblicità truffe. Vorrei che quelle pubblicità fossero "artefatti di un'era che saremmo tutti troppo felici di lasciarci alle spalle".
Flavio Copes

1
@FlavioCopes Aggiornato la mia risposta con il link da Wayback Machine.
Benjamin Crouzier,

2

http://nodejs.org/api/modules.html

[...] il nodo inizia nella directory principale del modulo corrente e aggiunge /node_modulese tenta di caricare il modulo da quella posizione.

Se non viene trovato lì, si sposta nella directory principale e così via , fino a quando non viene raggiunta la radice dell'albero.

Se stai realizzando i tuoi moduli specifici per la tua app, puoi tenerli ( e solo quelli ) in quelli della tua app /node_modules. E sposta tutte le altre dipendenze nella directory principale.

Questo caso d'uso è davvero fantastico, ti consente di mantenere i moduli creati appositamente per la tua app perfettamente con la tua app e non ingombra l'app con dipendenze che possono essere installate in seguito.


1

scenario 1:

Uno scenario: usi un pacchetto che viene rimosso da npm. Se hai tutti i moduli nella cartella node_modules, non sarà un problema per te. Se hai solo il nome del pacchetto in package.json, non puoi più ottenerlo. Se un pacchetto ha meno di 24 ore, è possibile rimuoverlo facilmente da npm. Se ha più di 24 ore, è necessario contattarli. Ma:

Se contatta l'assistenza, controlleranno se la rimozione di quella versione del pacchetto interromperà qualsiasi altra installazione. In tal caso, non lo rimuoveremo.

leggi di più

Quindi le possibilità per questo sono basse, ma c'è lo scenario 2 ...


scenario 2:

Un altro scenario in cui questo è il caso: sviluppi una versione aziendale del tuo software o un software molto importante e scrivi nel tuo package.json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Si utilizza il metodo function1(x)di quel pacchetto.

Ora gli sviluppatori di studpid-pacchetto di rinominare il metodo function1(x)di function2(x)e fanno un guasto ... Cambiano la versione del loro pacchetto da 1.0.1a 1.1.0. Questo è un problema perché quando chiami npm installla prossima volta, accetti la versione 1.1.0perché hai usato la tilde ("studpid-package": "~1.0.1" ).

La chiamata function1(x)può causare errori e problemi ora.


Il push dell'intera cartella node_modules (spesso più di 100 MB) nel repository, ti costerà spazio di memoria. Pochi kb (solo package.json) rispetto a centinaia di MB (package.json e node_modules) ... Pensaci.

Potresti farlo / dovresti pensarci se:

  • il software è molto importante.

  • ti costa denaro quando qualcosa fallisce.

  • non ti fidi del registro npm. npm è centralizzato e potrebbe teoricamente essere chiuso.

Non è necessario pubblicare la cartella node_modules nel 99,9% dei casi se:

  • sviluppi un software solo per te stesso.

  • hai programmato qualcosa e vuoi solo pubblicare il risultato su GitHub perché qualcun altro potrebbe essere interessato a questo.


Se non si desidera che node_modules sia nel proprio repository, è sufficiente creare un .gitignorefile e aggiungere la riga node_modules.

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.