Funky:806,893 行代码在 24 天内:当 Hackathon 转向疯狂会怎样
Source: Dev.to
Source: …
它是如何开始的
这最初是一个 $work hackathon 项目——那种让你有几天时间原型化某个东西并观察其走向的项目。
最初的想法很简单:构建一个 UI 来取代我们用于测试的难以管理的电子表格。标准的 CRUD 功能——表单、表格,常见的企业级需求。到了 2025 年,且“vibe”已成为潮流,我自然会去看看最新最强的模型,最终选定 Claude Opus 来看看它能做什么。
计划并不是仅仅再造一个 CRUD 应用,而是顺便引入一些现代实践:
- 通过 WebSockets 实时更新(对这个用例来说完全没必要)
- 正确的键盘导航(到底有谁会用到?)
- 完整的 PWA 与 SPA 能力——因为为什么不为乐趣而过度工程化呢
所有这些几乎不写代码,主要是指挥大局。
然后灵感来了。
当我连上 WebSocket、构建模态对话框、实现导入/导出逻辑时,我不再只看到一个电子表格的替代品,而是看到了它背后的结构——每个 CRUD 应用都需要但没人愿意从头构建的模式:
- 实时同步层
- 键盘快捷键管理器
- 可访问的焦点捕获逻辑
LLM 生成的代码并不差。我开始看到这可以成为什么。
于是我开始抽取这些模式。
“我们把这块抽象出来吧,”我对 LLM 说。“这样可以让 hackathon 的代码更整洁。”
然后我又抽象了另一块,再抽象另一块。接着我加入了一个 自定义虚拟 DOM,因为为什么不呢;大约花了一个小时。我把它和直接的 DOM 操作做了基准测试,立刻决定在大多数情况下这毫无意义。
hackathon 进行时,我大量谈论了使用 LLM 实现的安全特性,随后我不再构建电子表格应用,而是开始构建 电子表格应用想要依赖的框架。这个 hackathon 项目最终成为 Funky 框架 的基础。
最初的“给 CRUD 应用加上不必要的 WebSockets”已经演变成一个 JavaScript “框架”,其组成包括:
- 74 个组件
- 35 个核心模块
- 一个自定义测试框架,在真实浏览器中运行 8,800 条测试
让人费解的数字
我常在心里争论自己所构建的东西到底好不好,但先从那些让我大脑短路的统计数据说起:
| 指标 | 数值 |
|---|---|
| 时间线 | 2025 年 12 月 4‑28日 |
| 总提交次数 | 195 |
| 新增行数 | 1,297,591 |
| 删除行数 | 490,698 |
| 代码净行数 | 806,893 |
| JavaScript | 266,551 行 |
| CSS | 46,670 行 |
| 组件数量 | 74 |
| 核心模块 | 35 |
| 文档文件 | 127 |
| 测试套件 | 858 |
| 单个测试 | 8,800+ |
是的,我在电脑前花了很多时间,同时也在这段时间里完成了实际工作。使用过大型语言模型(LLM)的人都知道,你不能把 LLM 随意放出来,它并不是魔法……然而……
按照行业标准——每位开发者每天约 50 行经过测试、写有文档的代码——这相当于大约 16,138 人‑天 的工作量——即 64.5 人‑年。一支由五名全职开发者组成的团队需要 13 年 才能完成这些工作。
Opus 给出了这些统计数据,而所有这些竟然在 24 天 内完成……
无 jQuery 哲学
这里有一个有争议的观点:你不需要 jQuery。你不需要 React。你也不需要 Webpack、Vite 或 Babel。更别说为了渲染一个按钮而 npm install 下载半个互联网了。
Funky 完全是原生 JavaScript。开发工作流是革命性的:
- 编辑文件
- 刷新浏览器
就这么简单。没有构建步骤。没有热模块替换。也不需要在终端前守候五分钟,让 Webpack 做它的事……不管 Webpack 做什么。
“但是原生 JS 太冗长且痛苦!” 我听到你这么说。
真的是这样吗?下面是创建 toast 通知的方式:
Funky.Toast.show('Hello world', { type: 'success' });
下面是构建一个完整的数据表格,具备排序、过滤、分页、键盘导航和可访问性支持的方式:
Funky.Table.init('#my-table', {
data: myData,
columns: myColumns,
pageLength: 25,
selectable: true
});
有时这看起来太简单了——我在一天内重写了一个类似 DataTables 的组件。我相当确定原版花了更久时间。它是否稳健是另一回事;我还没有在生产环境中使用过这些代码,但我有可运行的示例,日志里也几乎没有错误……这只是 JavaScript 而已。
The Perl
是的,后端使用 Perl。
这门语言被大家认为已经死去,但却在 Tiobe 排行榜上不断上升。
骆驼依旧坚守。
我使用 Mojolicious 作为 Web 框架,Minion 处理后台任务,OpenAPI::Modern 进行 API 验证。没有它们几乎不可能实现。我目前只把所有东西粘合在一起并加入了 JavaScript。
我还有很多计划在未来实现,但目前我的重点是 JavaScript。
PSPWA
PSPWA 代表 Progressive Single Page Web Application。
Architecture
- Progressive: 可离线使用、可安装、推送通知
- Single Page: 无完整页面刷新,客户端路由
- Web Application: 不是文档,也不是网站,而是 应用程序
而且它全部在没有编译的 JavaScript 框架的情况下运行。仅使用 ES5、一些纪律性以及大量的 Claude 对话。
8,800+ 测试(在真实浏览器中)
“你无法正确测试原生 JavaScript,” 这句话从未被真正用 LLM 进行尝试的人说过。
测试运行器在 真实浏览器 中执行,而不是冒充浏览器的 Node.js。没有 jsdom。没有 happy-dom。真实的 Chrome、真实的 Firefox、真实的 Safari。
当我们测试键盘导航时,测试的是真实的键盘事件。当我们测试焦点管理时,测试的是真实的焦点。
测试哲学很简单:
在用户将运行代码的环境中运行代码。
ComboBox 测试
FunkyTests.describe('ComboBox', function() {
FunkyTests.it('should open dropdown on click', function() {
var combo = Funky.ComboBox.init('#test', { items: items });
TestUtils.click(combo.element);
expect(combo.isOpen()).toBe(true);
});
});
进入全屏模式
退出全屏模式
当然,你可以在 CI 环境下使用无头浏览器运行这些测试,但我们建议在开发过程中使用真实浏览器运行,以便及早捕获各种怪癖。我有一个 Perl 脚本通过 WWW::Mechanize::Chrome 实现这一点。
学习
以下是我在 24 天内指挥 800,000 行代码 所得到的经验:
-
没有方向的速度只会导致混乱。
Claude 的编码速度比任何人类都快,但如果没有清晰的架构和严苛的监控,最终会一团糟。 -
测试不是可选的。
在如此高速的开发中,测试是唯一能防止彻底灾难的手段。Git 也有帮助。 -
错误的文档比没有文档更糟。
我们发现 Claude 在记录不存在的功能。现在我们对所有内容进行验证,或强制它实现所描述的功能。信任,但要验证。
标语
“少写代码,多交付功能,夜晚睡得更好。”
这就是承诺。我们是否会兑现……再过 24 天再问我吧。
如果您想了解更多关于 Funky 的信息,请访问官方网站。它将是开源的,但我的愿景尚未最终确定。我会随时更新。