¿Cómo obtengo la ruta al script actual con Node.js?
Frecuentes
Visto 846,295 equipos
1079
¿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?
14 Respuestas
1501
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
269
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
130
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
127
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
52
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
50
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
28
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
__dirname
ya no funciona con módulos ES. - Dan Dascalescu
23
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
14
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
9
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
7
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 porpkg
.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 useappDirectory = 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 oprocess.cwd()
para obtener el directorio actual.
Respondido el 08 de Septiembre de 17 a las 08:09
6
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
0
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
-3
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 node.js or haz tu propia pregunta.
nodejs.org/docs/latest/api/globals.html el enlace de documentación de la respuesta aceptada. - allenhwkim