日本开发者 mizchi 长期活跃于前端与工具链领域,因对 TypeScript、WebAssembly 以及现代 Web 工程实践的深入研究而受到关注。结合自身在 React、Preact、Qwik、Svelte 等框架中的实践经验,他决定从零实现一个 UI 库——Luna UI,重点讨论轻量运行时、Signal 响应式系统,以及以 Web Components、SSR 与 Hydration 为前提的整体设计思路。
对现有 UI 库的不满
作为 UI 库爱好者,尝试过各种方案后,发现现有库仍难以解决核心痛点:
- React: 体积大,运行缓慢,不喜 RSC 改进方向。
- Qwik/Solid: 编译时展开过于复杂。
- Svelte/Vue: SFC 难以集成到生态系统中。
- Preact: 思路正确但 Signal 是后来补上的,生态系统一般。
- 共同问题: 互操作性低,除 Qwik 外 SSR 速度令人不满,缺乏以 WebComponents 为核心的项目。
基于这些考虑,参考 preact/signal,并以 WebComponents SSR + Hydration 为前提进行了设计。考虑到 SSR 优化需要垂直整合,自研成为必然选择。
产出与对比
LunaUI 是一个用 MoonBit 编写的基于 Signal 的声明式 UI 库,可用于 Moonbit/JS。在下文示例中,对比了 luna 和 preact 的相同实现:preact 为 20kb,而 luna 仅为 6.7kb(取决于 treeshake 功能)。
示例代码:TSX
由于用 jsx-runtime 包装了 Moonbit JS 后端产物,js 构建中可直接使用 JSX。
npm add @luna_ui/luna
安装后即可使用:
import { createSignal, createMemo, render, For, Show } from '@luna_ui/luna';
function Counter() {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
const isEven = createMemo(() => count() % 2 === 0);
return (
<div>
<h1>Luna Counter Example</>
Count: {count}
Doubled: {doubled}
{() => isEven() ? 'Even' : 'Odd'}
setCount(c => c - 1)}>-
setCount(c => c + 1)}>+
setCount(0)}>Reset
);
}
app = .();
(app) {
(app, );
}





