Как получить путь к текущему скрипту с помощью Node.js?




(9)

Как мне получить путь к скрипту в Node.js?

Я знаю, что есть process.cwd , но это относится только к каталогу, где был вызван сценарий, а не самому скрипту. Например, скажем, что я в /home/kyle/ и я запускаю следующую команду:

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

Если я вызову process.cwd() , я получаю /home/kyle/ , not /home/kyle/some/dir/ . Есть ли способ получить этот каталог?


Node.js 10 поддерживает модули ECMAScript , где __dirname и __filename недоступны из коробки.

Затем, чтобы получить путь к текущему модулю ES, необходимо использовать:

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

А для каталога, содержащего текущий модуль:

import path from 'path';

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

Вы можете использовать process.env.PWD, чтобы получить текущий путь к папке приложения.


Если вы используете pkg для упаковки своего приложения, вы найдете это выражение полезным:

appDirectory = require('path').dirname(process.pkg ? process.execPath : (require.main ? require.main.filename : process.argv[0]));
  • process.pkg сообщает, было ли приложение упаковано pkg .

  • process.execPath содержит полный путь исполняемого файла, который является /usr/bin/node или аналогичным для прямых вызовов скриптов ( node test.js ) или упакованного приложения.

  • require.main.filename содержит полный путь к основному скрипту, но он пуст, когда Node запускается в интерактивном режиме.

  • __dirname содержит полный путь к текущему сценарию, поэтому я не использую его (хотя может быть и то, что ОП спрашивает, а затем лучше использовать appDirectory = process.pkg ? require('path').dirname(process.execPath) : (__dirname || require('path').dirname(process.argv[0])); отметив, что в интерактивном режиме __dirname пуст.

  • Для интерактивного режима используйте process.argv[0] чтобы получить путь к исполняемому файлу узла или process.cwd() чтобы получить текущий каталог.


Если вы хотите в сценарии оболочки нечто большее, как $ 0, попробуйте следующее:

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;
    }
}

Когда дело доходит до основного сценария, это просто:

process.argv[1]

Из документации Node.js :

process.argv

Массив, содержащий аргументы командной строки. Первым элементом будет «узел», второй - путь к файлу JavaScript . Следующие элементы будут любыми дополнительными аргументами командной строки.

Если вам нужно знать путь к файлу модуля, используйте __filename .


Таким образом, вы можете это сделать:

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

Используйте resolve () вместо конкатенации с помощью '/' или '\', иначе вы столкнетесь с кросс-платформенными проблемами.

Примечание: __dirname - это локальный путь к модулю или включенному скрипту. Если вы пишете плагин, который должен знать путь к главному сценарию, это:

require.main.filename

или, чтобы просто получить имя папки:

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

Я знаю, что это довольно старый, и исходный вопрос, на который я отвечал, отмечен как дублированный и направленный здесь, но я столкнулся с проблемой, пытаясь заставить жасмин-репортеров работать, и мне не понравилась идея о том, что мне пришлось понизить чтобы он работал. Я узнал, что жасмин-репортеры не правильно разрешали savePath и фактически помещали вывод папок отчетов в каталог jasmine-reporters вместо корневого каталога, где я запускал gulp. Чтобы сделать эту работу правильно, я закончил использование process.env.INIT_CWD, чтобы получить начальный текущий рабочий каталог, который должен быть каталогом, в котором вы запускали gulp. Надеюсь, это поможет кому-то.

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


Я нашел его, просмотрев документацию снова. Я искал переменные уровня __filename и __dirname .

  • __filename - имя файла текущего модуля. Это разрешенный абсолютный путь к текущему файлу модуля. (например: /home/kyle/some/dir/file.js )
  • __dirname - это имя каталога текущего модуля. (например: /home/kyle/some/dir )

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






node.js