
在 Nuxt 3 的服务端 API 路由中,无法直接通过 import() 动态导入 JSON 文件(如 import(filePath)),因其违反 ES 模块静态分析规则;应改用 Node.js 原生 fs.readFile 或更现代的 readFile(Promise 版本)安全读取并解析。
在 nuxt 3 的服务端 api 路由中,无法直接通过 `import()` 动态导入 json 文件(如 `import(filepath)`),因其违反 es 模块静态分析规则;应改用 node.js 原生 `fs.readfile` 或更现代的 `readfile`(promise 版本)安全读取并解析。
在 Nuxt 3 的服务端 API(即 server/api/ 下的 .ts 文件)中,开发者常需根据请求参数(如 ?path=home)动态返回对应 JSON 内容。此时直觉上会尝试使用 import(filePath, { assert: { type: 'json' } }),但该写法在运行时传入变量路径会报错:
Module "file:///.../article-1.json" needs an import assertion of type "json"
这是因为 import() 的模块说明符(specifier)必须是编译期可静态分析的字符串字面量,不支持变量、模板字符串或运行时拼接——这是 JavaScript 模块规范的硬性限制,与 Nuxt 无关。
✅ 正确解法:使用 Node.js 内置 fs 模块(服务端环境可用)异步读取并解析 JSON:
// server/api/page.get.ts
import { promises as fs } from 'fs'
import { join } from 'path'
import { defineEventHandler, getQuery } from 'h3'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const path = String(query.path || '').trim()
// ✅ 安全校验:仅允许预设的文件名,防止路径遍历攻击
const validPaths = [
'home',
'article-1', 'article-2', 'article-3',
'article-4', 'article-5', 'article-6'
]
if (!validPaths.includes(path)) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid path parameter'
})
}
try {
// ✅ 使用绝对路径 + Promise API(推荐)
const jsonPath = join(process.cwd(), 'assets', 'json', `${path}.json`)
const content = await fs.readFile(jsonPath, 'utf8')
const data = JSON.parse(content)
return data
} catch (err) {
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
throw createError({
statusCode: 404,
statusMessage: `JSON file not found: ${path}.json`
})
}
throw createError({
statusCode: 500,
statusMessage: 'Failed to load JSON file',
cause: err
})
}
})? 关键要点说明:
- 禁止拼接路径后直接 import():ES 模块不允许动态 specifier,强行使用会导致构建失败或运行时错误;
- 优先使用 fs/promises 而非回调式 fs.readFile:代码更简洁、错误处理更清晰,且避免 Promise 构造反模式(如原答案中的 new Promise(...) 包裹回调);
- 务必校验输入路径:防止 ../../../etc/passwd 类型的路径遍历(Path Traversal)漏洞;
- 使用 process.cwd() + join() 构建安全绝对路径:确保从项目根目录解析,不受工作目录影响;
- 显式错误分类处理:区分 404(文件不存在)与 500(解析失败/权限问题),提升 API 可观测性。
? 进阶建议:若 JSON 文件数量较多或需热更新,可考虑在构建时预读取并缓存(配合 useStorage 或内存 Map),但对常规场景,上述按需读取方案已足够高效、安全且符合 Nuxt 3 最佳实践。


















