html-webpack-plugin 多语言需为每语言配独立HTML模板,避免JS动态替换;Vite中需配置resolve.alias并导出JSON为模块;lang与data-i18n必须成对更新,fallback须按BCP 47层级降级。

html-webpack-plugin 多语言模板怎么配才不漏页
单个 HTML 模板 + 多个 HtmlWebpackPlugin 实例是最稳妥的落地方式,不是“可选”,而是必须。靠 JS 动态替换文本会漏掉 <title>、<meta name="description">、<link hreflang> 这类在 DOM 渲染前就起作用的内容。
- 每个语言对应一个独立模板文件(如
src/templates/index.zh-CN.html、src/templates/index.en-US.html),避免用 JS 拼接<title>—— SEO 和 SSR 场景下这些内容必须静态存在 -
templateParameters只传纯字符串字段(title、description),别传对象或函数,否则 webpack 编译时无法序列化 - 模板里直接写
<html lang="">,而不是等 JS 运行后再改document.documentElement.lang—— 否则<title>和屏幕阅读器初始播报仍是旧语言 - 输出文件名必须带语言码:用
filename: 'index.[name].html'+chunks: ['main']配合name字段,比硬编码index.zh.html更易维护
Vite 中怎么让 i18n 资源参与构建和预加载
Vite 默认把 locales/zh-CN.json 当作普通静态资源,不会进构建图谱,导致 import('locales/zh-CN.json') 在生产环境 404 或返回空对象 —— 不是代码写错,是路径没被识别为模块。
- 在
vite.config.js中显式配置resolve.alias,把locales映射到实际路径:{ locales: path.resolve(__dirname, 'src/locales') } - 语言包必须用
export default导出,不能只写纯 JSON —— Vite 的 esbuild 对纯 .json 文件默认禁用导入,需加defineConfig({ json: { stringify: true } })或改后缀为.json.ts - 动态 import 语言包时,必须用完整路径:
import(`../locales/${lang}.json`),不能省略../—— 否则 vite 插件无法定位模块 - 若用
fetch('./locales/en-US.json'),确保public/locales/下有对应文件,且响应头含Content-Type: application/json,否则response.json()会静默失败
lang 属性和 data-i18n 怎么同步才不出错
改 document.documentElement.lang 是无效操作,浏览器根本不看它来决定文本渲染行为。真正起效的是每个元素自身的 lang 和 data-i18n* 属性,二者必须成对更新,缺一不可。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
<h1 data-i18n="welcome" lang="zh-CN">欢迎</h1>是最小合法单元;只加data-i18n不加lang→ 标点间距错乱、字体 fallback 失效;只加lang不加data-i18n→ 文本不变 - 切换语言时,要同时做两件事:遍历所有已存在的
[data-i18n]元素,调用翻译函数;再遍历所有[lang]元素,把值设为新语言码(但跳过<code lang="bash">这类明确多语言混排的) -
data-i18n-placeholder、data-i18n-title、data-i18n-alt必须显式写,data-i18n不会自动覆盖这些属性 —— 常见错误是 placeholder 还是英文,但按钮文字已切中文 - 动态插入的 DOM(如 AJAX 弹窗)插入后必须立即执行
i18n.translate(element),不能依赖 MutationObserver —— 它监听不到data-i18n属性变化,只管节点增删
语言包加载失败时 fallback 怎么写才真兜得住
绝大多数线上故障不是键名写错,而是 fetch 返回 404 或 MIME 类型错误导致 response.json() 抛异常,然后整个页面留白 —— 用户看到的是空格或原始键名,不是降级文案。
立即学习“前端免费学习笔记(深入)”;
- fetch 必须包 try/catch,捕获
TypeError: Failed to fetch和error.name === 'TypeError'(网络断开)、response.status === 404(文件缺失)两类情况 - fallback 优先级链必须严格:先试完整 BCP 47 码(
zh-HK),再截主语言(zh),最后用内置默认对象(硬编码英文键值对),不能直接 fallback 到en-US—— 用户语言是zh-TW却 fallback 到美式英语,体验断裂 - 语言包 JSON 必须扁平结构,禁止嵌套对象;键名全部小写+下划线;缺失键必须保留(
"nav_help": "[未翻译]"),否则 JS 查找返回undefined,DOM 文本变成"null" - 服务端返回语言包时,响应头必须含
Content-Type: application/json,否则 Chrome 120+ 会拒绝解析,静默返回空对象
lang 和 data-i18n 的耦合关系 —— 少标一个属性,就有一处用户看不见的 bug。


















