¿Cómo obtengo la ruta al script actual con Node.js?

¿Cómo obtendría la ruta al script en Node.js?

Yo se que hay process.cwd, pero eso solo se refiere al directorio donde se llamó al script, no al script en sí. Por ejemplo, digamos que estoy en /home/kyle/ y ejecuto el siguiente comando:

node /home/kyle/some/dir/file.js

Si llamo process.cwd(), Yo obtengo /home/kyle/no, /home/kyle/some/dir/. ¿Hay alguna forma de obtener ese directorio?

preguntado el 28 de junio de 10 a las 11:06

nodejs.org/docs/latest/api/globals.html el enlace de documentación de la respuesta aceptada. -

14 Respuestas

Lo encontré después de revisar la documentación nuevamente. Lo que estaba buscando eran los __filename e __dirname variables de nivel de módulo.

  • __filename es el nombre de archivo del módulo actual. Esta es la ruta absoluta resuelta del archivo del módulo actual. (ex:/home/kyle/some/dir/file.js)
  • __dirname es el nombre del directorio del módulo actual. (ex:/home/kyle/some/dir)

Respondido 24 Oct 18, 16:10

Si solo desea el nombre del directorio y no la ruta completa, puede hacer algo como esto: function getCurrentDirectoryName () {var fullPath = __dirname; var ruta = fullPath.split ('/'); var cwd = ruta [ruta.longitud-1]; return cwd; } - Anthony Martin

@AnthonyMartin __dirname.split ("/"). Pop () - 19 horas

Para aquellos que prueban la solución @apx (como lo hice yo :), esta solución no funciona en Windows. - Laoujin

O simplemente __dirname.split(path.sep).pop() - Burgi

Or require('path').basename(__dirname); - Viacheslav Cotruta

Entonces, básicamente, puedes hacer esto:

fs.readFile(path.resolve(__dirname, 'settings.json'), 'UTF-8', callback);

Utilice resolve () en lugar de concatenar con '/' o '\', de lo contrario se encontrará con problemas multiplataforma.

Nota: __dirname es la ruta local del módulo o script incluido. Si está escribiendo un complemento que necesita conocer la ruta del script principal, es:

require.main.filename

o, para obtener el nombre de la carpeta:

require('path').dirname(require.main.filename)

Respondido 26 Oct 12, 18:10

Si su objetivo es solo analizar e interactuar con el archivo json, a menudo puede hacerlo más fácilmente a través de var settings = require('./settings.json'). Por supuesto, es síncrono fs IO, así que no lo hagas en tiempo de ejecución, pero en el momento de inicio está bien, y una vez que esté cargado, se almacenará en caché. - Isaacs

@Marc ¡Gracias! Por un tiempo, estaba haciéndome cargo del hecho de que __dirname es local para cada módulo. Tengo una estructura anidada en mi biblioteca y necesito saber en varios lugares la raíz de mi aplicación. Me alegro de saber cómo hacer esto ahora: D - Thijs Koerselman

Nodo V8: path.dirname (process.mainModule.filename) - camino del futuro

Si no considera que Windows sea una plataforma real, ¿podemos omitir la resolución? BSD, Macos, linux, tizen, symbian, Solaris, android, flutter, webos todos usan / ¿verdad? - ray foss

Este comando devuelve el directorio actual:

var currentPath = process.cwd();

Por ejemplo, para usar la ruta para leer el archivo:

var fs = require('fs');
fs.readFile(process.cwd() + "\\text.txt", function(err, data)
{
    if(err)
        console.log(err)
    else
        console.log(data.toString());
});

Respondido 12 Feb 18, 23:02

Para los que no entendieron Asincrónico e Sincrónico, mira este enlace ... stackoverflow.com/a/748235/5287072 - DarckBlezzer

esto es exactamente lo que el OP no quiere ... ¡la solicitud es para la ruta del script ejecutable! - cesarsol

El directorio actual es algo muy diferente. Si ejecuta algo como cd /foo; node bar/test.js, el directorio actual sería /foo, pero el script se encuentra en /foo/bar/test.js. - rjmunro

No es una buena respuesta. Es un desastre una lógica portuguesa, este puede ser un camino mucho más corto de lo esperado. - kris_IV

¿Por qué harías esto? si el archivo fuera relativo al directorio actual, simplemente podría leer text.txt y funcionaría, no necesita construir la ruta absoluta - miguel mrozek

Utilice __dirname !!

__dirname

El nombre del directorio del módulo actual. Este es el mismo que el path.dirname () del __filename.

Ejemplo: ejecutar node example.js desde / Users / mjr

console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr

https://nodejs.org/api/modules.html#modules_dirname

Para ESModules, querría usar: import.meta.url

Respondido 28 Abr '19, 13:04

Esto también sobrevive a los enlaces simbólicos. Entonces, si crea un contenedor y necesita encontrar un archivo, por ejemplo, path.join (__ dirname, "../example.json"); seguirá funcionando cuando su binario esté vinculado en node_modules / .bin - Jason

Esta respuesta no solo fue dada años antes, también ya no funciona con módulos ES. - Dan Dascalescu

Cuando se trata del script principal, es tan simple como:

process.argv[1]

Desde el Documentación de Node.js:

proceso.argv

Una matriz que contiene los argumentos de la línea de comandos. El primer elemento será 'nodo', el segundo elemento será la ruta al archivo JavaScript. Los siguientes elementos serán cualquier argumento adicional de la línea de comandos.

Si necesita conocer la ruta de un archivo de módulo, utilice __Nombre del archivo.

Respondido el 20 de junio de 20 a las 10:06

¿Podría el votante negativo explicar por qué no se recomienda? - tamlin

@Tamlyn Quizás porque process.argv[1] se aplica solo al guión principal mientras __filename apunta al archivo del módulo que se está ejecutando. Actualizo mi respuesta para enfatizar la diferencia. Aún así, no veo nada de malo en usar process.argv[1]. Depende de los requisitos de uno. - lukasz wiktor

Si el script principal se lanzó con un administrador de procesos de nodo como pm2 process.argv [1] apuntará al ejecutable del administrador de procesos /usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js - user3002996

@LukaszWiktor ¡Muchas gracias! Funciona perfectamente con una CLI personalizada de Node.js :-) - bgrand-ch

Node.js 10 admite Módulos ECMAScript, Donde __dirname e __filename ya no están disponibles.

Entonces para obtener el ruta al módulo ES actual uno tiene que usar:

import { fileURLToPath } from 'url';

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

Y para el directorio que contiene el módulo actual:

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

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

Respondido el 05 de junio de 19 a las 03:06

¿Cómo puedo saber si estoy escribiendo un módulo ES o no? ¿Es solo una cuestión de qué versión de Node estoy ejecutando, o si estoy usando palabras clave de importación / exportación? - ed brannin

Módulos ES disponibles solo con --experimental-modules bandera. - Alma de Nicken

--experimental-modules solo es necesario si está ejecutando la versión del nodo es <13.2. simplemente nombre el archivo .mjs en lugar de .js - ¡Brent

¡Gracias, eso me solucionó! Me parece que sería genial para la compatibilidad con versiones anteriores. - gal grünfeld

var settings = 
    JSON.parse(
        require('fs').readFileSync(
            require('path').resolve(
                __dirname, 
                'settings.json'),
            'utf8'));

respondido 30 mar '14, 05:03

Solo una nota, a partir del nodo 0.5 solo puede requerir un archivo JSON. Por supuesto que eso no respondería a la pregunta. - kevin cox

Cada programa de Node.js tiene algunas variables globales en su entorno, que representa alguna información sobre su proceso y una de ellas es __dirname.

Respondido 26 Feb 17, 10:02

Esta respuesta no solo se dio años antes, __dirname ya no funciona con módulos ES. - Dan Dascalescu

Se trata de NodeJs 10, pero esta respuesta se publicó en 2016. - Hazarapet Tunanyan

Sé que esto es bastante antiguo, y la pregunta original a la que respondía está marcada como duplicada y dirigida aquí, pero encontré un problema al intentar que los reporteros de jazmín trabajaran y no me gustó la idea de tener que degradar en para que funcione. Descubrí que jasmine-reporters no estaba resolviendo el savePath correctamente y en realidad estaba poniendo la salida de la carpeta de informes en el directorio jasmine-reporters en lugar del directorio raíz de donde ejecuté gulp. Para que esto funcione correctamente terminé usando proceso.env.INIT_CWD para obtener el directorio de trabajo actual inicial, que debería ser el directorio donde ejecutó gulp. Espero que esto ayude a alguien.

var reporters = require('jasmine-reporters');
var junitReporter = new reporters.JUnitXmlReporter({
  savePath: process.env.INIT_CWD + '/report/e2e/',
  consolidateAll: true,
  captureStdout: true
 });

Respondido 30 Oct 19, 05:10

Puede usar process.env.PWD para obtener la ruta de la carpeta de la aplicación actual.

Respondido el 28 de Septiembre de 16 a las 08:09

OP solicita la "ruta de acceso al script" solicitada. PWD, que significa algo así como Process Working Directory, no es eso. Además, la expresión "aplicación actual" es engañosa. - dmcontador

Esto es exactamente lo que estaba buscando a pesar de que es una respuesta incorrecta para esta pregunta: D - ProllyGeek

Si está utilizando pkg para empaquetar su aplicación, encontrará útil esta expresión:

appDirectory = require('path').dirname(process.pkg ? process.execPath : (require.main ? require.main.filename : process.argv[0]));
  • process.pkg indica si la aplicación ha sido empaquetada por pkg.

  • process.execPath contiene la ruta completa del ejecutable, que es /usr/bin/node o similar para invocaciones directas de scripts (node test.js) o la aplicación empaquetada.

  • require.main.filename contiene la ruta completa del script principal, pero está vacía cuando Node se ejecuta en modo interactivo.

  • __dirname sostiene el camino completo de la corriente script, así que no lo estoy usando (aunque puede ser lo que pide OP; entonces mejor use appDirectory = process.pkg ? require('path').dirname(process.execPath) : (__dirname || require('path').dirname(process.argv[0])); señalando que en modo interactivo __dirname esta vacio.

  • Para el modo interactivo, utilice process.argv[0] para obtener la ruta al ejecutable de Node o process.cwd() para obtener el directorio actual.

Respondido el 08 de Septiembre de 17 a las 08:09

Use el basename método de la path módulo:

var path = require('path');
var filename = path.basename(__filename);
console.log(filename);

Aquí es la documentación de la que se tomó el ejemplo anterior.

Como señaló Dan, Node está trabajando en Módulos ECMAScript con el indicador "--experimental-modules". Nodo 12 todavía apoya __dirname e __filename como anteriormente.


Si está utilizando el --experimental-modules bandera, hay una Enfoque alternativo.

La alternativa es conseguir el ruta al módulo ES actual:

const __filename = new URL(import.meta.url).pathname;

Y para el directorio que contiene el módulo actual:

import path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);

Respondido 26 Abr '19, 02:04

index.js dentro de cualquier carpeta que contenga módulos para exportar

const entries = {};
for (const aFile of require('fs').readdirSync(__dirname, { withFileTypes: true }).filter(ent => ent.isFile() && ent.name !== 'index.js')) {
  const [ name, suffix ] = aFile.name.split('.');
  entries[name] = require(`./${aFile.name}`);
}

module.exports = entries;

Esto encontrará todos los archivos en la raíz del directorio actual, requerirá y exportará todos los archivos presentes con el mismo nombre de exportación que la raíz del nombre del archivo.

Respondido el 17 de enero de 21 a las 23:01

Si desea algo más como $ 0 en un script de shell, intente esto:

var path = require('path');

var command = getCurrentScriptPath();

console.log(`Usage: ${command} <foo> <bar>`);

function getCurrentScriptPath () {
    // Relative path from current working directory to the location of this script
    var pathToScript = path.relative(process.cwd(), __filename);

    // Check if current working dir is the same as the script
    if (process.cwd() === __dirname) {
        // E.g. "./foobar.js"
        return '.' + path.sep + pathToScript;
    } else {
        // E.g. "foo/bar/baz.js"
        return pathToScript;
    }
}

contestado el 05 de mayo de 17 a las 10:05

__dirname e __filename están ya no está disponible con módulos ES. - Dan Dascalescu

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.