2012-07-01 15 views
45

Ho diverse app nel nodo che condividono tutti i moduli che ho scritto. Questi moduli non sono disponibili tramite npm. Mi piacerebbe essere in grado di condividere liberamente tra le app, ma non voglio copiare le directory, né affidarmi a Git per farlo. E non sono molto bravo nell'usare i link simbolici per fare questo.Come condividere il codice tra le app node.js?

Vorrei organizzare le directory di qualcosa di simile:

app1 
server.js 
node_modules 
    (public modules from npm needed for app1) 
lib 
    (my own modules specific to app1) 

app2 
server.js 
node_modules 
    (public modules from npm needed for app2) 
lib 
    (my own modules specific to app2) 

shared_lib 
(my own modules that are used in both app1 and app2) 

Il problema che sto vedendo è che i moduli in shared_lib sembrano confondersi su dove trovare i moduli che saranno nelle node_modules directory di qualsiasi app in cui sono in esecuzione. Almeno penso che questo sia il problema.

Quindi .... qual è un buon modo per fare ciò che evita di avere duplicati di file? (nota che non mi importa di duplicati di cose in node_modules, dal momento che quelli non sono il mio codice, non li controllo in Git, ecc.)

risposta

15

Ho questo funzionamento avendo node_modules cartelle a diversi livelli - il nodo poi attraversa automaticamente verso l'alto fino a trovare il modulo.

Nota non devi pubblicare per NPM di avere un modulo all'interno di node_modules - basta usare:

"private": true 

All'interno di ciascuna delle vostre package.json file privati ​​- per il vostro progetto avrei il seguente:

app1 
server.js 
node_modules 
    (public modules from npm needed for app1) 
    (private modules locally needed for app1) 

app2 
server.js 
node_modules 
    (public modules from npm needed for app2) 
    (private modules locally needed for app2) 

node_modules 
    (public modules from npm needed for app1 & app2) 
    (private modules locally for app1 & app2) 

Il punto è node.js ha un meccanismo per gestire questo già ed è fantastico. Basta combinarlo con il trucco "privato non su NPM" e sei a posto.

In breve:

require('somemodule') 

Da app A o B sarebbe cascata verso l'alto fino a quando non ha trovato il modulo - a prescindere se si viveva più in basso o più in alto. Infatti, questo consente di scambiare a caldo la posizione senza modificare alcuna delle istruzioni (...).

node.js module documentation

+3

Quando ho provato questo, non è stato possibile risolvere alcun modulo richiesto dai moduli condivisi. Nella tua struttura, sembra che la cartella node_modules più alta abbia sia moduli privati ​​(controllati nel controllo del codice sorgente) che pubblici (npm install'd - non registrati). Non cerco normalmente di controllare i moduli pubblici nel controllo del codice sorgente: come hai risolto questo problema? –

1

Se verifichi lo node.js docs, vedrai che Node.js comprende anche il formato di file package.json, almeno in modo scorrevole.

In sostanza, se si dispone di una directory chiamata foo, e in tale directory è un file package.json con la coppia chiave-valore: "main": "myCode.js", quindi se si tenta di require("foo") e trova questa directory con un file package.json dentro, lo farà quindi utilizzare foo/myCode.js per il modulo foo.

Così, con la struttura di directory, se ogni lib condiviso ha il proprio elenco con una tale un semplice package.json file di dentro, poi le applicazioni possono ottenere le librerie condivise da:

var lib1 = require('../shared_lib/lib1'); 
var lib2 = require('../shared_lib/lib2'); 

E che dovrebbero lavorare per entrambi di queste app.

4

basta utilizzare il percorso corretto nel vostro richiedono chiamare

Per esempio in server.js che sarebbero:

var moduleName = require (' ../ shared_lib/moduleName/module.js');

È importante sapere che non appena il percorso è preceduto da "/", "../" o "./", il percorso è relativo al file chiamante.

Per ulteriori informazioni sui nodi caricamento del modulo visita: http://nodejs.org/docs/latest/api/modules.html

+4

Ma se lo faccio, e poi quel modulo tenta di richiedere un modulo che viene da NPM, esso si confonde e dà gli errori. – rob

34

Nodo consiglia di utilizzare npm link per la creazione dei pacchetti propri Node.JS a livello locale e poi renderli disponibili ad altre applicazioni. È una semplice procedura in quattro fasi.

procedura tipica sarebbe quello di creare prima il pacchetto con la seguente struttura

hello 
    | index.js 
    | package.json 

tipica implementazione di questi file sarebbe indice

.js

exports.world = function() { 
    return('Hello World'); 
    } 

package.json

{ 
    "name": "hello", 
    "version": "0.0.1", 
    "private": true, 
    "main": "index.js", 
    "dependencies": { 
    }, 
    "engines": { 
    "node": "v0.6.x" 
    } 
    } 

'privato: true' assicura che NPM si rifiuterà di pubblicarlo nel repository. Questo è un modo per prevenire la pubblicazione accidentale di repository privati.

Passare alla directory principale della cartella dell'applicazione, eseguire il collegamento npm per collegare il file globalmente in modo che possa essere utilizzato in altri pacchetti.

Ora per utilizzare questo pacchetto in un altro app, dire ciao-mondo con la seguente struttura di directory

hello-world 
| app.js 

Passare alla cartella ciao-mondo e gestiscono

npm link hello 

Ora lo usano come qualsiasi altro pacchetto npm come

app.js

var http = require('http'); 
    var hello = require('hello'); 

    var server = http.createServer(function(req, res) { 
    res.writeHead(200); 
    res.end(hello.world()); 
    }); 
    server.listen(8080); 
+0

Come funziona quando si esegue la distribuzione in un ambiente PaaS come Heroku o Nodejitsu? –

+0

Il collegamento npm non funzionerà in un ambiente PaaS. Heroku onora i moduli del nodo che sono stati inseriti nel tuo codice. Quindi questa potrebbe essere un'opzione. – almypal

+0

Questo è ciò che non ottengo - se si esegue il deploy su Heroku da git, non si controlla il proprio node_modules. Inoltre, ciò implicherebbe che si copia il codice condiviso nella cartella node_modules prima di effettuare il check in. Che sembra ingombrante e incline a errori. O mi sta sfuggendo qualcosa? Grazie! –

1

Sì, è possibile fare riferimento shared_lib da app1, ma poi si incorrere in un problema se si desidera comprimere e distribuire app1 a qualche altro ambiente, come ad esempio un server Web su AWS.

In questo caso, è meglio installare i moduli in shared_lib in app1 e app2 utilizzando "npm install shared_lib/module". Installa inoltre tutte le dipendenze dei moduli shared_lib in app1 e app2 e gestisce conflitti/duplicati.

vedere questo: How to install a private NPM module without my own registry?

Problemi correlati