《今日国外热门科技访谈播客》
Biome 与 JavaScript 工具链的下一步
中文主题
Rust 重写、统一格式化与 lint、跨文件模块图,以及为什么前端工具链正在从“可无限扩展”转向“更少配置、更强内建能力”。
基本信息
- 节目:Software Engineering Daily
- 嘉宾:Emanuele Stoppa
- 日期:2026-06-18
- 来源:Software Engineering Daily
- 链接:https://softwareengineeringdaily.com/2026/06/18/biome-and-the-future-of-javascript-tooling/?utm_source=rss&utm_medium=rss&utm_campaign=biome-and-the-future-of-javascript-tooling
一句话总结
这期访谈把 Biome 放回更长的前端工具演化史里:它不只是用 Rust 重写 Prettier/ESLint 的替代品,而是在尝试用单一二进制、模块图、类型推断和统一 LSP 体验,修正过去十多年 JavaScript 工具链在性能、配置复杂度和插件失控上的结构性问题。
Highlights
- Biome 的核心主张不是“又一个 linter”,而是把 formatter 与 linter 合并到一个 Rust 工具里,用尽量少配置替代过去 ESLint、Prettier、多插件并存的组合。
- Stoppa 认为前端工具链的老问题不是功能不够,而是插件系统给了开发者太多自由,最终把维护成本、性能负担和调试复杂度转嫁给了用户与团队。
- Biome 的差异化能力在于模块图与类型感知规则:它能在 lint 前先扫描整个项目,做跨文件分析,例如检测 import cycle、未安装依赖、未定义 CSS class。
- Biome 试图绕开对 TypeScript 编译器的硬依赖,通过类型推断实现一部分 type-aware lint 规则,这是一条与 typescript-eslint 不同的实现路线。
- 访谈里反复出现的产品哲学是“统一体验”:CLI、编辑器、LSP、未来的 go-to-definition 等能力都希望建立在同一套底层信息模型上,而不是多个工具各管一段。
长文笔记
这期最有价值的部分,不是 Biome 的功能清单,而是它背后要解决的“前端开发为什么会被工具链拖住”这个老问题。Stoppa 先从个人经历讲起:他最早做 PHP、Postgres、jQuery,后来一路走到 React、Astro、Rome、Biome。这个时间线里的一个关键判断是,很多今天被包装成新趋势的东西,本质上并不新,比如 SSR 回潮,在他看来更像是“用 JavaScript 重新做一遍当年 PHP 就在做的事情”。这个判断不是怀旧,而是在解释为什么工具链会越来越重:浏览器能力提高了,应用复杂度提高了,开发者希望更快做出更复杂的交互,于是 bundler、formatter、linter、plugin、framework 迅速堆叠,最终让“写业务代码”之外的维护工作变成真实负担。
访谈里对 bundler 的解释也很清楚。Stoppa 没有把 bundler 简化成“打包 JS”,而是把它定义成一种现代 Web 资产链接器:从页面或入口点出发,构造整个依赖树,然后决定哪些 JavaScript、CSS、图片、字体、Wasm 以及组件内嵌样式该如何被收集、排序、产出。这里最重要的不是“合并文件”本身,而是 bundler 要解决很多顺序与作用域问题。例如单文件组件里 HTML、样式、脚本共存,样式既分散又相互影响,打包器必须决定它们的合并顺序,否则最终渲染结果会错。也就是说,现代 bundler 的职责早已从“减少请求数”扩展成“理解应用结构并为浏览器生成可运行、可下载、顺序正确的资产组合”。这也是他把 bundler 视为“最难也最有回报的软件之一”的原因。
但他对插件系统的态度明显经历了变化。早期 Webpack、Rollup 一代工具强调通用性和可扩展性,任何新资产、新语法、新框架都可以靠插件接入,这在生态爆发期非常有效。问题是,插件系统的收益与代价不对称:周末做个人项目时,开发者会享受“我能接一切”的自由;可一旦进入公司生产环境,几十个插件、上千行配置、构建速度下降、排错困难,这些成本就由维护团队长期承担。Stoppa 的判断很直接:某些扩展能力当然需要,但不是所有能力都应该做成无限制插件,否则工具本身反而无法创新,因为任何核心架构改动都可能把外围生态打碎。他拿 ESLint 举例,称其插件系统是成功原因,也是今天创新受限的原因;v9 推 flat config 虽然破坏了一部分旧生态,却是为了让配置更可预测、更可调试。这一段很重要,因为 Biome 的“少配置、更多内建”并不是纯粹审美偏好,而是对插件失控后果的反应。
Rust 为什么成为这一轮工具重写的主角,访谈也给了比“更快”更完整的答案。Stoppa 提出三个原因。第一是类型与依赖层面的严格性。Rust 依赖升级和破坏性变化更容易在编译期暴露,维护者面对大量依赖时,长期负担比 JavaScript/TypeScript 小。第二是内存控制。Rome 早期在 TypeScript 中已经能工作,甚至可以自举打包自己,但内存占用高到约 8GB,这说明它碰到了 Node.js 路线在这类重负载任务上的边界。Stoppa 的意思不是 JS 不能做工具,而是当工具要长期处理大规模 AST、语义模型、跨文件扫描时,开发者需要更直接的内存管理能力。第三是 Wasm 互操作。Rust 到 Wasm 的路径成熟,适合把同一套分析能力带到浏览器、playground 和其他宿主里。也就是说,Rust 吸引工具作者并不只是“跑得快”,还包括更稳定的依赖维护、更强内存控制,以及多端复用的工程现实。
从 Rome 到 Biome 的过渡,体现的则是开源项目在资源约束下如何收缩战线。Rome 原本野心很大,想把 formatting、linting、bundling、testing 都塞进一个统一工具里;公司关闭后,社区团队保留了项目,但不得不重新命名,Biome 这个名字就来自 “second Rome” 的概念转换。更关键的是产品范围变化:因为没有足够人力,Biome 不再同时向 bundler、测试器、格式化器、linter 横向全面扩张,而是改为在 formatter 与 linter 两条线上纵向深挖。这个取舍很现实。很多开源项目的问题不在愿景太小,而在愿景太大时无法持续交付。Biome 选择先把“替代 Prettier + ESLint 的核心体验”做好,而不是继续承诺一整套全家桶。
Biome 对用户的第一层价值,是把过去分散的工具体验集中起来。Stoppa 回忆多年前配置 ESLint 与 Prettier 的痛点:装多个包、配多个插件、处理彼此兼容关系,虽然可能只花十分钟,但他认为这十分钟根本不该花。Biome 的做法是一个配置文件、默认值尽量合理、安装后尽量即用,而且 CLI 与编辑器表现一致。它甚至会识别 Git 忽略文件,不去格式化这些文件;也能与 editorconfig 协作,减少重复维护配置。这些功能单看都不惊艳,但合起来针对的是工具链最真实的摩擦成本:并不是每个团队都在乎 formatter 快 10%,但几乎每个团队都在乎 onboarding 是否少踩坑、CI 是否稳定、编辑器与命令行是否结果一致。
Biome 的第二层价值在于它把 lint 从“单文件检查器”升级为“项目级分析器”。Stoppa 在访谈中多次强调 module graph,这是理解 Biome 差异化的核心。传统规则往往只看当前文件 AST,而 Biome 在 lint 前可以扫描整个项目,把 JavaScript、CSS、Vue、Astro 等文件及其关系收集到统一的数据结构里。于是它能实现几类跨文件规则:检查 import cycle;检查代码中使用了 package.json 没有安装的依赖;检查某个 CSS class 在组件里被引用,却根本没在项目里定义过。最后这个例子尤其具体:工具先全局收集 CSS 定义,再回到组件模板或元素的 class 使用点做核验,还能展示分析过的组件树。这种能力说明 Biome 的设计已经不是“把 ESLint 规则用 Rust 重写一遍”,而是试图建立一层语言无关、资产无关的工程图谱。
在类型相关规则上,Biome 也刻意走了一条不同路线。现有 TypeScript 生态中,typescript-eslint 通过接入 TypeScript 编译器提供 no-floating-promises 之类规则,这很有用,但成本是要借助外部编译器能力。Biome 则尝试做自己的 type inference,通过扫描项目和依赖、结合模块图与语义模型,对一部分类型关系进行推断,从而在没有直接依赖 TypeScript 编译器的情况下执行某些 type-aware lint。Stoppa 举了几个例子:判断 Promise 是否被正确 await;判断某些条件判断是否多余,因为变量值实际上始终为真;修复了对 lodash 等依赖类型无法推断的 bug。这里的关键不是“Biome 已经完全替代 TS 类型系统”,访谈并没有这么说;更准确地说,是 Biome 在探索一套更轻、更可控、能覆盖高价值规则的推断方案。它能减轻部分类型规则对外部编译器的绑定,但也意味着团队要持续建设自己的推断引擎,这是长期工程。
访谈里还明确区分了 module graph 与 semantic model。前者是跨文件的、偏通用的结构,只关心谁 import 谁、谁 export 什么、文件间如何连接;后者是单文件、强语言语义的模型。比如 JavaScript 的 semantic model 要理解作用域、绑定、导出关系,CSS 的 semantic model 则可能关注选择器特异性。这种拆分很重要,因为它解释了 Biome 为什么可以同时做“跨文件扫描”和“语言专用规则”:一层负责全局关系,一层负责局部语义。未来如果支持 GraphQL 之类语言,也会沿着这个思路扩展。这比很多用户熟悉的“单个 AST + 一堆 visitor”模型更复杂,但能支持更多项目级能力。
有意思的是,Stoppa 虽然批评插件泛滥,却没有否认插件本身的必要性。Biome 现在提供基于 GritQL 的插件系统,目的是补齐“工具不能知道每个公司代码库私有约束”这一现实。比如组织内部的命名约定、特定 API 使用规范、敏感业务流程检查,这些不应硬编码进通用工具,就适合通过 DSL 写成项目专属规则。访谈提到的一项即将到来的增强,是插件不仅能报错,还能提供自动修复。这会把插件从“提示器”推进成“codemod 工具”,适用于大规模迁移,例如 React 版本升级、内部接口重构。Stoppa 自己也承认,这某种程度上“推翻了自己对插件坏处的绝对说法”,但边界变得更清楚了:通用基础能力要内建,组织特定规则才交给插件。这个划分比过去“一切都插件化”更可持续。
接下来的功能路线图也反映了 Biome 的技术积累正在从 CLI 工具向持续分析平台扩展。第一类是 watcher。Biome 底层已有文件监视机制,未来通过 lint --watch 等方式暴露出来,就能在开发者编辑文件时增量反馈问题。第二类是 Markdown 支持,团队正在追求对 CommonMark 的高覆盖度,这意味着 Biome 希望把格式化/检查能力扩展到代码库外层文档。第三类是更强的框架支持,如 Svelte lint 规则,以及可能跟进 Astro 生态。这里可以看到 Biome 并不只是瞄准纯 JS/TS 文件,而是在把“前端仓库里常见的文本资产”逐步纳入统一处理范围。
LSP 这部分值得单独看,因为它揭示了 Biome 的长期野心不是“命令行跑得快”,而是“把编辑器体验也统一起来”。Stoppa 将 LSP 解释为一种让 VS Code、Zed、JetBrains、Vim、Helix 等客户端共享同一语言服务的协议。对 Biome 来说,这意味着它可以在一个地方实现诊断、格式化、规则解释、未来的 go-to-definition,然后把同样逻辑交付给不同编辑器。更关键的是,他反复提到“我们拥有整条栈和信息模型”,所以理论上不仅能做 lint/format,还能利用模块图和语义信息实现跳转定义等 IDE 功能。换句话说,Biome 如果继续扩张,可能会从 today’s formatter/linter 进入更完整的代码智能基础设施层。这一方向是否能成,取决于时间与社区贡献,但技术路线已经很清楚:统一数据模型比功能拼装更重要。
社区部分同样提供了一个开源项目可持续性的现实样本。Stoppa 并没有把 Biome 的增长归功于单一技术选择,而是强调几件朴素但难做的事:快速响应 issue 和提问、在 Discord 保持活跃、愿意讨论而不是长期沉默、尽量维持友好氛围。他还特别强调,许多重要功能并非核心团队独自完成,例如 Markdown parser、formatter、很多修复和新特性都来自社区贡献者。对比不少开源项目“代码强但维护反馈慢”,Biome 显然把“可达性”和“有人接球”当成产品体验的一部分。对开发者来说,这意味着工具是否值得迁移,不只看 benchmark,还要看遇到问题时社区能否给出反馈。
迁移策略上,访谈给了比较实操的建议。对于大代码库,Biome 可以读取 ESLint/Prettier 配置并尽量生成对应的 Biome 配置;第一次 lint 时可以选择 suppress 现有大量告警,让迁移不是“一次性还技术债”,而是“先接管增量,再逐步清理存量”。格式化变更则建议拆成独立 PR,并配合 Git 忽略特定 revision,避免 blame 历史被纯格式化提交污染。这个建议很工程化,也说明 Stoppa 清楚真正阻碍迁移的并不是“功能够不够”,而是团队能不能用低风险方式切换。对新项目则更简单:初始化配置、接受默认值、必要时用 biome explain 在 CLI 里查规则说明。这里的产品取向依旧是减少上下文切换,让开发者少离开当前环境。
整期访谈背后的更大判断是:前端工具链下一阶段比拼的不只是速度,而是“谁能把复杂性收回到工具内部,而不是继续外包给用户配置”。过去一代工具以灵活性取胜,代价是生态爆炸、配置臃肿、性能和调试都难以收敛;Biome 试图用 Rust、统一二进制、模块图、类型推断和单一 LSP 路线,重新集中这些复杂性。这条路同样有风险:内建越多,维护者越需要持续追赶框架和语言变化;自己做类型推断,也意味着要承担正确性与边缘案例成本。但如果它能持续把高频复杂度留在工具内部,而把用户暴露面压缩到更稳定、可预测的层面,那么它针对的就不是一个局部替代品市场,而是整个 JavaScript 工具链设计哲学的再平衡。
