Есть несколько способов подойти к этому, каждый со своими плюсами и минусами:
require.main.filename
С http://nodejs.org/api/modules.html :
Когда файл запускается непосредственно из Node, require.mainустанавливается его module. Это означает, что вы можете определить, был ли файл запущен напрямую, путем тестированияrequire.main === module
Поскольку moduleпредоставляет filenameсвойство (обычно эквивалентное __filename), точка входа текущего приложения может быть получена путем проверки require.main.filename.
Так что если вы хотите базовый каталог для вашего приложения, вы можете сделать:
var path = require('path');
var appDir = path.dirname(require.main.filename);
За и против
Это будет работать отлично большую часть времени, но если вы используете приложение с пусковым как PM2 или бегом мокко испытания, этот метод не получится .
global.X
Узел имеет глобальный объект пространства имен, который называется global- все, что вы прикрепите к этому объекту, будет доступно везде в вашем приложении. Таким образом, в вашем index.js(или app.jsкак называется ваш основной файл приложения), вы можете просто определить глобальную переменную:
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
За и против
Работает согласованно, но вы должны полагаться на глобальную переменную, что означает, что вы не можете легко повторно использовать компоненты / и т.д.
process.cwd ()
Это возвращает текущий рабочий каталог. Не надежны вообще, так как это полностью зависит от того, что каталог процесс был запущен из :
$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir
Приложение-корневой путь
Чтобы решить эту проблему, я создал модуль узла с именем app-root-path . Использование простое:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
Модуль app-root-path использует несколько различных методов для определения корневого пути приложения с учетом глобально установленных модулей (например, если ваше приложение работает, /var/www/но модуль установлен ~/.nvm/v0.x.x/lib/node/). Это не будет работать 100% времени, но это будет работать в большинстве распространенных сценариев.
За и против
Работает без конфигурации в большинстве случаев. Также предоставляет несколько приятных дополнительных удобных методов (см. Страницу проекта). Самый большой недостаток в том, что он не будет работать, если:
- Вы используете лаунчер, например, pm2
- И , модуль не установлен внутри
node_modulesкаталога вашего приложения (например, если вы установили его глобально)
Вы можете обойти это, установив APP_ROOT_PATHпеременную окружения или вызвав .setPath()модуль, но в этом случае вам, вероятно, лучше использовать globalметод.
NODE_PATH переменная среды
Если вы ищете способ определения корневого пути текущего приложения, одно из приведенных выше решений, вероятно, подойдет вам лучше всего. С другой стороны, если вы пытаетесь надежно решить проблему загрузки модулей приложения, я настоятельно рекомендую изучить NODE_PATHпеременную среды.
Система модулей Node ищет модули в разных местах. Одно из этих мест - везде, куда process.env.NODE_PATHуказывает . Если вы установите эту переменную среды, то вы можете requireмодули со стандартным загрузчиком модулей без каких-либо других изменений.
Например, если вы установите NODE_PATHна /var/www/lib, то следующее будет работать нормально:
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Отличный способ сделать это с помощью npm:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Теперь вы можете начать свое приложение с npm startи вы золотой. Я объединяю это с моим модулем forcece-node-path , который предотвращает случайную загрузку приложения без NODE_PATHнабора. Для еще большего контроля над выполнением переменных среды см. Checkenv .
Одна ошибка: NODE_PATH должна быть установлена вне приложения узла. Вы не можете сделать что-то подобное, process.env.NODE_PATH = path.resolve(__dirname)потому что загрузчик модулей кэширует список каталогов, в которых он будет искать, прежде чем ваше приложение запустится.
[добавлено 6/6/16] Другой действительно многообещающий модуль, который пытается решить эту проблему, является волнистым .