纯前端 HTML + JavaScript 即可实现在线 SQL 格式化工具,通过 <script> 引入 jsDelivr CDN 上的 sql-formatter@14.1.0 UMD 版本,全局获得 sqlFormatter 对象,调用 sqlFormatter.format(sql, {language: 'mysql', indent: ' ', keywordCase: 'upper'}) 即可完成格式化,无需后端、不发请求、不传数据;需显式指定 language 防止语法解析错误,并预清理不可见 Unicode 字符。

纯前端 HTML + JavaScript 就能做出可用的在线 SQL 格式化工具,不需要后端、不发请求、不传数据到服务器——关键在于用成熟的开源格式化库(如 sql-formatter)在浏览器里直接处理字符串。
怎么把 sql-formatter 集成进 HTML 页面
它不依赖 Node.js,提供浏览器可用的 UMD 版本,直接通过 <script> 引入即可使用。CDN 地址选官方推荐的 jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/sql-formatter@14.1.0/dist/sql-formatter.min.js"></script>
引入后全局会挂载 sqlFormatter 对象,调用 sqlFormatter.format() 即可格式化 SQL 字符串。
- 注意版本号要写明确,避免 CDN 缓存旧版导致行为异常(比如 v13 和 v14 对窗口函数、CTE 的处理逻辑有差异)
- 如果页面已用模块化构建(如 Vite),改用
import { format } from 'sql-formatter'更稳妥 - 不要用 unpkg,它的缓存策略不稳定,偶发 404 或返回空内容
format() 的常用参数和避坑点
默认行为对简单 SELECT 很友好,但遇到复杂语句(带注释、嵌套子查询、方言关键字)容易换行错乱或缩进塌陷。必须显式传配置对象:
立即学习“前端免费学习笔记(深入)”;
sqlFormatter.format(sql, {
language: 'postgresql', // 或 'mysql' 'mssql' 'snowflake',影响关键字高亮和语法解析
indent: ' ', // 两个空格,别用 '\t'(某些终端/编辑器显示不一致)
keywordCase: 'upper', // 'lower' 也行,但保持统一;设为 'preserve' 会保留原始大小写(不推荐)
linesBetweenQueries: 1 // 多语句间空一行,设 0 会挤在一起
});-
language必须设,否则默认按标准 SQL 解析,ILIKE(PostgreSQL)、TOP(SQL Server)会被误判为语法错误 - 如果用户粘贴的是带反引号的 MySQL 表名(
`user_info`),不指定language: 'mysql'会导致格式化失败并抛出SyntaxError - 传入 null 或空字符串会静默返回空字符串,建议加
if (!sql?.trim()) return ''提前拦截
HTML 结构和交互怎么写才稳
核心是两个 <textarea>:一个输入,一个输出,加一个按钮触发格式化。别用 contenteditable 或富文本组件——SQL 里有大量 < > &,容易被 HTML 解析器转义。
- 输入框设
spellcheck="false"关闭拼写检查,避免下划线干扰 - 输出框用
readonly而非disabled,否则 CSS 里无法用:read-only控制样式 - 按钮点击后立即
disabled,防止连点触发多次(大 SQL 可能卡顿 200ms+) - 不要监听
input实时格式化——用户敲SELECT * FRO还没打完就报错,体验极差
为什么不用自己写正则来格式化
有人试图用几条 replace() 模拟缩进,结果:SELECT a, b FROM t WHERE x IN (SELECT y FROM u) 里的括号层级、逗号分隔、AND/OR 对齐全乱套。SQL 是上下文相关语言,词法分析必须递归下降。
- 正则无法识别嵌套括号深度,
(a = (b + c))和(a = b) OR (c = d)结构完全不同 - 不同数据库的保留字冲突(如
order在 MySQL 是关键字,在 PostgreSQL 是普通标识符)需要完整语法树支持 -
sql-formatter内部用 nearley.js 生成 parser,已覆盖 95% 以上真实生产 SQL 场景
真正难的不是接入,而是处理用户粘贴进来的“脏 SQL”:含 ANSI 转义序列、混合编码 BOM、不可见 Unicode 空格(如 \u200b)。这些字符会让 format() 报错且不提示原因——得在调用前先做 sql.replace(/[\u200B-\u200D\uFEFF]/g, '') 清理。


















