ECMAScript 提案:JSON 模块
为什么我们要像模块一样导入 JSON?
很长一段时间以来,各种捆绑器(例如 webpack)允许我们像导入 ECMAScript 模块一样导入 JSON 数据。JSON 模块将其转化为标准功能。
为什么这么有趣?它提供了一种方便的使用方式,例如在我们的应用程序中使用配置数据。例如,以下文件结构:
my-app/
src/
config-data.json
main.mjs
my-app/src/config-data.json 如下所示:
{
"appName": "My App"
}
这是my-app/src/main.mjs:
import configData from './config-data.json' assert {type: 'json'};
console.log(`I am ${configData.appName}!`);
从assert到结束的语法称为导入断言。JSON 模块是创建导入断言的用例之一。
JSON 模块的默认导出包含 JSON 数据。没有命名的导出。
通过获取 JSON 数据fetch()
如果没有 JSON 模块,我们将不得不使用fetch():
async function fetchConfigData(relativePath) {
const urlOfConfigData = new URL(
relativePath, import.meta.url); // (A)
const response = await fetch(urlOfConfigData.toString()); // (B)
const json = await response.json(); // (C)
return json;
}
const configData = await fetchConfigData('config-data.json');
console.log(`I am ${configData.appName}!`);
我们正在使用两个相对较新的功能:
- Fetch API,一种基于 Promises 的API,用于下载 JavaScript 代码中的文件(B 行和 C 行)。
- 模块元数据属性
import.meta.url(A 行)。
fetch() 与 JSON 模块相比有两个缺点:
- 代码稍微复杂一些。
- Node.js 目前没有对
fetch(). (而且我怀疑 JSON 模块将比fetch().更早得到支持。)
通过动态导入 JSON 模块import()
前面的import语句是静态的(在运行时固定)。我们还可以动态导入 JSON 模块(在运行时可更改):
async function importConfigData(moduleSpec) {
const namespaceObj = await import( // (A)
moduleSpec, {assert: {type: 'json'}});
return namespaceObj.default; // (B)
}
const configData = await importConfigData('./config-data.json');
console.log(`I am ${configData.appName}!`);
注意,所述import()操作者(A线)返回一个模块命名空间对象。这就是为什么我们.default在 B 行返回 property 的值(包含默认导出)。
为什么要额外的语法?
您可能想知道为什么我们必须在重要语句的末尾使用额外的语法:
import configData from './config-data.json' assert {type: 'json'};
为什么 JavaScript 不能通过查看文件扩展名来检测这是 JSON?
import configData from './config-data.json';
这是不可能的,因为它会导致安全问题:浏览器从不查看文件扩展名,他们查看内容类型。服务器负责为文件提供内容类型。因此,导入.json文件时可能会发生两件事:
- 我们自己的服务器可能会发送其他内容类型,
application/json并且导入会以某种方式出错。 - 如果使用外部服务器,则风险更大:如果它发送内容类型为 的文件
text/javascript,它可能会在我们的应用程序中执行代码。
因此,JavaScript 在导入 JSON 时不会依赖内容类型。
可用性
- Chrome 91 支持 JSON 模块(来源:Chrome 平台状态)。
文章链接:https://www.lilianhua.com/ecmascript-proposal-json-module.html
English (US)
Español (ES)
Português (PT)
Français (CA)
Español (MX)
Español (VE)
Español (CO)
Español (AR)
Português (BR)
Quechua (PE)
Guaraní (PY)
简体中文 (ZH)
繁體中文 (HK)
日本語 (JP)
한국어 (KR)
हिन्दी (HI)
Pilipino (PH)
ไทย (TH)
Tiếng Việt (VN)
Bahasa Melayu (MY)
Bahasa Indonesia (ID)
বাংলা (BD)
اردو (PK)
සිංහල (LK)
ភាសាខ្មែរ (KH)
English (UK)
Français (FR)
Deutsch (DE)
Italiano (IT)
Русский (RU)
Nederlands (NL)
Türkçe (TR)
Polski (PL)
Svenska (SE)
Norsk (NO)
Dansk (DK)
Suomi (FI)
Ελληνικά (GR)
Čeština (CZ)
Magyar (HU)
Română (RO)
Български (BG)
Српски (RS)
Українська (UA)


