html-validate 是防止 dom 结构被篡改的第一道防线,必须在构建前执行;本地开发用 htmlhint 实时校验,ci/cd 中需前置 html-validate 检查并自定义 element-permitted-content 规则;html 压缩须谨慎,避免破坏 inline svg 和 source map。

打包后的 HTML 代码质量,不是靠手写规范能兜住的,而是由转译链路中每个环节是否介入、是否配置正确决定的。没配 html-validate 就上线,等于把结构合法性交给浏览器静默修正——你写的
html-validate 必须跑在构建命令之前
它不是“锦上添花”的 lint 工具,而是防止 DOM 结构被篡改的第一道防线。很多团队把它塞进 CI 后期或 PR 检查,结果错误 HTML 已合入主干,修复成本翻倍。
- 本地开发时:VS Code 安装 HTMLHint 插件,启用
tag-pair和element-permitted-content规则,保存即报错 - CI/CD 中:在
vite build或webpack命令前加npx html-validate src/**/*.html,失败直接中断流程 -
element-permitted-content必须自定义:默认规则对p标签放行所有内容,形同虚设;应显式声明"p": ["#text", "br", "span", "em"]
vite-plugin-html 的 transformHtml 钩子别乱用 minify
Vite 默认不处理 HTML 构建,build.minify: 'terser' 只压 JS,压 HTML 必须靠插件。但 vite-plugin-html 的 transformHtml 若直接调 html-minifier-terser,容易踩坑。
- 压缩会删空格和换行,导致 source map 对不上;只应在
mode === 'production'时启用 -
collapseWhitespace: true会破坏 inline SVG 内部空格,混合应用中必须关掉或用ignoreCustomFragments: [/<!--[\s\S]*?-->/, /<svg>/]</svg> - 别写成
%VITE_API_BASE%这种错格式,正确是,否则变量残留成字符串
webpack 的 html-webpack-plugin template 路径必须相对
template 设成绝对路径(如 /src/index.html)或 URL,Webpack 就无法监听变更,热更新失效,缓存也绕过——你改了 HTML,页面就是不刷新。
- 正确写法:
template: 'src/index.html'或统一放public/index.html,再配template: 'public/index.html' -
chunks必须显式列出:chunks: ['main', 'vendor', 'polyfill'];chunks: 'all'会把懒加载 chunk 全塞进去,首屏体积暴增 -
minify.removeRedundantAttributes: false必开——否则<meta charset="utf-8">的charset属性被删,Cordova / Capacitor 里中文直接乱码
别指望 Babel 或 ESLint 直接校验 HTML 结构
Babel 的 AST 解析器只认 JS/TS,硬喂 HTML 文件会报 path.node is undefined;ESLint 原生看不懂 <main></main> 是否嵌套、<h2></h2> 是否跳级。
- 真正起作用的是
html-validate(基于 parse5)、remark-lint(Markdown → HTML 流程前校验)、eslint-plugin-jsx-a11y(补aria-拼写和role值校验) - 脚手架模板里预置的
<header><nav><main><footer></footer></main></nav></header>看似规范,但开发者一删<nav></nav>或把<main></main>包进组件,就违反<main></main>只能出现一次的硬规则 - 动态插入 HTML 时,禁用
innerHTML;用insertAdjacentHTML('beforeend', htmlStr),避免重置已绑定的事件监听器
最易被忽略的点:所有校验和压缩逻辑,都只在构建阶段生效;开发时关掉压缩、开着 HTMLHint 实时标红,才是平衡调试体验与质量控制的实际做法。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











