Ripple: 注目すべき新しいTypeScript UIフレームワーク
ReactのuseMemo、useCallback、そしてクロージャのバグと格闘した経験があれば、リアクティビティを手動で管理することに伴う精神的なオーバーヘッドをすでにご存知でしょう。Dominic Gannaway氏(React Hooksコントリビューター、Infernoの作者、Svelte 5のコアメンテナー)が開発した新しいTypeScriptフレームワークRippleは、まったく異なるアプローチを採用しています。リアクティビティをコンパイル時に処理し、残りはフレームワークに任せるのです。
技術的に興味深いポイントを見ていきましょう。
重要なポイント
- Rippleはコンパイラ駆動型のUIフレームワークで、
.rippleファイルを使用し、きめ細かいDOM更新ロジックを生成します。仮想DOMや差分検出は不要です。 - そのリアクティビティモデルは
track()と@アクセス演算子を中心としており、依存配列、useMemo、useCallbackが不要になります。 - リアクティブコレクション(
#[]と#{})は、UI更新を自動的にトリガーする直接的なミューテーションを可能にします。 - このフレームワークは充実した開発者ツール(Vite統合、VSCode拡張機能、スコープ付きスタイル)を提供していますが、まだ初期段階の実験的なものです。学習する価値はありますが、本番環境での使用にはまだ準備が整っていません。
Ripple UIフレームワークとは?
Rippleは、.rippleファイルを中心に構築されたコンパイラ駆動型のUIフレームワークです。.rippleは.tsxや.jsxとは異なる独自のモジュール形式です。Rippleは実行時に仮想DOMや差分アルゴリズムを提供する代わりに、コンパイラがコンポーネントを解析し、実行時に動作するきめ細かいDOM更新ロジックを生成します。
差分検出はありません。コンポーネントの再実行もありません。変更されたノードだけに対する外科的な更新のみです。
その結果、Rippleは概念的にSolid(きめ細かいシグナル)とSvelte(コンパイラ駆動型の出力)の中間に位置するフレームワークとなっていますが、TypeScriptを最初から第一級市民として扱っています。後付けではありません。
Rippleのきめ細かいリアクティビティの仕組み
Rippleのきめ細かいリアクティビティモデルは、2つのプリミティブを中心としています。
track()— リアクティブな値または派生計算を作成@— 追跡された値の読み書きのためのアクセス演算子
import { track } from 'ripple'
export component Counter() {
let count = track(0)
let double = track(() => @count * 2) // 自動派生、依存配列不要
<div>
<p>{@count}</p>
<p>{@double}</p>
<button onClick={() => @count++}>{"Increment"}</button>
</div>
}
@countが変更されると、それに依存するDOMノードのみが更新されます。doubleは自動的に再計算されます。useMemoも依存配列もデバッグすべきクロージャのバグもありません。
これはReactのモデルとは大きく異なります。Reactでは状態変更がコンポーネント全体の再実行をトリガーします。また、SolidのcreateSignalとも異なり、Rippleは意図的にそれを模倣していません。track()という命名は異なるメンタルモデルを示しています。シグナルグラフを手動で配線するのではなく、追跡される関係を宣言しているのです。
リアクティブコレクションについて、Rippleは#[](TrackedArray)と#{} (TrackedObject)を導入しており、直接的なミューテーションが可能です。
const todos = #[]
todos.push({ id: 1, text: 'Write docs', completed: false }) // UIが自動的に更新される
スプレッド演算子は不要です。setStateも不要です。ただミューテートして進めるだけです。
Discover how at OpenReplay.com.
Ripple TSフロントエンドフレームワークの開発者体験
Rippleは焦点を絞った実用的なツールストーリーを提供しています。
- CLIスキャフォールディング:
npm create ripple my-appで数秒でViteベースのプロジェクトを作成 - VSCode拡張機能:
.rippleファイル内でのIntelliSense、診断、エラーハイライト - PrettierとESLintサポート:
.rippleモジュールの完全なフォーマットとリンティング - スコープ付きスタイル: コンポーネント内の
<style>ブロックは自動的にスコープ化され、CSS Modulesのセットアップは不要
コンポーネントはfunctionの代わりにcomponentキーワードを使用し、テンプレートは戻り値ではなく文です。これはコンパイラに最適化の余地を与える微妙な変化です。
component Button(props: { text: string, onClick: () => void }) {
<button onClick={props.onClick}>{props.text}</button>
}
制御フローはプレーンなJavaScriptを使用します。forループ、if/elseブロック、エラーバウンダリ用のtry/catchなど、.map()の複雑な処理や<Show>ラッパーコンポーネントは不要です。
サーバーサイドレンダリングについて: Rippleのドキュメントはrender(サーバー)とhydrate(クライアント)APIに言及しているため、SSRは設計の方向性の一部です。それを取り巻くエコシステムは初期段階で進化中であり、今日本番アプリを出荷するフレームワークではありません。
まとめ
Rippleは、稀有なフレームワーク開発の経歴を持つ人物による真の技術実験です。コアアイデア — 遅延リアクティブ評価、コンパイラが所有する依存関係追跡、TypeScriptネイティブ構文 — は、たとえ本番環境でRippleコードを一行も書かなくても理解する価値があります。
興味があれば、GitHubリポジトリとドキュメントが適切な出発点です。Viteスターターを立ち上げて、カウンターや小さなフォームを構築し、そのメンタルモデルがしっくりくるか確認してみてください。
興味深いフレームワークは、大声で自己主張することはほとんどありません。ただ、すでに使っているフレームワークについて違った考え方をさせてくれるだけです。
よくある質問
Reactは状態変更時にコンポーネント全体を再実行し、最適化にはuseMemoのようなフックに依存します。Solidはきめ細かいシグナルを使用しますが、手動でのシグナル作成が必要です。Rippleはコンパイラ駆動型の解析とtrack()プリミティブおよび@演算子を組み合わせて、ビルド時に外科的なDOM更新を生成し、依存配列や手動のメモ化を完全に不要にします。
いいえ。Rippleは初期段階の実験的なフレームワークです。ツールにはVite統合、VSCode拡張機能、スコープ付きスタイルが含まれていますが、エコシステムはまだ進化中です。現時点では、本番アプリケーションの出荷よりも、探索と学習に最適です。
TrackedArray (#[])とTrackedObject (#{})は、Rippleのリアクティブコレクションプリミティブです。pushやプロパティ割り当てなどの標準操作を使用してデータを直接ミューテートでき、UIが自動的に更新されます。これにより、Reactで一般的なイミュータブルな更新パターン、スプレッド演算子、setStateコールが不要になります。
Rippleのドキュメントはrenderとhydrate APIに言及しており、SSRがフレームワークの設計方向の一部であることを示しています。ただし、SSRのストーリーはまだ初期段階です。Next.jsやSvelteKitに匹敵する成熟したメタフレームワークや本番環境でテストされたSSRパイプラインは、まだRippleには用意されていません。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.