Rome CLIrome check命令实战:Lint、格式化与导入整理的统一检查与自动修复
【免费下载链接】toolsUnified developer tools for JavaScript, TypeScript, and the web项目地址: https://gitcode.com/gh_mirrors/to/tools
导读
本文以 Rome 仓库中 check.md 记录的终端输出为切入点,系统讲解rome check命令的定位、用法、输出格式与底层实现。rome check是 Rome(当前仓库的快照版本,命令名为rome)中一次运行即可同时完成**代码检查(lint)、格式化检查(format)与导入语句整理(organize imports)**的"一站式"命令,是日常开发与 CI 中最常使用的入口。读完本文,你将掌握rome check的全部参数、三种运行模式(只检查 / 安全修复 / 含不安全修复)、如何读懂它逐行渲染的诊断报告,以及它背后的源码调用链。
rome check是什么:一次运行,三类检查
Rome 将 JavaScript / TypeScript / JSON / JSX / TSX 等 Web 前端语言的工具链统一到了单一二进制中。在 CLI 层面,它拆分为几个命令:
rome format:仅做格式化(检查或写回);rome lint:仅做代码检查;rome check:lint + 格式化 + 导入整理三合一。
这一点可以从源码中得到印证:在 crates/rome_cli/src/execute/traverse.rs 的can_handle实现中,TraversalMode::Check模式下,只要文件支持 Lint、Format、OrganizeImports 三者之一就会被处理;而TraversalMode::Format只关心 Format,TraversalMode::Lint只关心 Lint。
具体到单个文件,crates/rome_cli/src/execute/process_file/check.rs 的check_file依次执行三个阶段:
- Lint(
lint_with_guard):运行 linter,产出规则诊断; - OrganizeImports(
organize_imports_with_guard):整理 import 语句; - Format(
format_with_guard):检查/执行格式化。
任一阶段产出错误,该文件即被标记为失败。rome check因此非常适合作为"提交前检查"与"CI 入口"。
快速上手:从一次真实的rome check输出说起
check.md记录了在项目根目录直接执行rome check的真实终端输出。这份输出同时展示了三条 lint 诊断,非常适合用来读懂 Rome 的诊断渲染格式:
$ rome check src/App.jsx:12:3 lint/jsx-a11y/altText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✖ Provide alt text when using img, area, input type='image', and object elements. 10 │ return <div className="App"> 11 │ <header className="App-header"> > 12 │ <img src={logo2} className="App-logo" /> │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 │ <p> 14 │ Edit ℹ Meaningful alternative text on elements helps users relying on screen readers to understand content's purpose within a page. src/App.jsx:12:13 lint/js/noUndeclaredVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✖ The logo2 variable is undeclared 10 │ return <div className="App"> 11 │ <header className="App-header"> > 12 │ <img src={logo2} className="App-logo" /> │ ^^^^^ 13 │ <p> 14 │ Edit ℹ Did you mean logo? - logo2 + logo src/App.jsx:2:7 lint/js/noUnusedVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✖ The import variable logo is unused. 1 │ // @jsx > 2 │ import logo from "./logo.svg"; │ ^^^^ 3 │ import "./App.css"; ℹ Unused variables are dead code and usually the result of incomplete refactoring. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✖ Found 3 problems逐段拆解这份输出,可以总结出 Rome 诊断渲染的固定结构:
头部:位置 + 规则码
每条诊断以文件:行:列与规则码开头,例如:
src/App.jsx:12:3 lint/jsx-a11y/altText—— 位置在src/App.jsx第 12 行第 3 列,触发的是jsx-a11y(可访问性)规则组下的altText规则;src/App.jsx:12:13 lint/js/noUndeclaredVariables—— 同一行第 13 列,触发js规则组的noUndeclaredVariables;src/App.jsx:2:7 lint/js/noUnusedVariables—— 第 2 行第 7 列,触发noUnusedVariables。
规则码的命名空间格式为lint/<group>/<ruleName>,这与仓库中 rome_diagnostics_categories 定义的诊断分类体系一致。上述三类规则的实现分别位于 crates/rome_js_analyze/src/aria_analyzers/(jsx-a11y 组)与 crates/rome_js_analyze/src/semantic_analyzers/(基于语义分析的 js 规则组)。
主体:错误消息 + 源码片段 + 定位标记
✖开头的加粗行是错误消息。例如altText规则要求"在使用img、area、input type='image'与object元素时提供alt文本";- 随后的代码块展示带行号的源码片段,
> 12 │指向出错行,行下方以^组成的波浪线精确圈出问题跨度。第一个诊断把整个<img ... />元素圈了出来,第二个诊断只圈住logo2标识符,第三个诊断圈住 import 中的logo变量——跨度范围完全由规则在 AST 上的定位决定; ℹ开头的浅色行是补充说明(advice)。altText的说明解释了可访问性动机:"有意义的替代文本能帮助依赖屏幕阅读器的用户理解页面中内容的作用";noUnusedVariables则提示"未使用变量属于死代码,通常是不完整重构的结果"。
修复建议与 diff 预览
第二个诊断展示了 Rome 最有价值的能力之一——建议式修复(suggested fix)。当规则能推断出修改方案时,会在诊断末尾渲染一个简单的 diff:
ℹ Did you mean logo? - logo2 + logonoUndeclaredVariables通过语义模型发现logo2与已声明变量logo高度相似,因此给出"你是不是想说logo?"的建议,并附上把logo2替换为logo的最小改动。这类"不安全"修复不会在默认模式下自动应用,需要显式使用--apply-unsafe。
汇总行
输出末尾的横线之下是汇总:✖ Found 3 problems。当存在问题时,命令以非零退出码结束,方便接入 CI。
三种运行模式:检查、安全修复、含不安全修复
rome check默认只报告问题,不修改文件。需要自动修复时,使用--apply或--apply-unsafe。两者在命令入口 crates/rome_cli/src/commands/check.rs 中被翻译为不同的FixFileMode:
| 命令 | FixFileMode | 行为 |
|---|---|---|
rome check | 无 | 只检查,报告诊断,不写文件 |
rome check --apply | SafeFixes | 应用安全修复与格式化(SafeFixes) |
rome check --apply-unsafe | SafeAndUnsafeFixes | 应用安全修复 +不安全修复,并执行格式化与导入排序 |
--apply与--apply-unsafe互斥,同时传入会直接报错(源码中CliDiagnostic::incompatible_arguments("--apply", "--apply-unsafe"))。
为什么区分"安全"与"不安全"?因为部分修复可能改变代码语义。以noUnusedVariables为例:移除一个未使用的 import 通常是安全的;但像noUndeclaredVariables给出的"把logo2改成logo"这种建议,虽然大概率是开发者想要的,却无法保证 100% 正确,因此归入不安全修复。这一点在官方文档中也有对应说明,例如 website/src/pages/linter/index.mdx 演示了rome check --apply ./src与rome check --apply-unsafe ./src两种用法。
导入整理(organize imports)的差异同样可以在源码中确认:在 crates/rome_cli/src/execute/process_file/organize_imports.rs 中,只有当处于is_check_apply_unsafe()模式时才会把排序后的代码写回文件,否则仅产生一个 Diff 消息。也就是说,默认的rome check会提示 import 顺序问题,--apply不会自动排序,只有--apply-unsafe才会执行导入排序并写回。
当以 apply 模式运行且修复后仍有遗留错误时,CLI 会给出ApplyError诊断;traverse.rs中还会打印提示语:"If you wish to apply the suggested (unsafe) fixes, use the commandrome check --apply-unsafe"。
完整参数与配置说明
rome check的官方参数说明记录在 website/src/pages/cli.md 的# rome check一节,完整整理如下。
命令特有选项
rome check [--apply] [--apply-unsafe] [PATH]...| 选项 | 说明 |
|---|---|
--apply | 应用安全修复与格式化 |
--apply-unsafe | 应用安全修复与不安全修复,执行格式化与导入排序 |
--formatter-enabled=<true\|false> | 开关检查中的格式化阶段 |
--linter-enabled=<true\|false> | 开关检查中的 linter 阶段 |
--organize-imports-enabled=<true\|false> | 开关导入整理阶段 |
--stdin-file-path=PATH | 从标准输入读取代码,并用该路径(含扩展名)决定解析语言,例如echo 'let a;' \| rome check --stdin-file-path=file.js |
-h, --help | 打印帮助信息 |
三个*-enabled开关在 check.rs 中会覆盖rome.json里的对应配置项(formatter.enabled、linter.enabled、organize_imports.enabled),实现"命令行优先"的按需裁剪。
来自 rome.json 的配置项(可被 CLI 覆盖)
rome check会读取项目根目录的rome.json。下表是check支持覆盖的配置项及其默认值:
| 配置项 | 取值 | 默认值 |
|---|---|---|
--indent-style | tab/space | — |
--indent-size | 数字 | 2 |
--line-width | 数字 | 80 |
--quote-style | double/single | double |
--jsx-quote-style | double/single | double |
--quote-properties | preserve/as-needed | as-needed |
--trailing-comma | all/es5/none | all |
--semicolons | always/as-needed | 是否所有语句都打印分号 |
--vcs-client-kind | git | — |
--vcs-enabled | true/false | 是否与 VCS 客户端集成 |
--vcs-use-ignore-file | true/false | 是否使用 VCS 的 ignore 文件过滤待检查文件 |
--vcs-root | 路径 | 默认使用rome.json所在目录;找不到配置时退回当前工作目录 |
--files-max-size | 数字(字节) | 1 MiB,超过此大小的文件为性能考虑被忽略 |
--files-ignore-unknown | true/false | 遇到未知类型文件时不发诊断 |
其中 VCS 相关选项在 check.rs 中通过store_path_to_ignore_from_vcs将.gitignore等文件中的忽略规则合并进配置,使得rome check能天然跳过被版本控制忽略的路径。
全局选项
| 选项 | 说明 |
|---|---|
--colors=off\|force | 控制 ANSI 颜色输出:off纯文本,force强制着色 |
--use-server | 连接到已运行的 Rome daemon 服务 |
--verbose | 输出更详细的诊断附加信息 |
--config-path=PATH | 指定rome.json所在目录 |
--max-diagnostics=NUMBER | 限制显示的诊断条数,默认 20 |
--skip-errors | 跳过含语法错误的文件,而不是发出错误诊断 |
--no-errors-on-unmatched | 没有文件被处理时静默而非报错 |
--json | 以 JSON 格式输出报告 |
位置参数
PATH可以是单个文件、单个目录或一组路径;不传路径且不配合--stdin-file-path时,命令会报缺少<INPUT>参数(见 traverse.rs 的missing_argument检查)。
输出与退出码:适合 CI 的设计
rome check的终端汇总由 crates/rome_cli/src/execute/traverse.rs 中的CheckResult生成,格式为:
Checked N file(s) in 12ms Found N error(s)其退出码逻辑同样位于该文件:
- 处理过程中出现错误诊断(
errors > 0)时返回CliDiagnostic::check_error,即非零退出码; - 一个文件都没处理成功(
count - skipped == 0)时返回no_files_processed,除非指定--no-errors-on-unmatched; - 若开启
--error-on-warnings相关行为,存在警告也会导致非零退出。
配合--max-diagnostics(默认 20),当诊断数量超过上限时,Rome 会折叠多余部分并提示"Diagnostics not shown: N.",避免大仓库刷屏。结合--json则可以将报告序列化为结构化数据供其他工具消费。
另外,rome check的渲染还支持富文本 markup(rome_console的markup!宏体系,见 crates/rome_console/src/markup.rs),终端下以颜色区分错误(红)、信息(蓝)、警告(黄);--colors=off可切为纯文本以便重定向。
从标准输入检查:管道友好
rome check支持不落盘检查:将代码通过管道喂入,并用--stdin-file-path告知 Rome 该代码的文件名与扩展名(决定解析器语言):
echo 'let a;' | rome check --stdin-file-path=file.js echo '<img src={logo2} />' | rome check --stdin-file-path=App.jsx在 check.rs 中,若指定了stdin_file_path但管道没有实际输入,命令会报missing_argument("stdin", "check");读取成功后,输入内容会随TraversalMode::Check一起进入execute_mode处理。
源码级原理:一次rome check的完整调用链
把前面散落的源码证据串起来,一次rome check的完整流程是:
- 入口:crates/rome_cli/src/commands/check.rs 的
check函数解析--apply/--apply-unsafe得到FixFileMode; - 配置:
load_configuration读取rome.json,命令行开关覆盖formatter.enabled、linter.enabled、organize_imports.enabled,随后把 VCS 忽略文件合并进配置并update_settings写入 workspace; - 遍历:crates/rome_cli/src/execute/traverse.rs 用 Rayon 线程池并发遍历输入路径,
can_handle依据file_features判断每个文件支持哪些功能; - 逐文件处理:crates/rome_cli/src/execute/process_file/check.rs 的
check_file依次执行lint_with_guard→organize_imports_with_guard→format_with_guard,把诊断消息推入 channel; - 渲染与退出:控制台线程消费消息,按
--max-diagnostics限额渲染诊断,最终汇总 "Checked N file(s)" 与 "Found N error(s)",并根据错误数决定退出码。
规则诊断的产生则由 crates/rome_js_analyze 完成:语法分析基于 crates/rome_js_parser,语义信息(未声明变量、未使用变量等)依赖 crates/rome_js_semantic 构建的语义模型。altText这类可访问性规则位于aria_analyzers,noUndeclaredVariables、noUnusedVariables这类依赖语义分析的规则位于semantic_analyzers。
测试验证:行为都有用例背书
Rome 为rome check建立了系统的 CLI 快照测试,位于 crates/rome_cli/tests/commands/check.rs,覆盖了:
check --help帮助输出快照;- 干净文件通过(含只读文件系统场景);
- 语法错误(
parse_error)时输出错误诊断; noDebugger、noUndeclaredVariables、noUnusedVariables等规则的检查与--apply/--apply-unsafe修复前后内容对比(如FIX_BEFORE/FIX_AFTER、APPLY_SUGGESTED_BEFORE/APPLY_SUGGESTED_AFTER);- 通过
rome.json配置禁用 linter、忽略文件、升降级诊断严重级别等组合场景。
这些测试印证了本文所述的参数行为与输出格式,读者在修改或扩展 check 逻辑后,可直接运行该测试文件中的用例回归验证。
小结
rome check是 Rome 工具链中"一处入口、三类检查"的核心命令:默认只读地报告 lint、格式化与导入整理问题;--apply安全修复;--apply-unsafe进一步应用建议式修复并执行导入排序。它的诊断输出以"位置 + 规则码 + 源码片段 + 定位标记 + 修复 diff"的结构化格式呈现,--max-diagnostics、--json、--stdin-file-path等选项使其既能面向开发者终端,也能无缝嵌入 CI 与编辑器。无论是阅读诊断、配置规则,还是深入源码扩展行为,本文梳理的命令、配置与调用链都可以作为你的起点。
【免费下载链接】toolsUnified developer tools for JavaScript, TypeScript, and the web项目地址: https://gitcode.com/gh_mirrors/to/tools
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考