Fi让 Ruby 风格的 DSL 在浏览器里活起来

在前端开发的世界里,JavaScript 几乎是不可避开的核心语言。但 Basecamp(你可能知道他们的产品:Basecamp 项目管理工具、Hey 邮箱)长期坚持一个理念:

能不用 JS,就尽量不用 JS。

Fizzy 这个项目,就是在这种理念下诞生的。

它不是一个框架,不是一个 UI 库,而是一个非常特别的工具:
Fizzy 让你可以用 Ruby 风格的 DSL 来描述前端行为,并自动编译成可运行的 JavaScript。

换句话说,

你写 Ruby,它帮你生成 JS。浏览器只看到 JS,你看到的却是 Ruby 的优雅。

Fizzy 到底是什么?

Fizzy 是一个 Ruby → JavaScript 的转换器(更准确地说是 DSL 转换器)。它的主要作用是:

  • 读取 Ruby 风格的声明式前端行为代码(DSL)
  • 把这段代码解析成抽象语法树(AST)
  • 再把 AST 编译成浏览器可执行的 JavaScript
  • 最后由内置的 runtime 在浏览器执行

虽然听起来像魔法,但本质上它就是一个 前端行为编译器

为什么会有 Fizzy?

因为 Basecamp 的 Hotwire/Turbo 体系专注于:

  • 尽量少写 JS
  • 更多依赖 HTML + 少量声明式行为完成交互
  • 让前端开发更简单、可维护性更高

但是许多前端行为仍然需要 JavaScript,比如监听事件、更新 DOM 等。

既然 Hotwire 的世界是以 Ruby 为中心,那为什么不让前端行为也像 Ruby 一样写呢?

这就是 Fizzy 存在的意义:

用 Ruby 的表达方式描述浏览器行为,再自动转换成 JS。

开发者不需要写 JS,也不需要理解复杂的回调,只需要写 Ruby 风格的 DSL 就够了。

一个简单示例

假设我们希望点击某个元素时输出一句话。

在传统前端框架里,你可能会写:

element.addEventListener("click", () => {
  console.log("Hello");
});

而在 Fizzy 背后支持的 DSL 中,你可以写成 Ruby 风格:

on click do
  console.log "Hello"
end

Fizzy 会把它自动转换成与前面等价的 JavaScript。

效果一样,但风格完全不一样。

⚙️ 它内部是怎么做的?

Fizzy 的结构分成三部分:

  1. Parser(解析器)
    负责分析 Ruby 风格 DSL,生成语法树。
  2. Compiler(编译器)
    把语法树转换为现代 JavaScript。
  3. Runtime(运行时)
    浏览器执行的最小 JS 库,用来绑定事件、处理 DSL 行为。

它并不是为谁准备的?

  • 想构建一个大型 SPA 的开发者
  • 重度依赖 React/Vue 的团队
  • 想写大量前端业务逻辑的人

Fizzy 做的不是“增强 JS 生态”,而是“减少 JS 使用”。

它的定位非常明确:

帮助 Ruby 生态减少 JavaScript,而不是替代前端框架。

如何使用?

项目本身还处于比较底层的形态,目前的使用方式倾向于:

  • 作为 Hotwire/Turbo 的底层机制接入
  • 作为 Ruby DSL 的编译工具在构建流程中运行
  • 结合 HTML 里的行为声明自动生成 JS 绑定

更多细节可查看仓库文档(项目提供示例、测试代码、运行时说明)。

总结

Fizzy 是一个非常有趣、非常“Basecamp 风格”的工具。

它的目标不是让前端更复杂,而是让前端更简单:

  • 少写 JS
  • 多写 Ruby 风格的 DSL
  • 行为由编译器自动处理
  • 运行在浏览器里的仍然是标准 JavaScript

Github:https://github.com/basecamp/fizzy
油管:https://youtu.be/JFUVYLERFZ4