Gibt es einen anderen Weg, außer process.cwd()
, um den Pfadnamen des Root-Verzeichnisses des aktuellen Projekts zu erhalten. Implementiert Node so etwas wie die Eigenschaft von Ruby, Rails.root
,. Ich bin auf der Suche nach etwas, das konstant und zuverlässig ist.
Antworten
Zu viele Anzeigen?Es gibt viele Möglichkeiten, dies zu tun, jede mit ihren eigenen Vor- und Nachteilen:
require.main.filename
De http://nodejs.org/api/modules.html :
Wenn eine Datei direkt von Node aus ausgeführt wird,
require.main
wird auf seinemodule
. Das bedeutet, dass Sie feststellen können, ob eine Datei direkt ausgeführt wurde, indem Sie testenrequire.main === module
Denn
module
bietet einefilename
Eigenschaft (normalerweise gleichbedeutend mit__filename
), kann der Einstiegspunkt der aktuellen Anwendung ermittelt werden, indem dierequire.main.filename
.
Wenn Sie also das Basisverzeichnis für Ihre Anwendung benötigen, können Sie dies tun:
const { dirname } = require('path');
const appDir = dirname(require.main.filename);
Pro und Kontra
Dies wird in den meisten Fällen gut funktionieren, aber wenn Sie Ihre Anwendung mit einem Launcher wie pm2 oder Laufen Mokka Tests, wird diese Methode fehlschlagen. Dies wird auch nicht funktionieren, wenn Sie Node.js ES-Module verwenden, bei denen require.main
ist nicht verfügbar.
module.paths
Der Knoten veröffentlicht alle Modulsuchpfade auf module.paths
. Wir können diese durchgehen und die erste auswählen, die sich auflöst.
async function getAppPath() {
const { dirname } = require('path');
const { constants, promises: { access } } = require('fs');
for (let path of module.paths) {
try {
await access(path, constants.F_OK);
return dirname(path);
} catch (e) {
// Just move on to next path
}
}
}
Pro und Kontra
Dies funktioniert manchmal, ist aber nicht zuverlässig, wenn es in einem Paket verwendet wird, da es möglicherweise das Verzeichnis zurückgibt, in dem das Paket installiert ist, und nicht das Verzeichnis, in dem die Anwendung installiert ist.
Verwendung einer globalen Variablen
Node hat ein globales Namespace-Objekt namens global
- Alles, was Sie diesem Objekt zuordnen, wird überall in Ihrer Anwendung verfügbar sein. Also, in Ihrer index.js
(o app.js
oder was auch immer Ihre Hauptanwendung Datei benannt ist), können Sie einfach eine globale Variable definieren:
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
Pro und Kontra
Funktioniert konsistent, aber man ist auf eine globale Variable angewiesen, was bedeutet, dass man Komponenten usw. nicht einfach wiederverwenden kann.
process.cwd()
Dies gibt das aktuelle Arbeitsverzeichnis zurück. Überhaupt nicht zuverlässig, da es völlig davon abhängt, in welchem Verzeichnis der Prozess gestartet wurde von :
$ 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-Pfad
Um dieses Problem zu lösen, habe ich ein Knotenmodul namens app-Root-Pfad . Die Verwendung ist einfach:
const appRoot = require('app-root-path');
const myModule = require(`${ appRoot }/lib/my-module.js`);
En app-Root-Pfad Modul verwendet verschiedene Techniken, um den Root-Pfad der Anwendung zu bestimmen, wobei global installierte Module berücksichtigt werden (wenn Ihre Anwendung beispielsweise in /var/www/
aber das Modul ist installiert in ~/.nvm/v0.x.x/lib/node/
). Das wird nicht immer zu 100 % funktionieren, aber in den meisten Fällen schon.
Pro und Kontra
Funktioniert unter den meisten Umständen ohne Konfiguration. Bietet auch einige nette zusätzliche Komfortmethoden (siehe Projektseite). Der größte Nachteil ist, dass es nicht funktionieren wird, wenn:
- Sie verwenden einen Launcher, wie pm2
- UND ist das Modul nicht innerhalb der App installiert.
node_modules
(zum Beispiel, wenn Sie es global installiert haben)
Sie können dies umgehen, indem Sie entweder eine APP_ROOT_PATH
Umgebungsvariable, oder durch den Aufruf von .setPath()
auf dem Modul, aber in diesem Fall sind Sie wahrscheinlich besser dran, wenn Sie die global
Methode.
NODE_PATH Umgebungsvariable
Wenn Sie nach einem Weg suchen, um ermitteln. Wenn Sie den Root-Pfad der aktuellen Anwendung nicht kennen, ist eine der oben genannten Lösungen für Sie wahrscheinlich am besten geeignet. Wenn Sie hingegen versuchen, das Problem des zuverlässigen Ladens von App-Modulen zu lösen, empfehle ich Ihnen dringend, sich mit dem NODE_PATH
Umweltvariable.
Knotens Module System sucht nach Modulen an verschiedenen Orten. Einer dieser Orte ist der Ort process.env.NODE_PATH
Punkte . Wenn Sie diese Umgebungsvariable setzen, dann können Sie require
Module mit dem Standard-Modul-Loader ohne weitere Änderungen.
Zum Beispiel, wenn Sie NODE_PATH
a /var/www/lib
würde das Folgende sehr gut funktionieren:
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Eine gute Möglichkeit, dies zu tun, ist die Verwendung von npm
:
{
"scripts": {
"start": "NODE_PATH=. node app.js"
}
}
Jetzt können Sie Ihre Anwendung mit npm start
und Sie sind glücklich. Ich kombiniere das mit meinem enforce-node-path Modul, das ein versehentliches Laden der Anwendung ohne NODE_PATH
gesetzt. Für noch mehr Kontrolle über die Erzwingung von Umgebungsvariablen, siehe checkenv .
Ein Problem: NODE_PATH
doit eingestellt werden außerhalb der Knoten-App. Sie können nicht etwas tun wie process.env.NODE_PATH = path.resolve(__dirname)
weil der Modullader die Liste der Verzeichnisse, die er durchsucht, bevor Ihre Anwendung ausgeführt wird, im Cache speichert.
[hinzugefügt 4/6/16] Ein weiteres vielversprechendes Modul, das versucht, dieses Problem zu lösen, ist gewellt .
__dirname
ist kein globaler, sondern ein lokaler Wert für das aktuelle Modul, so dass jede Datei ihren eigenen lokalen, unterschiedlichen Wert hat.
Wenn Sie das Root-Verzeichnis des laufenden Prozesses wollen, sollten Sie wahrscheinlich die Option process.cwd()
.
Wenn Sie Vorhersagbarkeit und Zuverlässigkeit wünschen, müssen Sie wahrscheinlich eine bestimmte Umgebungsvariable als Voraussetzung für Ihre Anwendung festlegen. Ihre Anwendung sucht nach MY_APP_HOME
(oder was auch immer) und wenn es dort ist und die Anwendung in diesem Verzeichnis existiert, ist alles in Ordnung. Wenn sie undefiniert ist oder das Verzeichnis Ihre Anwendung nicht enthält, sollte es mit einer Fehlermeldung enden, die den Benutzer auffordert, die Variable zu erstellen. Sie könnte als Teil eines Installationsprozesses gesetzt werden.
Sie können Umgebungsvariablen in Node lesen mit etwas wie process.env.MY_ENV_VARIABLE
.
1- Erstellen Sie eine Datei im Projekt Root und nennen Sie sie einstellungen.js
2- Fügen Sie innerhalb dieser Datei folgenden Code ein
module.exports = {
POST_MAX_SIZE : 40 , //MB
UPLOAD_MAX_FILE_SIZE: 40, //MB
PROJECT_DIR : __dirname
};
3- Erstellen Sie innerhalb von node_modules ein neues Modul mit dem Namen "settings" und schreiben Sie innerhalb des Moduls index.js diesen Code:
module.exports = require("../../settings");
4- und jedes Mal, wenn Sie Ihr Projektverzeichnis benötigen, verwenden Sie einfach
var settings = require("settings");
settings.PROJECT_DIR;
auf diese Weise haben Sie alle Projektverzeichnisse relativ zu dieser Datei ;)
Der einfachste Weg, um die globale Wurzel ( vorausgesetzt, Sie verwenden NPM, um Ihre node.js-Anwendung auszuführen: 'npm start' usw. )
var appRoot = process.env.PWD;
Wenn Sie die obigen Angaben gegenprüfen möchten
Nehmen wir an, Sie wollen eine Gegenprobe machen process.env.PWD
mit den Einstellungen Ihrer node.js-Anwendung. Wenn Sie einige Laufzeittests zur Überprüfung der Gültigkeit von process.env.PWD
können Sie es mit diesem Code vergleichen (den ich geschrieben habe und der gut zu funktionieren scheint). Sie können den Namen des letzten Ordners in appRoot zum Beispiel mit dem npm_package_name in Ihrer package.json-Datei abgleichen:
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.');
}
können Sie auch dieses NPM-Modul verwenden: require('app-root-path')
die für diesen Zweck sehr gut geeignet ist
- See previous answers
- Weitere Antworten anzeigen