我在AWS EC2上的Linux上运行了一个Node.JS应用程序,该应用程序使用fs模块读取HTML模板文件.以下是该应用程序的当前结构:
/server.js
/templates/my-template.html
/services/template-reading-service.js
Run Code Online (Sandbox Code Playgroud)
HTML模板将始终位于该位置,但是,模板读取服务可能会移动到不同的位置(更深的子目录等).在模板读取服务中,我使用fs.readFileSync()来加载文件,像这样:
var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8');
Run Code Online (Sandbox Code Playgroud)
这会引发以下错误:
Error: ENOENT, no such file or directory './templates/my-template.html'
Run Code Online (Sandbox Code Playgroud)
我假设这是因为路径'./'正在解析到'/ services /'目录而不是应用程序根目录.我也尝试将路径更改为'../templates/my-template.html'并且有效,但它看起来很脆弱,因为我认为这只是相对于"向上一个目录"进行解析.如果我将模板读取服务移动到更深的子目录,那么该路径将会中断.
那么,相对于应用程序根目录引用文件的正确方法是什么?
gre*_*zap 29
要获取运行节点进程的目录的绝对文件系统路径,可以使用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');
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,那么您可能将/service/template-reading-service.js作为一个单独的进程运行,在这种情况下,您将需要进行任何启动,该进程将其作为主要应用程序处理的路径传递给它根.例如,如果/server.js将/service/template-reading-service.js作为一个单独的进程启动,那么/server.js应该将它自己的process.cwd()传递给它.
Ins*_*dJW 26
尝试
var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8');
Run Code Online (Sandbox Code Playgroud)
小智 18
接受的答案是错误的.硬编码path.join(__dirname, '../templates')将完全执行不需要的操作,service-XXX.js如果文件移动到子位置(如给定示例services/template),则使文件中断主应用程序.
使用process.cwd()将返回启动正在运行的进程的文件的根路径(因此,例如/Myuser/myproject/server.js返回/Myuser/myproject/).
这是问题的副本从运行的node.js应用程序确定项目根目录.
在那个问题上,__dirname答案得到了应有的正确鞭打.提防绿色标记,路人.
对于 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 content1 = fs.readFileSync(relativePath('./file.xyz'), 'utf8') // same dir
const content2 = fs.readFileSync(relativePath('../file.xyz'), 'utf8') // parent dir
Run Code Online (Sandbox Code Playgroud)