HN 日本語サマリー

← 一覧へ戻る
Web開発

The front end framework for correctness: built on Effect, architected like Elm

The front end framework for correctness: built on Effect, architected like Elm (foldkit.dev)

67 pointsby plucafs35 コメント

要約

Foldkitは、Effect上に構築されElmのようなアーキテクチャを採用した、正しさを重視する新しいフロントエンドフレームワークです。予測可能な状態管理、明示的な副作用、そしてスケーラビリティに優れた構造化されたアプローチを提供し、設計を通じてバグの防止を目指します。

全文翻訳

正しさのためのフロントエンドフレームワーク:Effect上に構築され、Elmのように設計されています。 Effect上に構築。Elmのように設計。TypeScriptで記述。 npx create-foldkit-app@latest 飛び込む プレイグラウンドを起動 GitHubで表示 674 振る舞いを宣言する。出荷する。繰り返す。 React、Vue、Svelte、Solidはレンダリングを解決し、アーキテクチャはあなたに委ねます。Foldkitはアーキテクチャを提供するため、ドメインに集中できます。 予測可能な状態 すべてのアプリケーション状態を保持する単一の不変モデル。すべての変更は単一の更新関数を流れます。隠されたミューテーション、古いクロージャ、驚きはありません。 明示的な副作用 副作用は更新から返す値であり、ハンドラに埋め込まれた命令的な呼び出しではありません。コマンドは何が起こるべきかを記述します。ランタイムがいつ、どのように処理します。 優雅にスケールする 複雑さは指数関数的ではなく線形に増加します。50ファイルのアプリは5ファイルのアプリと同じパターンに従うため、各機能は既存のものと絡み合うのではなく構造を追加します。新しいチームメンバーはコードを読んで理解できます。 Effect上に構築。内外ともに。 すでにEffectを知っているなら、Foldkitは自然に感じられます。Effectに慣れていないなら、Foldkitはそれを学ぶのに最適な方法です。 すべてのFoldkitアプリケーションはEffectです すべての状態は単一のスキーマです 副作用は失敗しないEffectとしてモデル化されています 動作を見てみましょう。 メッセージが更新を通過してモデルに流れる様子をご覧ください。コードはリアルタイムでハイライトされ、各ステップで何が起こっているかを示します。 非同期カウンター ノートプレイヤー 大きな画面では、アクションが実行されるときに、関連するコードがリアルタイムでハイライトされているのがわかります。 // MODEL const Model = S.Struct({ count: S.Number, isResetting: S.Boolean, resetDuration: S.Number, }) // MESSAGE const ClickedIncrement = m('ClickedIncrement') const ChangedResetDuration = m('ChangedResetDuration', { seconds: S.Number, }) const ClickedResetAfterDelay = m('ClickedResetAfterDelay') const CompletedDelayReset = m('CompletedDelayReset') // COMMAND const DelayReset = Command.define( 'DelayReset', { seconds: S.Number }, CompletedDelayReset, )(({ seconds }) => Effect.sleep(`${seconds} seconds`).pipe( Effect.as(CompletedDelayReset()), ), ) // UPDATE M.tagsExhaustive({ ClickedIncrement: () => [ evo(model, { count: count => count + 1 }), [], ], ChangedResetDuration: ({ seconds }) => [ evo(model, { resetDuration: () => seconds }), [], ], ClickedResetAfterDelay: () => [ evo(model, { isResetting: () => true }), [DelayReset({ seconds: model.resetDuration })], ], CompletedDelayReset: () => [ evo(model, { count: () => 0, isResetting: () => false }), [], ], }) 0 Add 1 Reset Delay (seconds) − + Reset after 2 seconds Model State count: 0 isResetting: false resetDuration: 2 Phase Idle Message Log バッテリー付属。 ほとんどのフレームワークは、ルーティングライブラリ、状態マネージャー、UIキット、フォームバリデーターを自分で用意するように求めてきます。Foldkitはそれらを1つのまとまったシステムとして提供します。 ルーティング 型安全な双方向ルーティング。URLは型付きルートに解析され、ルートはURLに再構築されます。文字列マッチングなし、解析と構築の間の不一致なし。 ルーティングを探る UIコンポーネント The Elm Architectureのために構築された、アクセス可能なコンポーネント(ダイアログ、メニュー、タブ、リストボックス、開閉メニューなど)。スタイリングやカスタマイズが容易です。 コンポーネントを参照する サブモデル 自己完結型のモデル、メッセージ、更新、ビューを、より大きなプログラム内に埋め込みます。子要素はドメインの事実を型付きのアウトメッセージとして表面化し、親は更新でそれらを処理します。すべてのステートフルFoldkit UIコンポーネントはサブモデルとして提供されます。 サブモデルを探る サブスクリプション モデルのスライスを、メッセージを発行する可能性のあるスコープ付きストリームにバインドします。ランタイムはスライスが値を保持している間スコープを開き、スライスが変更されると閉じます。 サブスクリプションを探る 管理リソース WebSockets、AudioContext、RTCPeerConnectionなどの長寿命のブラウザリソースのモデル駆動型ライフサイクル。ランタイムは、モデルがリソースを要求したときに取得し、不要になったときに解放します。 管理リソースを探る フィールド検証 同期および非同期サポートを備えたフィールドごとの検証。ルールを述語として定義し、更新で適用すると、モデルは各フィールドの状態を追跡します。 フィールド検証を探る テスト 2つのテストプリミティブ。ストーリーはメッセージを更新に送信し、結果のモデルとコマンドをアサートします。シーンはアクセス可能なロケーターを通じてレンダリングされたビューを駆動し、再レンダリングされたHTMLをアサートします。 テストについて学ぶ 開発者ツール アプリの実行中にメッセージ、モデルの状態、コマンドを検査します。タイムトラベルモードはUIを過去の任意のモデルに巻き戻します。AIエージェントはMCP over MCPで同じデータに接続できます。 開発者ツールを探る 埋め込み Runtime.embedを使用して、任意のホストアプリケーション内にFoldkitウィジェットを実行します。ホストはSchema型ポートを通じてデータをプッシュし、値を受け取り、disposeでウィジェットを破棄します。 埋め込みを探る ストーリーやシーンのように読めるテスト。 純粋な更新関数は純粋なテストを意味します。ストーリーはステートマシンをテストします。シーンはアクセス可能なロケーターを使用してビュー(ボタンのクリック、入力へのタイピング)を通じて機能をテストします。DOMなし、モックなし。 テストについて学ぶ import { Scene, Story } from 'foldkit' import { expect, test } from 'vitest' // Story — ステートマシンをテストする test('fetch weather updates the model', () => { Story.story( update, Story.with(model), Story.message(SubmittedWeatherForm()), Story.model(model => { expect(model.weather._tag).toBe('WeatherLoading') }), Story.Command.expectExact(FetchWeather), Story.Command.resolve(FetchWeather, SucceededFetchWeather({ weather })), Story.model(model => { expect(model.weather._tag).toBe('WeatherSuccess') }), ) }) // Scene — ビューを通じてテストする test('type a zip code, click get weather, see the forecast', () => { Scene.scene( { update, view, }, Scene.with(model), Scene.type(Scene.label('Zip code'), '90210'), Scene.click(Scene.role('button', { name: 'Get Weather' })), Scene.expect(Scene.role('button', { name: 'Loading...' })).toExist(), Story.Command.expectExact(FetchWeather), Story.Command.resolve(FetchWeather, SucceededFetchWeather({ weather })), Scene.inside( Scene.role('article'), Scene.expect(Scene.text('Beverly Hills, California')).toExist(), Scene.expect(Scene.text('72°F')).toExist(), ), ) }) プログラムが思考するのを見る。 すべての状態変更がメッセージと単一のモデルを流れるとき、ミュータブル状態フレームワークでは不可能だった開発者ツールが得られます。すべてのメッセージがログに記録されます。すべてのモデル状態が検査可能です。行をクリックすると、何が変更されたかが正確にわかります。 さらに、AIエージェントはMCP over MCPで接続できます。現在のモデルを読み取り、メッセージ履歴をたどり、UIを過去の状態に巻き戻します。開発者ツールが表示するデータへのプログラムアクセス。 このサイトはFoldkitで実行されています。このページの右下にあるタブを探して、開発者ツールをライブで試してみてください。 開発者ツールについて学ぶ 人間が読みやすく、AIが生成しやすいように構築。 Foldkitアプリは明示的で予測可能です。これにより、LLMはFoldkitコードの生成に特に優れています。そして、生成されたFoldkitコードは人間がレビューするのに非常に簡単になります。 AIエージェントは、モデルコンテキストプロトコル(MCP)を介して実行中のFoldkitアプリに直接接続することもできます。現在のモデルを読み取り、メッセージ履歴を検査し、UIを過去の状態に巻き戻し、メッセージをディスパッチします。 AI支援開発をセットアップする 何が問題なのでしょうか? Foldkitはフロントエンド開発について異なる考え方を求めてきます。The Elm Architectureを使用しているため、コンポーネント、フック、ローカル状態はありません。すべてが宣言的で構造化されています。状態、副作用、ビューについての考え方をシフトする必要があります。 それは規律です。それは報われますが、それは本当の要求です。 どのように機能するかを見る 比較するとどうですか? Foldkitは異なる種類のフロントエンドフレームワークです。React、Vue、Svelte、Solidと比較検討している場合、主な違いは構文やパフォーマンスではありません。Foldkitは、あなたに委ねるのではなく、アーキテクチャを規定していることです。 Reactと比較する 誰のためのものか フロントエンドを必要とするEffect開発者 バックエンドはすでにEffectを使用しています。Foldkitは欠けているフロントエンド部分です:同じエコシステム、同じパターン、コンテキストスイッチなし。 正しさを重視する開発者 バグを検出するだけでなく、アーキテクチャで防止したい。 連携を維持する必要があるチーム 状態、副作用、ビューの1つのパターンは、意見の相違を減らし、オンボーディングを迅速化します。 複雑な状態のプロジェクト