Bepaal de project root van een draaiende node.js applicatie
Is er een betere manier dan process.cwd()
om de root directory van een draaiend node.js proces te bepalen? Zoiets als het equivalent van Rails.root
, maar dan voor Node.js. Ik'ben op zoek naar iets dat zo voorspelbaar en betrouwbaar mogelijk is.
284
3
Er zijn verschillende manieren om dit aan te pakken, elk met hun eigen voor- en nadelen:
require.main.filename
Van :
Dus als je de basisdirectory voor je app wilt, kun je doen:
Voors & tegens
Dit zal meestal goed werken, maar als u uw app met een launcher zoals pm2 uitvoert of mocha tests uitvoert, zal deze methode falen.
global.X
Node heeft een globaal namespace object genaamd
global
- alles wat je aan dit object koppelt zal overal in je app beschikbaar zijn. Dus, in jeindex.js
(ofapp.js
of hoe je hoofd app bestand ook heet), kun je gewoon een globale variabele definiëren:Voors & tegens
Werkt consistent, maar je moet vertrouwen op een globale variabele, wat betekent dat je componenten/etc. niet gemakkelijk kunt hergebruiken.
process.cwd()
Dit geeft de huidige werkdirectory terug. Helemaal niet betrouwbaar, omdat het volledig afhangt van vanuit welke directory het proces gestart is vanuit:
app-root-path
Om dit probleem aan te pakken, heb ik'een node-module gemaakt genaamd app-root-path. Het gebruik is eenvoudig:
De app-root-path module gebruikt verschillende technieken om het root pad van de app te bepalen, rekening houdend met globaal geïnstalleerde modules (bijvoorbeeld, als je app draait in
/var/www/
maar de module is geïnstalleerd in~/.nvm/v0.x.x/lib/node/
). Het zal'niet 100% van de tijd werken, maar het'gaat werken in de meest voorkomende scenario's.Voors & tegens
Werkt zonder configuratie in de meeste omstandigheden. Biedt ook een aantal leuke extra gemaksmethoden (zie projectpagina). Het grootste nadeel is dat het niet zal werken als:
node_modules
directory (bijvoorbeeld, als je het globaal geïnstalleerd hebt)U kunt dit omzeilen door ofwel een
APP_ROOT_PATH
omgevingsvariabele in te stellen, of door.setPath()
op de module aan te roepen, maar in dat geval bent u waarschijnlijk beter af met deglobal
methode.NODE_PATH omgevingsvariabele
Als je'op zoek bent naar een manier om het root pad van de huidige app te bepalen, zal een van de bovenstaande oplossingen waarschijnlijk het beste voor je werken. Als, aan de andere kant, u'het probleem van het betrouwbaar laden van app modules probeert op te lossen, raad ik u ten zeerste aan de
NODE_PATH
omgevingsvariabele te onderzoeken.Node's Modules system zoekt naar modules in een verscheidenheid van locaties. Een van deze locaties is waar
process.env.NODE_PATH
naar wijst. Als u deze omgevingsvariabele instelt, dan kunt u modulesrequireen
met de standaard module loader zonder andere wijzigingen.Bijvoorbeeld, als u
NODE_PATH
instelt op/var/www/lib
, dan zou het volgende prima werken:Een goede manier om dit te doen is door
npm
te gebruiken:Nu kun je je app starten met
npm start
en je'bent goud waard. Ik combineer dit met mijn enforce-node-path module, die voorkomt dat per ongeluk de app geladen wordt zonderNODE_PATH
ingesteld. Voor nog meer controle over het afdwingen van omgevingsvariabelen, zie checkenv.Eén probleem:
NODE_PATH
moet worden ingesteld buiten de node app. Je kunt niet iets doen alsprocess.env.NODE_PATH = path.resolve(__dirname)
omdat de module loader de lijst van mappen die het zal doorzoeken in een cache opslaat voordat je app draait.[toegevoegd 4/6/16] Een andere echt veelbelovende module die dit probleem probeert op te lossen is wavy.
__dirname
is niet globaal; het is lokaal voor de huidige module, dus elk bestand heeft zijn eigen lokale, verschillende waarde.Als je de root directory van het lopende proces wilt, wil je waarschijnlijk wel
process.cwd()
gebruiken.Als je voorspelbaarheid en betrouwbaarheid wilt, dan moet je waarschijnlijk een eis stellen aan je applicatie dat een bepaalde omgevingsvariabele is ingesteld. Je app zoekt naar
MY_APP_HOME
(Of wat dan ook) en als die er is, en de applicatie bestaat in die directory, dan is alles goed. Als het niet gedefinieerd is of de map bevat uw toepassing niet dan zou het moeten afsluiten met een fout die de gebruiker vraagt om de variabele te creëren. Het zou kunnen worden ingesteld als onderdeel van een installatieproces.Je kunt omgevingsvariabelen in node lezen met iets als
process.env.MY_ENV_VARIABLE
.1- maak een bestand aan in de project root noem het settings.js
2- voeg in dit bestand de volgende code toe
3- binnen node_modules maak een nieuwe module aan noem het "settings" en binnen de module index.js schrijf deze code:
4- en elke keer dat u uw project directory wilt gebruiken gewoon
op deze manier heb je alle project directories relatief aan dit bestand ;)