Există o modalitate mai bună decât proces.cwd()pentru a determina directorul rădăcină de funcționare node.js proces? Ceva de genul echivalentul de Șine.root
, dar pentru Node.js. Am'm în căutarea pentru ceva care este la fel de previzibil și de încredere posibil.
Există mai multe moduri de a aborda acest lucru, fiecare cu propriile lor argumente pro și contra:
De la http://nodejs.org/api/modules.html:
atunci Când un fișier este rulat direct de la Nod,
nevoie.principal
este setat la "modulul". Asta înseamnă că puteți determina dacă un fișier a fost condusă direct de testarenevoie.principala === modulul
Pentru că "modulul" oferă o
filename
proprietate (în mod normal, echivalent cu__filename
), punctul de intrare al curentului de aplicare pot fi obținute prin verificare nevoie.principal.filename`.
Deci, dacă doriți directorul de bază pentru aplicația dumneavoastră, puteți face:
var path = require('path');
var appDir = path.dirname(require.main.filename);
Acest lucru va lucra foarte bine în majoritatea timpului, dar dacă te're rulează aplicația cu un lansator, cum ar fi pm2 sau de funcționare mocca teste, această metodă nu va reuși.
Nod are un nume global obiect numit "global" — nimic pe care le atașați la acest obiect vor fi disponibile peste tot în aplicația dumneavoastră. Deci, în index.js "(sau " app.js sau oricare ar fi aplicația principală de fișier este numit), puteți defini o variabilă globală:
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
Funcționează în mod constant, dar trebuie să se bazeze pe o variabilă globală, ceea ce înseamnă că puteți't reutiliza cu ușurință componente/etc.
Acest lucru se întoarce directorul curent de lucru. Nu sunt fiabile deloc, ca's depinde în întregime de ceea ce directorul a fost lansat procesul la:
$ 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
Pentru a aborda această problemă, am'am creat un nod modul numit app-root-calea. Utilizare este simplu:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
La app-root-calea modulul utilizează mai multe tehnici diferite pentru a determina calea rădăcină al aplicației, luând în considerare, la nivel global modulele instalate (de exemplu, dacă aplicația se execută în/var/www/dar modulul este instalat în
~/.nvm/v0.x.x/lib/node/`). Nu o't lucra 100% din timp, dar's de gând să lucreze în cele mai frecvente situații.
Funcționează fără configurație în cele mai multe cazuri. De asemenea, oferă niște avantaje suplimentare metode (a se vedea pagina proiectului). Cea mai mare escrocherie este că nu o't funcționa dacă:
node_modules
director (de exemplu, dacă ați instalat-o la nivel global)Puteți obține în jurul valorii de acest lucru fie prin stabilirea unui APP_ROOT_PATH de mediu variabile, sau de asteptare
.setPath()` pe module, dar în acest caz, ar're, probabil, mai bine folosind "global" metoda.
Daca're în căutarea pentru o modalitate de a determina calea rădăcină de aplicația curentă, una dintre soluțiile de mai sus este probabil să funcționeze cel mai bine pentru tine. Dacă, pe de altă parte,'re încercarea de a rezolva problema de încărcare app module fiabil, am foarte recomandăm să căutați în `NODE_PATH de mediu variabile.
Nod's Module de sistem se pare de module într-o varietate de locații. Una dintre aceste locații este oriunde `proces.env.NODE_PATH puncte. Dacă setați acest mediu variabil, atunci pot solicita module cu modul standard încărcător, fără alte modificări.
De exemplu, dacă setați NODE_PATH " la " /var/www/lib
, următoarele ar merge numai bine:
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
O modalitate foarte bună de a face acest lucru este folosind `nmp:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Acum puteți începe aplicația dvs. cu npm startși're de aur. Am combina acest lucru cu mi [intareasca-nod-calea](https://github.com/inxilpro/enforce-node-path) modul, care previne în mod accidental de încărcare app fără NODE_PATH
set. Pentru mai mult control asupra executării variabile de mediu, a se vedea checkenv.
Unul te-am prins: NODE_PATH
trebuie să fie setat afara de la nodul de aplicație. Nu poti face ceva de genul proces.env.NODE_PATH = calea.rezolva(__dirname)
deoarece module loader cache lista de directoare se va căuta înainte de aplicația se execută.
[adaugat 4/6/16] un Alt foarte promițătoare modulul că încercările de a rezolva această problemă este ondulat.
__dirname
e't globală; it's locală pentru modulul curent astfel încât fiecare fișier are propriile sale locale, de valoare diferită.
Dacă doriți directorul rădăcină de funcționare proces, probabil că nu doriți să utilizați proces.cwd()
.
Dacă doriți previzibilitatea și fiabilitatea, atunci probabil ai nevoie pentru a face o cerință de cererea dumneavoastră că o anumită variabilă de mediu este stabilit. Aplicația arată pentru MY_APP_HOME` (Sau orice altceva) și dacă-l's acolo, și există aplicații în care directorul de atunci totul este bine. Dacă este nedefinit sau directorul nu't conține cererea dumneavoastră, atunci ar trebui să ieșiți cu o eroare de fapt care ia determinat utilizatorul pentru a crea variabila. Ar putea fi stabilit ca o parte dintr-un proces de instalare.
Puteți citi variabile de mediu în nodul cu ceva de genul proces.env.MY_ENV_VARIABLE
.
1 - crearea unui fișier în directorul rădăcină al proiectului numesc settings.js
2 - în acest fișier adăugați acest cod
module.exports = {
POST_MAX_SIZE : 40 , //MB
UPLOAD_MAX_FILE_SIZE: 40, //MB
PROJECT_DIR : __dirname
};
3 - în interiorul node_modules crea un modul nou nume "setări" și în interiorul modulului index.js scrie acest cod:
module.exports = require("../../settings");
4 - și în orice moment doriți director de proiect folosi doar
var settings = require("settings");
settings.PROJECT_DIR;
în acest fel, veți avea toate proiect directoare relative la acest dosar ;)
cel mai simplu mod de a obține rădăcină global (presupunând că utilizați NPM pentru a rula node.js app 'npm start', etc.)
var appRoot = process.env.PWD;
Dacă doriți să cross-verificați cele de mai sus
Spui că vrei să-i compar proces.env.PWD
cu setările de tine node.js aplicație. daca vrei ceva de execuție teste pentru a verifica validitatea de proces.env.PWD`, puteți verifica-l cu acest cod (pe care am scris-care pare să funcționeze bine). Puteți verifica numele ultimului folder în appRoot cu npm_package_name în pachet.fișier json, de exemplu:
var path = require('path');
var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)
//compare the last directory in the globalRoot path to the name of the project in your package.json file
var folders = globalRoot.split(path.sep);
var packageName = folders[folders.length-1];
var pwd = process.env.PWD;
var npmPackageName = process.env.npm_package_name;
if(packageName !== npmPackageName){
throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
}
if(globalRoot !== pwd){
throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
}
de asemenea, puteți utiliza acest modul NPM: cer('app-root-calea')
care funcționează foarte bine pentru acest scop
Am'am găsit acest lucru funcționează în mod constant pentru mine, chiar și atunci când aplicația este invocat de la un sub-dosar, ca se poate cu un test de cadre, cum ar fi Moca:
process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);
De ce functioneaza:
La runtime nod creează un registru de drumuri pline de toate fișierele încărcate. Modulele sunt încărcate în primul rând, și, astfel, la partea de sus a acestui registru. Prin selectarea primului element din registru și se întorc la calea înainte de 'node_modules' directorul suntem în măsură să determine o rădăcină a cererii.
L's doar o linie de cod, dar pentru simplitate's sake (dragul meu), am cutie neagră într-un modul NPM:
https://www.npmjs.com/package/node-root.pddivine
Bucurați-vă de!
Toate aceste "rădăcină dirs" cea mai mare parte de necesitatea de a rezolva unele virtual calea către o gramada de cale, deci poate ar trebui să te uiți la cale.rezolva`?
var path= require('path');
var filePath = path.resolve('our/virtual/path.ext");
De fapt, mi se pare, poate, banal, de asemenea, o soluție pentru cele mai robuste: pur și simplu loc următoarele fișiere în directorul rădăcină al proiectului dumneavoastră: root-path.js care are următorul cod:
import * as path from 'path'
const projectRootPath = path.resolve(__dirname)
export const rootPath = projectRootPath
O tehnica pe care o'am găsit util atunci când se utilizează express este să adăugați următoarele la app.js înainte de orice alte căi sunt stabilite
// set rootPath
app.use(function(req, res, next) {
req.rootPath = __dirname;
next();
});
app.use('/myroute', myRoute);
Nu este nevoie de a utiliza globals și aveți calea de la directorul rădăcină ca o proprietate a obiectului solicitării.
Acest lucru funcționează în cazul tău app.js este în rădăcina de proiect care, în mod implicit, acesta este.
Știu că asta e deja prea târziu. Dar ne poate aduce URL-ul rădăcină prin două metode
Metoda 1
var path = require('path');
path.dirname(require.main.filename);
2 metoda
var path = require('path');
path.dirname(process.mainModule.filename);
Link-ul de referință:- https://gist.github.com/geekiam/e2e3e0325abd9023d3a3
const users = require('../../../database/users'); // 👎 what you have
// OR
const users = require('$db/users'); // 👍 no matter how deep you are
const products = require('/database/products'); // 👍 alias or pathing from root directory
npm instala sexy-avea nevoie să-salvați
necesită('sexy-necesită'); const routere = necesită('/routere'); const api = necesită('$api'); ...
.căi
de fișiere în directorul rădăcină al proiectului.$db = /server/baza de date $api-v1 = /server/api/legacy $api-v2 = /server/api/v2
La partea de sus a fișierului principal adauga:
mainDir = __dirname;
Apoi să-l utilizați în orice fișier aveți nevoie de:
console.log('mainDir ' + mainDir);
mainDir
este definit la nivel global, dacă aveți nevoie de ea doar în fișierul curent utilizat __dirname
în loc.main.js
, index.js
, gulpfile.js
.Adăugați această undeva spre începutul app principal de fișier (de exemplu, app.js):
global.__basedir = __dirname;
Aceasta stabilește o variabilă globală, care va fi întotdeauna echivalent cu aplicația's de bază dir. Folositi-l la fel ca orice altă variabilă:
const yourModule = require(__basedir + '/path/to/module.js');
Simplu...
Puteți adăuga pur și simplu directorul rădăcină calea în express app variabilă și de a lua această cale de la app. Pentru a adăuga acest app.set('rootDirectory', __dirname); în index.js sau app.js fișierul. Și de a folosi `req.app.ia('rootDirectory') pentru obtinerea directorul rădăcină calea în cod.
process.mainModule.paths
.filter(p => !p.includes('node_modules'))
.shift()
Obține toate căile în module principale și filtra cei cu "node_modules", apoi a obține prima de restul calea lista. Comportament neașteptat nu va arunca o eroare, doar o "nedefinit".
Funcționează bine pentru mine, chiar și atunci când de asteptare ie $ moca
.