Ich verwende das Flag --experimental-modules
beim Ausführen meiner Knotenanwendung, um ES6-Module zu verwenden.
Wenn ich dieses Flag verwende, ist die Metavariable __dirname
jedoch nicht verfügbar. Gibt es eine alternative Methode, um denselben String zu erhalten, der in __dirname
gespeichert ist und mit diesem Modus kompatibel ist?
In Node.js 10 gibt es eine Alternative, bei der nicht mehrere Dateien erstellt werden müssen:
import path from 'path';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
Es gab Vorschläge zur Offenlegung dieser Variablen durch import.meta
, aber für den Moment benötigen Sie eine harte Workaround, die ich hier gefunden habe:
// expose.js
module.exports = {__dirname};
// use.mjs
import expose from './expose.js';
const {__dirname} = expose;
Ich benutzte:
import path from 'path';
const __dirname = path.resolve(path.dirname(decodeURI(new URL(import.meta.url).pathname)));
decodeURI
war wichtig: benutzte Leerzeichen und anderes Material innerhalb des Pfads meines Testsystems.
path.resolve()
behandelt relative URLs.
Für Node 10.12 + ...
Vorausgesetzt, Sie arbeiten von einem Modul aus, sollte diese Lösung funktionieren, und Sie erhalten auch Unterstützung für __Dateinamen
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Das Schöne daran ist, dass Sie nur noch zwei Codezeilen von der Unterstützung von require () für CommonJS-Module entfernt sind. Dazu würden Sie hinzufügen:
import { createRequireFromPath } from 'module';
const require = createRequireFromPath(__filename);
import path from 'path';
const __dirname = path.join(path.dirname(decodeURI(new URL(import.meta.url).pathname)));
Dieser Code funktioniert auch unter Windows
Ich bin auch in dieses Problem gekommen, meine Lösung:
./src/app.mjs:
app.set('views', path.join(path.resolve('./src'), 'views'));
Hier finden Sie Informationen zu meiner Ordnerorganisation:
./index.mjs
import server from './src/bin/www.mjs';
server.start();
./package.json
"scripts": {
"start": "node --experimental-modules ./index.mjs"
},
Es gibt die korrekten Pfade auf meinem Windows-PC als __dirname
zurück.
Ich benutze diese Option, da der Pfad mit file://
Beginnt, entferne einfach diesen Teil.
const __filename = import.meta.url.slice(7);
const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/"));
Ich habe dieses Modul erstellt es-dirname , das den aktuellen Skript-Dirnamen zurückgibt.
import dirname from 'es-dirname'
console.log(dirname())
Es funktioniert sowohl in CommonJs Skripten als auch in ES Modulen auf Windows und Linux .
Öffnen Sie dort ein Problem, wenn ein Fehler vorliegt, da das Skript bisher in meinen Projekten funktioniert hat, in einigen anderen Fällen jedoch fehlschlagen kann. Verwenden Sie es daher nicht in einer Produktionsumgebung. Und dies ist eine vorübergehende Lösung, da ich mir sicher bin, dass das Node.js-Team in naher Zukunft eine solide Methode dafür herausbringen wird.