代码格式化与在线运行速查表

格式化、校验、在线试跑——这三个动作覆盖了日常处理代码片段的大部分需求。本页说明它们各自的边界,并把最常吵不出结果的缩进、引号、分号等风格取舍列成对照表。

原理解析

代码格式化是统一缩进、空格、换行、引号等风格的约定。风格一致能让 diff 聚焦于「逻辑变更」而非「格式噪声」,也降低多人协作的认知负担。

现代项目多用 Prettier、gofmt、Black 等工具在保存/提交时自动格式化(format on save / pre-commit hook),把主观争论交给工具。Linter(如 ESLint)则进一步捕获潜在错误与坏味道。

什么时候该查这张表

这张表在你要为某个语言选格式化或静态检查工具时有用。它按语言列出 prettier、eslint、rustfmt、gofmt、clang-format 等工具各自做什么、典型场景与注意事项。选工具前先确认项目已有的约定。

不该查的情况:你在设计代码风格规范或讨论格式化与 lint 的职责边界。两者常被混为一谈 —— 格式化管布局(缩进、引号、换行),lint 管写法规范与潜在缺陷(未用变量、危险模式),两者可独立选型。

判断标准:先看项目已有约定。不要在既有项目里引入第二套格式化工具,那会造成大面积无意义 diff。正确做法是读项目的配置文件(.prettierrc、.eslintrc、rustfmt.toml、.editorconfig)确认现状,只有新项目或需要统一时才做选型。

特别注意格式化与 lint 的执行顺序:应先格式化再 lint。因为格式化会改变代码形态(如把单行 if 展开成多行),若顺序反了,lint 报告的行号与问题都会过时,导致编辑器里报的位置对不上。

边界与常见陷阱

  • 格式化工具与 lint 规则的职责重叠会互相打架

    典型冲突:prettier 决定用分号,eslint 的 @typescript-eslint 规则也管分号;prettier 决定换行宽度,eslint 的 max-len 也在管。两边配置不一致时,lint 报错改完又被格式化器改回去,陷入循环。解决办法是明确分工:布局类规则(indent / quotes / semi / max-len)交给 formatter 并在 lint 里关闭,语义类规则(no-unused-vars / eqeqeq)交给 lint。ESLint 有 --fix 也能缓解,但根治靠配置不重叠。

  • 首次接入格式化工具会产生大量无关 diff

    在一个从未格式化过的仓库里跑 prettier,可能改动几百个文件、上万行,此时 diff 里混着真正的逻辑修改与纯格式变更,review 变得不可能,blame 历史也被污染。规范做法是单独一个纯格式化的 commit,与功能改动分开;更稳妥的是分批格式化(每次一个目录)并配合 .git-blame-ignore-revs 标记格式提交,让 git blame 忽略它们。

  • 不同编辑器的格式化配置不一致会互相覆盖

    同一个项目里,团队成员的编辑器插件、.editorconfig、保存时格式化钩子、pre-commit 钩子各有一套配置且优先级不同,最终提交的代码与编辑器里看到的不一致。典型症状是「我明明按了保存,代码却被改成另一个样子」。根治方式是只保留一个格式化入口(pre-commit 或 CI),editorconfig 统一基础设置,编辑器插件与钩子配置保持一致并在 README 里写明。

与相邻内容的分工

要实际格式化一段代码,用站内相关工具;本页是工具选型对照。

要设计项目的代码风格规范(缩进、命名、提交信息),属工程规范范畴,本表不覆盖。

要配置 lint 规则集与 CI 检查,属持续集成范畴,与格式化是两条独立链路。

若目的是解决某个具体格式争议,先看项目现有配置文件与 .editorconfig,再讨论工具选择。

实战片段

要点:① 布局类规则(indent / quotes / semi / max-len)交给 formatter 并在 lint 里显式关闭,两边都管就会互相打架 —— lint 报错改完又被格式化器改回去,陷入循环;② 首次接入格式化工具要单独一个纯格式化 commit,必要时用 .git-blame-ignore-revs 标记,避免污染 blame;③ 执行顺序必须先格式化再 lint,否则 lint 报的行号会因格式化改变形态而过时;④ 在既有项目里绝不引入第二套格式化工具;⑤ 统一格式化入口(pre-commit 或 CI),editorconfig 管基础设置。

// ① .prettierrc —— 只管布局,不掺语义规则
{
  "semi": false,
  "singleQuote": true,
  "printWidth": 100,
  "trailingComma": "all",
  "arrowParens": "always"
}

// ② .eslintrc —— 语义规则;布局类交给 prettier 并显式关闭,避免互相打架
{
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  "prettier/prettier": "off",
  "rules": {
    "semi": "off",
    "quotes": "off",
    "max-len": "off",
    "@typescript-eslint/no-unused-vars": "error",
    "@typescript-eslint/no-explicit-any": "warn",
    "eqeqeq": ["error", "always"]
  }
}

// ③ 执行顺序:先格式化,再 lint
// package.json
{
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint . --ext .ts,.vue",
    "fix": "npm run format && npm run lint -- --fix",
    "prepare": "husky && husky install",
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{ts,vue}": ["prettier --write", "eslint --fix"]
  }
}

// ④ .git-blame-ignore-revs —— 纯格式化提交不污染 blame
// ① 找到那次格式化提交:git log --format='%H %s' | grep -i format
// ② 写进文件(每行一个 commit)
// ③ 生效:git config blame.ignoreRevsFile .git-blame-ignore-revs

// ⑤ .editorconfig —— 跨编辑器的基础约定
// root = true
// [*]
// indent_style = space
// indent_size = 2
// end_of_line = lf
// insert_final_newline = true
// charset = utf-8

实践注解

  • 格式化工具会掩盖真实的 diff未与团队对齐规则时,一次格式化提交可能改动上千行,把真正的逻辑改动淹没。落地格式化的正确顺序是:先单独提交一次「纯格式化」,之后才做功能改动,并把格式化写进 pre-commit。
  • XML 与 HTML 的「格式化」不等于「可安全往返」格式化会改动空白节点,而空白在 XML 里可能是数据的一部分(如 <pre> 内容、文本节点的尾随空格)。带语义空白的文档不应做自动重排。
  • 缩进宽度不是排版问题而是可读性协议同一仓库混用 2 与 4 空格会让编辑器自动推断出错,进而产生「只改了缩进」的噪声 diff。用 .editorconfig 统一,并让格式化器在保存时执行,比靠人自觉可靠。

数据来源

  • Language style guides (PEP 8, Google Style Guides)
  • EditorConfig specification

上述编号、名称与定义均来自公开规范,本站不主张对规范数据本身的独创性;本页的编排方式、中文释义与实践注解由本站撰写。

三类工具对照

工具做什么典型场景注意
XML 格式化重新缩进并校验 XML 结构接口报文、配置文件、SOAP 响应标签未闭合会直接报错
JS 格式化统一缩进、引号、分号与换行接手他人代码、合并前统一风格只改排版不改语义,但需确认行尾分号规则
JS 运行在浏览器里执行片段并查看输出验证正则、试算法、调试小函数运行在浏览器沙箱内,无法访问文件系统

常见风格取舍

维度选项 AA 的特点选项 BB 的特点
缩进2 空格前端主流,嵌套深时省横向空间4 空格Python 与部分后端偏好,层次更醒目
缩进空格任何编辑器显示一致Tab可自定义宽度,但混用易错乱
引号单引号JS/Python 常见,HTML 属性中更安全双引号JSON 强制要求,JSX 属性惯用
行尾加分号避免自动分号插入的边界坑不加分号更简洁,需规避以 ( [ ` 开头的行

常见问题

格式化会改变代码的运行结果吗?

正规的格式化工具只做词法层面的排版,不改变语法结构,因此不会改变运行结果。但有两个真实风险要注意。一是自动分号插入:JavaScript 在不写分号的风格下,如果一行的开头是括号、方括号或反引号,可能被解析器接上一行,格式化调整换行位置就可能触发这个问题。二是压缩与格式化是相反的操作,压缩会删掉空格和换行,如果代码依赖分号,压缩前必须先保证分号完整。稳妥做法是格式化后跑一遍测试或静态检查。

XML 和 JSON 该怎么选?

新项目默认选 JSON,除非有明确理由。JSON 更轻、类型更清晰、与 JavaScript 天然互操作,解析库也普遍更快。XML 仍有优势的场景:需要 schema 强校验、需要命名空间隔离、需要混合内容与属性、以及对接既有的企业系统(很多金融、政务接口仍是 SOAP 或 XML)。另外 XML 支持注释,JSON 标准不支持,配置文件的可读性场景有时这也是一个考虑点。

在网页里运行 JavaScript 安全吗?

看代码来源。浏览器里的执行环境本身是沙箱化的,无法读写本地文件,也不能访问同源之外的资源,所以运行自己写的片段是安全的。风险在于粘贴来历不明的代码:它可能发起网络请求把数据传走,或者利用当前页面的上下文做操作。建议只运行自己写或可信任来源的代码,涉及密钥和真实数据的场景一律不要在在线运行器里处理。

团队里缩进风格吵不出结果,怎么办?

不要靠讨论解决,用工具固化。选定一种主流风格(前端用两空格、Python 用四空格是最省事的起点),然后把规则写进编辑器配置与格式化工具的配置文件,提交到仓库里,让每次保存自动生效。关键在于自动化而不是共识:有了配置文件,新成员不需要了解争论史,工具会替团队做决定。剩下唯一要人工把关的是命名与结构,这些格式化工具管不了。