Esistono diversi modi per affrontarlo, ognuno con i propri pro e contro:
require.main.filename
Da http://nodejs.org/api/modules.html :
Quando un file viene eseguito direttamente dal nodo, require.mainviene impostato su relativo module. Ciò significa che è possibile determinare se un file è stato eseguito direttamente mediante testrequire.main === module
Poiché modulefornisce una filenameproprietà (normalmente equivalente a __filename), il punto di ingresso dell'applicazione corrente può essere ottenuto controllando require.main.filename.
Quindi, se vuoi la directory di base per la tua app, puoi fare:
var path = require('path');
var appDir = path.dirname(require.main.filename);
Pro e contro
Funzionerà alla grande per la maggior parte del tempo, ma se stai eseguendo la tua app con un launcher come pm2 o eseguendo test moka , questo metodo fallirà.
global.X
Il nodo ha un oggetto dello spazio dei nomi globale chiamato global: tutto ciò che si collega a questo oggetto sarà disponibile ovunque nell'app. Quindi, nel tuo index.js(o app.jscome si chiama il tuo file principale dell'app), puoi semplicemente definire una variabile globale:
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
Pro e contro
Funziona costantemente ma devi fare affidamento su una variabile globale, il che significa che non puoi riutilizzare facilmente componenti / ecc.
process.cwd ()
Ciò restituisce la directory di lavoro corrente. Non affidabile a tutti, come è del tutto dipende da ciò che directory il processo è stato avviato da :
$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir
app-root-path
Per risolvere questo problema, ho creato un modulo nodo chiamato app-root-path . L'uso è semplice:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
Il modulo percorso root dell'app utilizza diverse tecniche per determinare il percorso root dell'app, tenendo conto dei moduli installati a livello globale (ad esempio, se l'app è in esecuzione /var/www/ma il modulo è installato ~/.nvm/v0.x.x/lib/node/). Non funzionerà al 100% delle volte, ma funzionerà negli scenari più comuni.
Pro e contro
Funziona senza configurazione nella maggior parte dei casi. Fornisce inoltre alcuni metodi utili aggiuntivi (vedi la pagina del progetto). Il più grande svantaggio è che non funzionerà se:
- Stai usando un launcher, come pm2
- E , il modulo non è installato nella
node_modulesdirectory della tua app (ad esempio, se lo hai installato a livello globale)
Puoi aggirare il problema impostando una APP_ROOT_PATHvariabile ambientale o chiamando .setPath()il modulo, ma in tal caso probabilmente stai meglio usando il globalmetodo.
NODE_PATH variabile ambientale
Se stai cercando un modo per determinare il percorso principale dell'app corrente, è probabile che una delle soluzioni di cui sopra funzioni meglio per te. Se, d'altra parte, stai cercando di risolvere il problema del caricamento affidabile dei moduli dell'app, ti consiglio vivamente di esaminare la NODE_PATHvariabile ambientale.
Il sistema di moduli Node cerca moduli in una varietà di posizioni. Una di queste posizioni è ovunque process.env.NODE_PATHpunti . Se imposti questa variabile ambientale, puoi requiremoduli con il caricatore di moduli standard senza altre modifiche.
Ad esempio, se si imposta NODE_PATHsu /var/www/lib, il seguente funzionerebbe perfettamente:
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Un ottimo modo per farlo è usare npm:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Ora puoi avviare la tua app con npm starte sei d'oro. Unisco questo con il mio modulo enforce-node-path , che impedisce il caricamento accidentale dell'app senza NODE_PATHimpostazione. Per un controllo ancora maggiore sull'applicazione delle variabili ambientali, vedere checkenv .
One gotcha: NODE_PATH deve essere impostato al di fuori dell'app del nodo. Non puoi fare qualcosa del genere process.env.NODE_PATH = path.resolve(__dirname)perché il caricatore di moduli memorizza nella cache l'elenco delle directory che cercherà prima dell'esecuzione dell'app.
[aggiunto il 6/6/16] Un altro modulo davvero promettente che tenta di risolvere questo problema è ondulato .