nodo __dirname no definido


138

Desde el manual del nodo veo que puedo obtener el directorio de un archivo __dirname, pero desde REPL esto parece no estar definido. ¿Es esto un malentendido de mi parte o dónde está el error?

$ node
> console.log(__dirname)
ReferenceError: __dirname is not defined
    at repl:1:14
    at REPLServer.eval (repl.js:80:21)
    at Interface.<anonymous> (repl.js:182:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:162:10)
    at Interface._line (readline.js:426:8)
    at Interface._ttyWrite (readline.js:603:14)
    at ReadStream.<anonymous> (readline.js:82:12)
    at ReadStream.emit (events.js:88:20)
    at ReadStream._emitKey (tty.js:320:10)


1
Recibí este problema al usar eslint, lo configuré por error en "browser": truelugar de "node": trueen mi archivo .eslintrc.json.
— Toivo Säwén

Respuestas:


187

__dirnamesolo se define en scripts. No está disponible en REPL.

intenta hacer un guion a.js

console.log(__dirname);

y ejecutarlo:

node a.js

Verás __dirnameimpreso.

Explicación de fondo agregada: __dirnamesignifica 'El directorio de este script'. En REPL, no tienes un script. Por __dirnamelo tanto, no tendría ningún significado real.


55
Además, no puede usar algunas de las variables globales dentro de los módulos RequireJS. Si usa RequireJS en el lado del servidor, consulte stackoverflow.com/questions/9027429/… .
— Ojo

1
Sí, eso realmente debería agregarse a la respuesta Eye, porque eso es lo que me atrapó.
— Tomáš Zato - Restablece a Mónica el

3
No agregar eso al script de carga de REPL es desagradable. No puedo pensar en ninguna razón por la que no estaría allí ...
— jcollum

Cargué un archivo de script mientras estaba dentro del REPL usando .load script.js. Es una lástima __dirname todavía no está disponible desde script.js
— Kevin Wheeler

¡Votado! me ahorró 15 minutos cuando me preguntaba qué está pasando
— PirateApp

96

Sobre la base de las respuestas existentes aquí, puede definir esto en su REPL:

__dirname = path.resolve(path.dirname(''));

O:

__dirname = path.resolve();

Si no pathse pasan segmentos, path.resolve()devolverá la ruta absoluta del directorio de trabajo actual.


O las alternativas de @ Jthorpe:

__dirname = process.cwd();
__dirname = fs.realpathSync('.');
__dirname = process.env.PWD

si lo usa nesh, puede definir esto como parte de su script de carga; es ingenioso
— jcollum

1
o __dirname = process.cwd()o __dirname=fs.realpathSync('.')o__dirname = process.env.PWD
— Jthorpe

1
path.dirnameparece que ya no acepta valores que no sean cadenas en la versión principal más nueva 6.0.0, por lo que la primera sugerencia en esta respuesta no funcionará.
— trysis

30

En el uso de ES6:

import path from 'path';
const __dirname = path.resolve();

también disponible cuando se llama al nodo con --experimental-modules


No necesita importar módulos principales en REPL; los cargará sobre la marcha por ti.
— c24w

Esto proporciona el directorio de trabajo actual, no el directorio del .jsarchivo actual .
— Dirbaio

@Dirbaio, ¿cuál sería el archivo actual.js cuando esté en REPL?
— c24w

@ c24w acaba de marcar, parece dar el CWD
— Dirbaio

@Dirbaio Creo que ese era mi punto. Cuando ingresa el REPL, no hay ningún archivo JS actual. ¿Qué te gustaría __dirnameser, si no fuera el CWD?
— c24w

8

Como dijo @qiao, no se puede usar __dirnameen el nodo repl. Sin embargo, si necesita este valor en la consola, puede usar path.resolve()o path.dirname(). Aunque, path.dirname()solo te dará un "." entonces, probablemente no sea tan útil. Asegúrate de hacerlo require('path').


3

Parece que también podrías hacer esto:

__dirname=fs.realpathSync('.');

claro no te olvides fs=require('fs')

(no es realmente global en los scripts de nodo exactamente, solo se define en el nivel del módulo)


No necesita requerir módulos centrales en el REPL; los cargará sobre la marcha por ti.
— c24w

2

Estaba ejecutando un script desde un archivo por lotes como usuario de SYSTEM y todas las variables similares process.cwd(), path.resolve()y todos los demás métodos me darían la ruta a la carpeta C: \ Windows \ System32 en lugar de la ruta real. Durante los experimentos, noté que cuando se produce un error, la pila contiene una ruta verdadera al archivo de nodo.

Aquí hay una manera muy hacky de obtener una ruta verdadera activando un error y extrayendo la ruta de e.stack. No utilice.

// this should be the name of currently executed file
const currentFilename = 'index.js';

function veryHackyGetFolder() {
  try {
    throw new Error();
  } catch(e) {
    const fullMsg = e.stack.toString();
    const beginning = fullMsg.indexOf('file:///') + 8;
    const end = fullMsg.indexOf('\/' + currentFilename);
    const dir = fullMsg.substr(beginning, end - beginning).replace(/\//g, '\\');
    return dir;
  }
}

Uso

const dir = veryHackyGetFolder();

Si no está ejecutando esto a través de REPL, puede usar __dirnamey __filename.
— c24w

Esta es la única respuesta que al menos intenta proporcionar una solución correcta.
— Tomáš Zato - Restablece a Monica el

@ c24w Intenté __dirname, __filename y todo lo demás. Ninguna solución estándar funcionó en mi caso. Aquí está mi proyecto que ejecuta un proceso como SYSTEM desde el programador de tareas si está aburrido github.com/DVLP/Unscheduler. Cualquier solución estándar que funcione es obviamente mejor que mi truco anterior :)
— Pawel

2

También estaba tratando de unirme a mi camino usando path.join(__dirname, 'access.log')pero arrojaba el mismo error.

Así es como lo arreglé:

Primero importé el paquete de ruta y declaró una variable llamada __dirname, luego llamé al método de resolve ruta .

En CommonJS

var path = require("path");

var __dirname = path.resolve();

En ES6 +

import path  from 'path';

const __dirname = path.resolve();

Feliz codificación .......


1

Aunque no es la solución a este problema, me gustaría agregarlo, ya que puede ayudar a otros.

Debería tener dos guiones bajos antes de dirname, no un guión bajo ( __dirnameno _dirname).

NodeJS Docs


__dirname (con dos guiones bajos) no funciona en el REPL
— Aaron J Spetner

1

Si tienes node __dirname not definedcon node --experimental-modules, que puede hacer:

const __dirname = path.dirname(import.meta.url)
                      .replace(/^file:\/\/\//, '') // can be usefull

Por otro ejemplo, trabaje solo con el directorio actual / pwd, no con otro directorio.


1

Si está utilizando módulos Node.js , __dirnamey __filenameno existe.

De la documentación de Node.js :

No requiere exportaciones, module.exports, __filename, __dirname

Estas variables CommonJS no están disponibles en los módulos ES.

requirese puede importar a un módulo ES mediante module.createRequire().

Se pueden crear equivalentes __filenamey __dirnamedentro de cada archivo a través de import.meta.url:

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname


0

a veces hacemos un archivo con extensión .js y agregamos consol.log (_dirname); pero enfrentamos errores, tenemos prisa, así que olvidamos agregar un guión bajo más antes del "nombre del directorio" para enfrentar el error de referencia. La sintaxis correcta es consol.log (__ nombre del directorio);

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.