ECMAScript 提案:JSON modules
ECMAScript 模块系统(import
和 export
关键字)默认仅可以引用 JavaScript 代码。
但是一个实用的例子是存储应用的配置数据在 JSON 文件中,这样的话,我们想要在 ES 模块中直接引用 JSON 文件。
一直以来,commonjs 模块支持引用 JSON 文件格式。幸运的是,名为 JSON modules 的新提案处于 stage 3 状态,使得直接在 ES 模块中导入 JSON 文件成为可能。让我们看看 JSON 模块如何运行。
直接引用 JSON 文件
让我们尝试引用一个名为 config.json
的 JSON 文件,其中包含一个应用必须的配置信息:名称和当前版本。
{
"name": "My Application",
"version": "v1.2"
}
如何在 ES 模块中引用 config.json
?
举例来说,让我们创建一个简单的 web 应用,从 JSON 配置文件中渲染出应用的名称和版本。
如果你尝试在 Node.js 中直接引用 config.json
,将会抛出一个错误:
import http from 'node:http'
import config from './config.json'
http
.createServer((req, res) => {
res.write(`App name: ${config.name}\n`)
res.write(`App version: ${config.version}`)
res.end()
})
.listen(8080)
当尝试运行这个应用,Node.js 抛出一个错误 TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".json"
。
Node.js 使用 import
声明的时候默认导入的是 JavaScript 代码。但是感谢 JSON modules 提案,现在你可以直接从 JSON 中引用数据。
在修复这个应用的错误之前,让我们通过一些章节来了解 JSON modules 提案是什么。
JSON modules 提案
JSON modules 提案的本质是允许在 ES 模块中通过标准的 import
声明引用 JSON 数据文件。JSON 内容通过 import 断言引用:
import jsonObject from "./file.json" assert { type: "json" }
assert { type: "json" }
是一个 import 断言标识模块应该作为 JSON 解析和引用。
jsonObject
变量包含解析 file.json
内容的 JavaScript 对象。
JSON 模块也可以动态导入:
const { default: jsonObject } = await import("./file.json", {
assert: {
type: "json",
},
})
当一个模块被动态引入,包括 JSON 模块,default content default
属性变为可用。
在上面的用例中 import 断言指定一个 JSON 类型。然而,这是一个更加通用的提案 import assertions 支持引入很多格式的数据,例如 CSS 模块。
允许 JSON modules 模块
现在,让我们结合 JSON 模块和上面的 web 应用:
import http from "http"
import config from "./config.json" assert { type: "json" }
http
.createServer((req, res) => {
res.write(`App name: ${config.name}\n`)
res.write(`App version: ${config.version}`)
res.end()
})
.listen(8080)
现在主进程引用 config.json
文件,并访问 config.name
和 config.version
的值。
JSON modules 支持运行的 Node.js 版本是 >=17.1
,同时需要设置开启 --experimental-json-modules
标记 Experimental JSON modules:
node --experimental-json-modules index.mjs
在浏览器环境中,Chrome 91 开始支持 JSON modules 模块。
总结
默认情况下,ES 模块仅支持导入 JavaScript 代码。
感谢 JSON modules 模块提案,使得可以直接在 ES 模块中直接导入 JSON 内容。仅需要在 import 声明的右侧使用 import 断言:
import jsonContent from "./file.json" assert { type: "json" }
要开始使用 JSON modules 模块,需要 Node.js 17.1 版本并开启 --experimental-json-modules
标记,或者在 Chrome 91 及以上版本中。
本文由 吳文俊 翻译,原文地址:JSON Modules in JavaScript。