40

我有一个在 AWS EC2 上的 Linux 上运行的 Node.JS 应用程序,它使用 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”并且有效,但它似乎很脆弱,因为我想这只是相对于“向上一个目录”进行解析。如果我将模板阅读服务移动到更深的子目录,则该路径将中断。

那么,相对于应用程序的根目录引用文件的正确方法是什么?

4

4 回答 4

37

尝试

var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8');
于 2012-10-24T15:06:43.530 回答
33

要获取运行节点进程的目录的绝对文件系统路径,可以使用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() 传递给它。

于 2012-10-25T00:53:27.730 回答
21

接受的答案是错误的。硬编码path.join(__dirname, '../templates')将完全做不想要的事情,service-XXX.js如果文件移动到子位置(如给定示例services/template),则使文件破坏主应用程序。

Usingprocess.cwd()将返回启动运行进程的文件的根路径(因此,例如 a/Myuser/myproject/server.js返回/Myuser/myproject/)。

这是问题从正在运行的 node.js 应用程序确定项目根目录的副本。

在那个问题上,__dirname答案得到了应有的鞭打。当心绿色标记,路人。

于 2014-05-28T10:52:26.957 回答
5

对于 ES 模块,__dirname不可用,因此请阅读此答案并使用:

import { resolve, dirname, join } from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs'

const relativePath = a => join(dirname(fileURLToPath(import.meta.url)), a)

const pathToFileInSameDirectory   = relativePath('./file.xyz')
const pathToFileInParentDirectory = relativePath('../file.xyz')

const content1 = fs.readFileSync(pathToFileInSameDirectory,   'utf8')
const content2 = fs.readFileSync(pathToFileInParentDirectory, 'utf8')
于 2020-03-24T20:01:31.940 回答