Skip to content

Node v22 中 JSON 导入报错 SyntaxError: Unexpected identifier 'assert' 的解决方法

问题描述

在升级到 Node.js v22 后,代码中导入 JSON 文件的语句:

javascript
import config from "./some-config-file.json" assert { type: "json" };

会引发以下错误:

SyntaxError: Unexpected identifier 'assert'
    at compileSourceTextModule (node:internal/modules/esm/utils:337:16)
    ...其他堆栈跟踪

此问题仅出现在 Node v22 及以上版本,在 Node v21 及更早版本中相同代码可正常运行。

问题原因:Node v22 移除了对 import assert 语法的支持(原名为 "import assertions"),改用了新标准的 "import attributes" 语法。这是因为 ECMAScript 规范提案已将关键字从 assert 改为 with

解决方案

方法一:使用新语法 with(推荐适用于 Node v18.20+)

最简单直接的解决方案是将 assert 替换为 with

javascript
import config from "./some-config-file.json" with { type: "json" };

注意事项

  1. 此语法需要 Node v18.20 及以上版本
  2. 对于需要兼容 Node v16 和 v17 的项目:
    • Node v16.14 和 v17.1 支持旧版 assert 语法
    • 但 Node v16 和 v17 不支持新版 with 语法
    • 如果项目需要多版本支持,请考虑其他替代方案

方法二:使用 createRequire 加载 JSON(跨版本兼容方案)

如需保持旧版 Node 的兼容性(Node v12.2+),可使用 createRequire 方法加载 JSON:

javascript
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

const config = require('./some-config-file.json');

优点

  • 支持从 Node v12.2.0 开始的所有版本
  • 与原生 import 一样具备模块缓存机制
  • 被广泛使用(如 import-from-esm)

方法三:手动读取和解析 JSON(最低兼容方案)

使用原生 Node.js 模块手动读取和解析 JSON 文件:

javascript
import fs from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

// 获取当前模块路径
const currentDir = dirname(fileURLToPath(import.meta.url));
const configPath = join(currentDir, 'some-config-file.json');

// 异步读取并解析
const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));

同步读取版

javascript
import fs from 'node:fs';
// ...(同上路径获取)

const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));

注意事项

此方法相比原生import

  • 每次调用都会重新读取文件(无模块缓存)
  • 修改文件可能导致读取不一致
  • 需要自行处理相对路径解析

优化建议:可封装为共享模块解决缓存问题:

javascript
// json-loader.js
import { createRequire } from 'node:module';
export const loadJSON = (path) => createRequire(import.meta.url)(path);

最佳实践选择指南

方案优势限制推荐场景
with语法最简洁,符合新标准需 Node v18.20+新项目/无需兼容旧版本
createRequire最佳兼容性(v12.2+),行为一致比原生稍重需兼容多个 Node 版本
手动解析兼容所有 Node 版本需手动处理路径和缓存特殊环境或学习目的

升级建议

  1. 检查项目支持的 Node 版本范围(通过 .nvmrcpackage.jsonengines 字段)
  2. 若能接受 Node v18.20 作为最低版本,优先选用 with 语法
  3. 对需要向后兼容的类库项目,建议使用 createRequire 方案

通过选择适合项目需求的解决方案,即可解决 Node v22 的 JSON 导入错误问题。