Правильный способ ссылки на файлы по отношению к корню приложения в Node.JS

У меня есть приложение Node.JS, работающее на Linux в AWS EC2, которое использует модуль fs для чтения в файлах шаблонов HTML. Вот текущая структура приложения:

/server.js
/templates/my-template.html
/services/template-reading-service.js

Шаблоны HTML всегда будут находиться в этом месте, однако служба чтения шаблонов может перемещаться в разные местоположения (более глубокие подкаталоги и т.д.). Внутри службы чтения шаблонов я использую fs.readFileSync() для загрузки файла, вот так:

var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8');

Это вызывает следующую ошибку:

Error: ENOENT, no such file or directory './templates/my-template.html'

Я предполагаю, что это потому, что путь "./" разрешается в директорию "/services/", а не в корне приложения. Я также попытался изменить путь к "../templates/my-template.html", и это сработало, но оно кажется хрупким, потому что я полагаю, что это просто решение относительно "одного каталога". Если я перемещу службу чтения шаблонов в более глубокий подкаталог, этот путь будет разорван.

Итак, каков правильный способ ссылки на файлы относительно корня приложения?

Ответ 1

Пытаться

var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8');

Ответ 2

Чтобы получить абсолютный путь файловой системы к каталогу, в котором выполняется процесс узла, вы можете использовать process.cwd(). Поэтому, предполагая, что вы запускаете /server.js как процесс, который реализует /services/template-reading-service.js в качестве модуля, вы можете сделать следующее из /service/template-reading-service.js:

var appRoot = process.cwd(),
    templateContent = fs.readFileSync(appRoot + '/templates/my-template.html', 'utf8');

Если это не сработает, вы можете запускать /service/template-reading-service.js в качестве отдельного процесса, и в этом случае вам нужно будет, чтобы все запуски, которые обрабатывали этот процесс, передавали ему путь, который вы хотите рассматривать в качестве основного приложения корень. Например, если /server.js запускает /service/template-reading-service.js в качестве отдельного процесса, то /server.js должен передать ему свой собственный process.cwd().

Ответ 3

Принятый ответ неверен. Hardcoding path.join(__dirname, '../templates') будет делать то, что не нужно, что service-XXX.js файл service-XXX.js основным приложением, если он перемещается в под-местоположение (в качестве данного примера services/template),

Использование process.cwd() вернет корневой путь для файла, инициировавшего /Myuser/myproject/server.js процесс (так, например, как возвращает /Myuser/myproject/).

Это дубликат вопроса. Определите корень проекта из запущенного приложения node.js.

В этом вопросе ответ __dirname получил надлежащее взбивание, которого он заслуживает. Остерегайтесь зеленой метки, прохожие.