Web開発
TanStack Start を使用したアプリケーションの構築
Building apps using TanStack Start (lovable.dev)
要約
Lovableは、より高速で堅牢なアプリケーション構築のため、ReactフレームワークであるTanStack Startを導入しました。これにより、以前のクライアントサイドレンダリング(CSR)のみの構成から、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)が利用可能になり、SEO対策やパフォーマンスが向上します。また、サーバーサイドロジックをコンポーネントファイル内に直接記述できるようになり、開発プロセスが簡素化され、セキュリティも強化されます。
全文翻訳
5月13日より、新しいプロジェクトはServer-Side Rendered (SSR)となり、高速でフルスタックなアプリを構築するためのモダンなReactフレームワークであるTanStack Startによって動きます。これを使用するために、何かをオプトインしたり、設定したり、新しいことを学ぶ必要はありません。既存のプロジェクトは以前と同じように動作しますが、クローラーの可読性を向上させるためのプリレンダリングが適用されます。この記事は、内部で何が変わり、なぜ変わったのか疑問に思っている人のためのものです。何が異なるのか、なぜTanStack Startを選んだのか、新しい要素がどのように組み合わさるのか、そしてLovableが生成するアプリにそれが何を意味するのかを説明します。
要するに、以前はReact + Viteで構築され、静的ファイルとしてデプロイされたSingle-Page Apps (SPAs)を作成していました。すべてがClient-Side Rendered (CSR)であり、これはうまく機能しますが、いくつかの制限がありました。バックエンドロジック(メールの送信、有料APIの呼び出し、サービスロールキーを使用したデータベースへのアクセスなど)に似たものはすべて、アプリコードを呼び出すものとは独立してデプロイされ、異なるURLで動作する別のエッジファンクションに存在する必要がありました。
新しいスタックの基盤はTanStack Startです。これは、ファーストクラスのサーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、およびルートごとのクライアントサイドレンダリング(CSR)を統合したサーバー関数とともに提供するフルスタックのReactフレームワークです。これにより、サーバーのみのロジックをコンポーネントファイル内に直接配置でき、ビルドプロセスがクライアントとサーバーの分離を管理しながら、標準的な呼び出しのように機能します。また、これは多くの点でユーザーに利益をもたらします。
| レイヤー | 以前のスタック | 新しいスタック |
|--------------------|----------------------------|----------------------------------|
| フレームワーク | Vite + React Router | TanStack Start (TanStack Router) |
| ランタイム | 静的ホスティング (Cloudflare Pages) | Cloudflare Workers |
| レンダリング | Client-Side Rendering (CSR) のみ | Server-Side Rendering (SSR) または Static-Site Generation (SSG) または Client-Side Rendering (CSR) (ルートごと) |
| サーバーロジック | Edge Functions | TanStack Server Functions |
| データベース、認証、ストレージ、リアルタイム | Supabase | Supabase |
| シークレット | Supabase | Cloudflare Workers bindings |
### なぜTanStack Startなのか
新しいベースフレームワークを探し始めたとき、制約は明確でした。Reactエコシステムに留まり、オープンで独立しており、どこにでも簡単にデプロイでき、検索エンジンがLovableで構築されたアプリをより適切にインデックス化できるようにサーバーサイドレンダリングをサポートし、強力な開発者エコシステムを持つ確立されたチームによって保守されている必要がありました。TanStack Startはこれらのすべての条件を満たしています。
TanStack Startの型システムは強力で、エンドツーエンドのタイプセーフティを可能にし、コードを生成するAIにより明確なガードレールを提供します。ルーターは多くのチームが何年も使用しているものと同じであり、サーバーランタイムは基盤となるReactのサーバー/クライアント境界を尊重する方法でその上に位置しています。これは、JavaScriptサーバーを実行できる任意のプラットフォームにデプロイできるように設計されています。その上、Lovable独自のサプライチェーンセキュリティスキャンと強化されたサードパーティライブラリ管理により、LovableでTanStackを基盤に構築することは安全でセキュアです。
### レンダリング: SSR、SSG、そしてブラウザが実際に受け取るもの
最も影響の大きい変更は、ページがコンテンツを既に含んだ状態でブラウザに到着するようになったことです。これがなぜ重要なのかを理解するには、古い動作がどのようなものだったかを見ると役立ちます。クライアントレンダリングされたReactアプリは、最初の要求でほぼ空のHTMLシェル(基本的には<div id="root">と<script>タグ)を返します。その後、ブラウザはJavaScriptをダウンロードし、実行し、その後に初めてページをレンダリングするために必要なデータをフェッチします。画面に何か表示されるまでに2回の往復が発生します。これは遅く、非常に重要な種類のトラフィック、つまりクローラーにとっては実質的に見えません。
クローラーはJavaScriptのみのページをどう扱うかによって異なります。Googleは最終的にレンダリングしますが、最近の測定では中央値の遅延は約10秒で、長時間のテールでは数時間に及ぶこともあります。他のいくつかのクローラーはJavaScriptをまったく実行せず、それらにとってクライアントレンダリングされたアプリは単なる空のページです。さらに、LinkedIn、Slack、WhatsApp、XなどのソーシャルプレビューアーはHTMLから直接メタタグを読み取るため、クライアントサイドレンダリングされたアプリは、ページごとに完全に適切なタイトルと説明タグが設定されていても、一般的なプレビューを表示します。
TanStackのアプローチはSEOのベストプラクティスに従っています。なぜなら、サーバーサイドレンダリングでは、サーバーがReactツリーを実行し、ローダーを実行し、その結果を完全に形成されたHTMLとして最初の要求でストリーミングするからです。リクエストごとのデータに依存しないルート(ブログ投稿、ランディングページ、マーケティングページ、aboutページ、すべての訪問者が同じものを見るあらゆるもの)の場合、TanStack Startはさらに一歩進んで、デプロイ時にこれらのルートをプリレンダリングし、リクエスト時にサーバー実行なしでフラットなHTMLとして提供できます。LovableのAIは、ルートが条件を満たした場合にこれを自動的に適用します。
### 実行モデル: コードが実行される場所
TanStack Startの核となる原則の1つは、コードがデフォルトでアイソモーフィックであることです。ルートモジュール、ローダー、コンポーネントは、サーバーとクライアントの両方のバンドルに含まれます。サーバーまたはクライアントでのみ実行されるべきものは、境界を明示的にマークします。そのような境界の1つがcreateServerFnです。これはビルド時にViteプラグインによって変換されます。サーバーバンドルでは、ハンドラー本体はそのまま含まれますが、クライアントバンドルでは、ハンドラー本体全体が、サーバーのエンドポイントにPOSTする型付きのfetch()スタブに置き換えられます。その結果、通常のファイルに通常の関数のように記述し、どこからでもインポートでき、ビルドが環境の分割を自動的に判断します。このモデルは、Lovableがコードを生成する方法と特にうまく適合します。
以前は、個別にデプロイされ、独自のURLで呼び出される別のバックエンド関数が必要だった機能が、今ではそれを使用するコンポーネントの隣に存在できます。1つのファイル、1つのメンタルモデル、1つのデプロイ。AIはサーバーのみのパーツをcreateServerFnでマークし、ビルドが残りを処理します。利点は、何か問題が発生したときの移動部品が少なくなり、呼び出しサイトとハンドラー間のエンドツーエンドの型付けです。各行がどこで実行されるかを知る必要はありませんが、生成されたコードを読めば一目でわかり、後でAIがそのコードを編集するときも同様です。
### 公開
Lovableでの公開は、以前とまったく同じように機能します。公開をクリックすると、デプロイが実行されている間、エディターが進捗状況を表示し、しばらくするとアプリがyour-project.lovable.appでライブになります。変更されたのは、舞台裏で実際に構築されているものです。以前は、公開とはシングルページアプリの静的ファイルをCDNにアップロードすることでした。今では、すべての公開でサーバーレンダリングされたアプリが構築され、静的に提供できるルートが事前生成され、それらすべてがエッジワーカーとしてデプロイされます。
### シークレットと環境変数
TanStack Startの変数は命名規則に従います。VITE_で始まるものはすべて公開と見なされ、ビルド時にクライアントバンドルに含まれますが、そのプレフィックスのないものはサーバーのみであり、サーバー関数からのみアクセスできます。Lovableユーザーの観点からは、これは見えません。以前と同じようにプロジェクト設定にシークレットを追加し、Lovableがそれぞれが適切な側に配置されるようにします。実際に新しいのは、サーバーのみのシークレットがどのように保存されるかです。これらはデプロイされたコードバンドルの一部ではありません。プロジェクトごとに分離されて別々に存在し、リクエスト時にバインディングとしてWorkerに注入されます。バンドルから分離されているため、シークレットをローテーションすると、次のリクエストですぐに変更が有効になります。再構築、再デプロイ、古いウィンドウはありません。ランタイムの動作により、シークレットがクライアントバンドルに到達することはありません。
### AIが新しいパターンを認識する方法
TanStack Startは、ほとんどのLLMトレーニングのカットオフ後にリリースされました。介入がなければ、TanStackコードを書くように求められたモデルは、Next.jsのgetServerSidePropsや「use server」ディレクティブ、または古いTanStackのリリース候補APIなど、よりよく知っているフレームワークのパターンにデフォルトで戻るでしょう。新しいパターンと慣習をモデルに教えるために、多くの作業が必要でした。これに対処するため、LovableのAIには、新しいスタックのすべてのリクエストのコンテキストに注入される、厳選されたTanStack固有のルールセットが与えられています。この知識ベースをゼロから構築したわけではありません。