Есть ли лучший способ, чем process.cwd()
, определить корневой каталог запущенного процесса node.js? Что-то вроде эквивалента Rails.root
, но для Node.js. Я ищу что-то настолько предсказуемое и надежное, насколько это возможно.
Существует несколько способов решения этой проблемы, каждый из которых имеет свои плюсы и минусы:
Из http://nodejs.org/api/modules.html:
Когда файл запускается непосредственно из Node,
require.main
устанавливается на егомодуль
. Это означает, что вы можете определить, был ли файл запущен напрямую, проверивrequire.main === module
.Поскольку
module
предоставляет свойствоfilename
(обычно эквивалентное__filename
), точка входа текущего приложения может быть получена путем проверкиrequire.main.filename
.
Поэтому, если вам нужен базовый каталог для вашего приложения, вы можете сделать следующее:
var path = require('path');
var appDir = path.dirname(require.main.filename);
В большинстве случаев этот метод работает отлично, но если вы запускаете свое приложение с помощью пусковой установки типа pm2 или выполняете тесты mocha, этот метод не сработает.
В Node есть объект глобального пространства имен, называемый 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');
Работает стабильно, но вы должны полагаться на глобальную переменную, что означает, что вы не можете легко повторно использовать компоненты/etc.
Возвращает текущий рабочий каталог. Совсем не надежно, так как полностью зависит от того, из какого каталога был запущен процесс:
$ 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
Чтобы решить эту проблему, я создал модуль node под названием 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% случаев, но это будет работать в большинстве распространенных сценариев.
Работает без конфигурации в большинстве случаев. Также предоставляет некоторые приятные дополнительные методы удобства (см. страницу проекта). Самым большим недостатком является то, что он не будет работать, если:
node_modules
вашего приложения (например, если вы установили его глобально)Вы можете обойти это, установив переменную окружения APP_ROOT_PATH
или вызвав .setPath()
для модуля, но в этом случае, вероятно, лучше использовать метод global
.
Если вы ищете способ определить корневой путь текущего приложения, то одно из приведенных выше решений, скорее всего, подойдет вам лучше всего. С другой стороны, если вы пытаетесь решить проблему надежной загрузки модулей приложения, я настоятельно рекомендую рассмотреть переменную окружения NODE_PATH
.
Node's Modules system ищет модули в различных местах. Одним из таких мест является место, куда указывает process.env.NODE_PATH
. Если вы установите эту переменную окружения, то сможете требовать
модули с помощью стандартного загрузчика модулей без каких-либо других изменений.
Например, если вы установите 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
и вы'золотой. Я сочетаю это с модулем enforce-node-path, который предотвращает случайную загрузку приложения без установленного NODE_PATH
. Для еще большего контроля над принудительным использованием переменных окружения, смотрите checkenv.
Одна загвоздка: NODE_PATH
должен быть установлен вне приложения node. Вы не можете сделать что-то вроде process.env.NODE_PATH = path.resolve(__dirname)
, потому что загрузчик модулей кэширует список каталогов, которые он будет искать перед запуском вашего приложения.
[добавлено 4/6/16] Другой действительно перспективный модуль, который пытается решить эту проблему - wavy.
__dirname
не является глобальным, оно локально для текущего модуля, поэтому каждый файл имеет свое локальное, отличное от других значение.
Если вам нужен корневой каталог запущенного процесса, то, вероятно, вам лучше использовать process.cwd()
.
Если вы хотите предсказуемости и надежности, то вам, вероятно, нужно сделать требованием вашего приложения установку определенной переменной окружения. Ваше приложение ищет MY_APP_HOME
(или любую другую), и если она есть, и приложение существует в этой директории, то все в порядке. Если она не определена или каталог не содержит вашего приложения, то приложение должно выйти с ошибкой, предлагая пользователю создать переменную. Она может быть установлена как часть процесса установки.
Вы можете читать переменные окружения в node с помощью чего-то вроде process.env.MY_ENV_VARIABLE
.
1- создайте файл в корне проекта, назовите его settings.js.
2- внутри этого файла добавьте следующий код
module.exports = {
POST_MAX_SIZE : 40 , //MB
UPLOAD_MAX_FILE_SIZE: 40, //MB
PROJECT_DIR : __dirname
};
3- внутри node_modules создайте новый модуль, назовите его "settings" и внутри модуля index.js напишите этот код:
module.exports = require("../../settings");
4- и в любое время, когда вы захотите открыть каталог проекта, просто используйте
var settings = require("settings");
settings.PROJECT_DIR;
таким образом у вас будут все директории проекта относительно этого файла ;)
самый простой способ получить глобальный корень (при использовании НПМ для выполнения node.js приложение 'НПМ старт' и т. д.)
var appRoot = process.env.PWD;
Если вы хотите кросс-проверки выше
Скажем, вы хотите проверить процесс.ОКР.Дуо с настройки вы node.js приложения. если вы хотите во время выполнения тестов для проверки правильности процесса.ОКР.Дуо, вы можете проверить его с помощью этого кода (который я написал, кажется, работает хорошо). Вы можете проверить имя последней папки в настройке approot с npm_package_name в свой пакет.JSON-файл, например:
var path = require('path');
var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)
//compare the last directory in the globalRoot path to the name of the project in your package.json file
var folders = globalRoot.split(path.sep);
var packageName = folders[folders.length-1];
var pwd = process.env.PWD;
var npmPackageName = process.env.npm_package_name;
if(packageName !== npmPackageName){
throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
}
if(globalRoot !== pwd){
throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
}
вы также можете использовать этот модуль НПМ: требуется('приложение-Root-пути')
, которая работает очень хорошо для этой цели
Я'вэ нашел это работает для меня, даже когда приложение вызывается из суб-папки, как это может быть с некоторыми тестирования, как Мокко:
process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);
Почему это работает:
Во время выполнения узла создает реестре на полные пути всех загруженных файлов. Модули загружаются первыми, а значит в верхней части реестра. Выбрав первый элемент реестра и возвращает путь до 'папки node_modules' каталога мы можем определить корень применение.
Это's просто одна строка кода, но для простоты'ы имя (мое имя), я черный в штучной упаковке его в НПМ модуль:
https://www.npmjs.com/package/node-root.pddivine
Наслаждайтесь!
Все эти "у корня Дирс" в основном нужно решить какие-то виртуальные пути в реальный путь кучу, так может быть вам стоит посмотреть на пути.решение`?
var path= require('path');
var filePath = path.resolve('our/virtual/path.ext");
На самом деле, я считаю, возможно тривиальное решение и самое надежное: вы просто поместите следующий файл в корневом каталоге вашего проекта: root-path.js который содержит следующий код:
import * as path from 'path'
const projectRootPath = path.resolve(__dirname)
export const rootPath = projectRootPath
Метод, который я'вэ нашел полезным при использовании курьерского добавить следующее app.js прежде чем любой из ваших других маршрутах устанавливаются
// set rootPath
app.use(function(req, res, next) {
req.rootPath = __dirname;
next();
});
app.use('/myroute', myRoute);
Нет необходимости использовать Globals и у вас есть путь к корневому каталогу как свойство объекта запроса.
Это работает, если ваш app.js находится в корне вашего проекта, который, по умолчанию, это.
Я знаю, что это уже слишком поздно. Но мы можем извлечь URL-адрес корневой папки двумя способами
1-й способ
var path = require('path');
path.dirname(require.main.filename);
2-й способ
var path = require('path');
path.dirname(process.mainModule.filename);
Ссылка:- https://gist.github.com/geekiam/e2e3e0325abd9023d3a3
const users = require('../../../database/users'); // 👎 what you have
// OR
const users = require('$db/users'); // 👍 no matter how deep you are
const products = require('/database/products'); // 👍 alias or pathing from root directory
<БР/>
НПМ установить сексуальный-требуется --сохранить
<БР/>требуют('сексуально-требует'); константный маршрутизаторы = требуют('/маршрутизаторы'); константный АПИ = требуют('$API-интерфейс'); ...
$база данных DB = /сервер/ $API-интерфейс-В1 = /сервера/по API/наследие $API-интерфейс-скорость V2 = /сервера/по API/П2
В верхней части основной файл добавить:
mainDir = __dirname;
Затем использовать его в любой файл, который вам нужен:
console.log('mainDir ' + mainDir);
mainDir
определяется глобально, если вы нужны ей только для текущего файла - используйте `__каталог вместо.main.js
, index.js
, gulpfile.js
.Добавить это где-то к началу основного файла приложения (напр. app.js):
global.__basedir = __dirname;
Это задает глобальную переменную, которая всегда будет соответствовать вашим приложением'с базы реж. Использовать его как и любую другую переменную:
const yourModule = require(__basedir + '/path/to/module.js');
Простой...
Вы можете просто добавить корневой каталог в экспресс переменной приложение и получить этот путь от приложения. Для этого добавить приложение.набор('корневой каталог каталог', __каталог); в index.js или app.js файл. И использовать запрос.приложение.вам('корневой каталог каталог')` для получения корневой каталог в коде.
если вы хотите определить корень проекта от запущенного приложения Node.js вы можете просто слишком.
процесс.mainModule.путь
Это будет делать:
path.join(...process.argv[1].split(/\/|\\/).slice(0, -1))
process.mainModule.paths
.filter(p => !p.includes('node_modules'))
.shift()
Вам все пути в основные модули и отфильтровать тех, с "папки node_modules" и, тогда вам первый из оставшегося списка путей. Неожиданное поведение не выдает ошибку, просто "неопределенным".
Работает хорошо для меня, даже при вызове, т. е. $ мокко
.