当前位置:首页 > 文章列表 > 文章 > 前端 > JavaScript import attributes 怎样加载 JSON 模块

JavaScript import attributes 怎样加载 JSON 模块

来源:17golang原创 2026-10-21 18:14:08 0浏览 收藏

如果你是在原生浏览器模块或 Node ESM 中加载 JSON,最稳妥的写法是把类型写在导入属性里:import data from "./data.json" with { type: "json" };。浏览器还要求脚本本身是模块,并且 JSON 响应的 MIME 类型应为 application/json。Vite 这类构建工具则会在构建阶段接管 JSON 文件,所以它的写法和原生运行时不能直接互换。

记住一句话:原生环境用 with { type: "json" } 明确告诉运行时“这是 JSON”;Vite 项目里不写 with 也可能正常,是因为 JSON 已经被构建器转换进模块图。

一、先看触发信号:你到底在哪个环境加载 JSON

我排查这类问题时,第一步不是修改语法,而是确认代码最终由谁加载。直接挂在 HTML 的 中,属于浏览器原生模块;带 "type": "module" 的 Node 项目或 .mjs 文件,属于 Node ESM;经过 Vite 开发服务器和生产构建的源码,则由构建器先处理。

这三个环境都写着 import,但 JSON 的“类型检查发生在哪里”并不相同。原生浏览器按照响应的 MIME 类型识别模块,文件名后缀不能代替服务端返回头;Node ESM 也把 JSON 的 type 属性视为必需条件。Vite 的 JSON 章节则明确提供了直接导入和根字段命名导入,这属于它的构建能力。

因此,看到下面这些信号时先停一下:浏览器报“期望 JavaScript 模块却收到 application/json”,Node 报缺少 JSON 类型属性,或者 Vite 中同一份 JSON 可以直接写命名导入。它们不是同一个故障。

二、原生环境的最小写法:给 JSON 标明类型

在浏览器原生模块里,准备一个与脚本同源的 data.json:

{
  "name": "Shilpa",
  "theme": "light"
}

然后在模块脚本中使用默认导入。JSON 模块只有一个默认导出,不能把对象字段直接当成 ES 命名导出:

服务端还要把这个文件作为 application/json 返回。with 属性会让运行时按 JSON 资源发起请求并检查媒体类型;如果服务器误返回 text/javascript,导入应失败,而不是把 JSON 文件当成代码执行。

原生 JavaScript JSON 模块的脚本类型、MIME 与默认导出关系图
图1:原生 JavaScript 加载 JSON 时,模块脚本、with 属性、MIME 与默认导出的静态关系示意图,不是截图,也不是运行证据。

三、需要按需读取时,用动态 import 的第二个参数

配置只在某个页面分支真正打开时才需要,可以用动态导入。属性不写在路径字符串里,而是放到第二个参数的 with 对象中:

async function loadThemeConfig() {
  // 动态导入仍然要明确 JSON 类型
  const module = await import("./theme.json", {
    with: { type: "json" },
  });

  // JSON 模块的值位于 default,而不是任意命名导出
  return module.default;
}

loadThemeConfig().then((config) => {
  // 只在配置加载成功后使用主题字段
  document.documentElement.dataset.theme = config.name;
});

静态导入和动态导入都会被当前环境缓存。如果你要读取“每次请求都可能变化”的积分、新闻或后台配置,不要把动态 import() 当成实时接口;应使用 fetch(),再根据响应处理 JSON。动态导入的优势是延后加载模块,不是绕过缓存。

四、Vite 为什么可以省略 with:它接管了构建阶段

在 Vite 源码中,下面这种写法是官方文档展示的能力:

// Vite 在构建阶段把 JSON 转成模块
import config from "./config.json";

// Vite 还支持根字段命名导入,适合只使用少量字段
import { apiBase } from "./config.json";

console.log(config.mode, apiBase);

这并不表示浏览器原生 import 忽然允许省略属性。开发阶段由 Vite 解析文件、生成可供模块图使用的代码;生产构建后,浏览器看到的是构建产物和普通 JavaScript 模块。Vite 的命名导入也是构建器提供的便利,不能据此推断原生 JSON 模块拥有同样的命名导出。

我通常按下面的边界做选择:如果代码直接交给浏览器或 Node 加载,保留 with { type: "json" };如果代码只在 Vite 管理的源码图中,按项目现有约定使用直接导入;如果同一段源码既要被原生运行又要被 Vite 打包,则优先统一成默认导入,并把环境差异写进构建约定,而不是让调用方猜。

浏览器 Node 原生运行时与 Vite 构建器 JSON 导入边界对比图
图2:原生运行时与 Vite 构建器处理 JSON 导入的边界对比示意图,不是截图,也不是运行证据。

五、按错误信号处理:修语法、修 MIME,还是改用 fetch

浏览器提示模块类型不匹配:先检查 HTML 是否使用了 type="module",再检查 JSON 响应的 Content-Type 是否为 application/json,最后确认静态导入带有 with { type: "json" }。文件名写成 .json 不能替代这三项。

旧代码还在写 assert { type: "json" }:导入属性的前一版语法使用过 assert,当前文档以 with 为标准写法。不要把两种语法拼在一起;按目标运行时和构建链的当前文档统一替换。

Node 报 JSON 类型缺失:确认项目处于 ESM 模式,并把静态或动态导入都改成带 type: "json" 的形式。Node 的原生规则与 Vite 的源码转换规则不能互相证明。

数据会变化却读到旧值:模块导入有生命周期内的缓存语义。把实时数据改成 fetch(),在请求后调用 response.json();不要通过给 URL 随意追加查询参数来掩盖数据来源和缓存策略。

六、最后用一张表做值班式复盘

场景推荐写法优先检查
浏览器原生模块import data from "./data.json" with { type: "json" }module 脚本、MIME、同源/CORS
Node ESM静态或动态导入都带 type: "json"ESM 模式、属性语法、文件路径
Vite 源码按 Vite 规则直接导入 JSON构建器版本、命名导入是否只是构建能力
实时数据fetch() 后解析 JSON缓存、请求失败、响应类型

把“原生加载”和“构建时转换”分清后,with { type: "json" } 就不再是需要死记的特殊符号:它是原生模块的类型边界;而 Vite 的省略,是构建器替你完成了文件转换。

相关问题

JSON 模块能否直接写 import { name } from "./data.json"?在原生 JSON 模块语义里不要这样写,使用默认导出后再读取字段;Vite 的命名导入是构建器能力。

什么时候应该放弃 import,改用 fetch?当数据需要按请求刷新、需要处理 HTTP 状态码,或不应被模块缓存生命周期绑定时,使用 fetch() 更清楚。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
IntersectionObserver 怎样按可见性加载内容IntersectionObserver 怎样按可见性加载内容
上一篇
IntersectionObserver 怎样按可见性加载内容
CSS color-mix 怎么按主题色生成悬停和禁用颜色
下一篇
CSS color-mix 怎么按主题色生成悬停和禁用颜色
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    581次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    620次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    651次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    616次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    432次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码