Web開発者の皆さん、こんにちは!昨年、当社では、Cloudflare上でのWebアプリケーションのデプロイをかなりの程度容易にする改善策を発表しました。それを受けて、Astro、Next.js、Nuxt、Qwik、Remix、SolidStart、SvelteKit、その他のCloudflareでホストされるWebアプリケーションがが大きく成長しています。本日、これらのWebフレームワークとの統合における大幅な改善が行われたことを発表します。この統合により、D1 SQLデータベース、R2オブジェクトストア、AIモデル、Cloudflareの開発者プラットフォームのその他の強力な機能を使用する、高度なアプリケーションの開発が容易になります。
以前は、D1でWebフレームワークに対応したアプリを開発し、ローカルで実行する場合は、アプリケーションの本番ビルドを構築してから、「wrangler pages dev」を使用してローカルで実行する必要がありました。特に問題はないものの、コードの反復に数秒、大きなアプリケーションでは数十秒かかることがありました。本番ビルドを使用した反復は単に遅すぎて、フローから外れてしまいます。また、フレームワーク作成者が多大な労力を費やして入れたすべてのDX最適化を活用することができません。 これは今日、変わります!
当社の目標は、開発者がアプリをCloudflareにデプロイする際に学習して採用するワークフローの大幅変更やカスタムAPIを採用することなく、可能な限り自然な方法でWebフレームワークと統合することです。Next.js開発者、Nuxt開発者、他のフレームワークをお希望のお客様には、使い慣れた高速ローカル開発ワークフローを引き続きご使用になりつつ、アプリケーションをCloudflare上で出荷することができます。
すべてのフルスタックWebフレームワークには、フレームワークに合わせてカスタマイズされたローカル開発サーバー(devserver)が付属しています。この開発サーバーは、多くの場合、優れた開発エクスペリエンスを提供しますが、1つだけ例外があります。Cloudflareの開発プラットフォーム、特にストレージソリューションの重要な機能を、ネイティブにサポートしていないという点です。
そのため、つい最近まで、難しい選択を強いられました。フレームワーク固有の開発サーバーを使用してアプリケーションを開発することもできますが、Cloudflareの機能の多くにはアクセスできません。あるいは、D1やR2のようなさまざまなリソースを含むCloudflareのプラットフォームをフルに活用することもできますが、フレームワーク固有の開発者ツールの使用を妥協しなければなりません。その場合、反復サイクルは遅くなり、ブラウザでコード変更の結果が表示されるまでに、数ミリ秒ではなく数秒かかるでしょう。でも、今は違います!見てみましょう。
では、アプリケーションを構築しましょう
C3 — cloudflareのcreate-cloudflare CLIを使って新しいアプリケーションを作成してみましょう。どんなnpmクライアント(pnpmでも可?!?)を使うことができますが、シンプルにするために、この記事では既定のnpmクライアントにします。あとは、以下を実行するだけです。
$ npm create cloudflare@latest
アプリの名前を入力するか、ランダムに生成されたアプリを使用します。次に、「WebサイトまたはWebアプリ」のカテゴリーとお好みのフルスタックフレームワークを選びます。当社がサポートするフレームワーク:Astro、Next.js、Nuxt、Qwik、Remix、SolidStart、SvelteKitなど。
C3は、アプリケーションのスキャピングをフレームワーク固有のCLIの最新バージョンに委任するため、フレームワークの機能やオプションを見逃すことなく、フレームワーク作成者が意図したようにアプリケーションをスキャフォールディングすることができます。C3は、Cloudflareへの統合とデプロイに必要なすべてをアプリケーションに追加するため、自分で設定する必要はありません。
アプリケーションがアップグレードされたので、いくつかのステップでデータベースに保存されている製品のリストを表示できるようにしましょう。まず、データベース用の設定をwrangler.toml設定ファイルに追加します。
[[d1_databases]]
binding = "DB"
database_name = "blog-products-db"
database_id = "XXXXXXXXXXXXXXXX"
そうです!Pagesにデプロイされたフルスタックアプリでも、バインドリソースの設定がwrangler.tomlファイルを介して設定できるようになりました。Pagesの設定強化については、専用の発表欄で詳しくお伝えします。
それでは、データベーススキーマを表す単純なschema.sqlファイルを作成してみましょう。
CREATE TABLE products(product_id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
INSERT INTO products (product_id, name, price) VALUES (1, 'Apple', 250), (2, 'Banana', 100), (3, 'Cherry', 375);
そして、データベースを初期化します。
$ npx wrangler d1 execute blog-products-db --local --file schema.sql
ローカルD1データベースに変更を適用するために、wrangler d1 execute
の–local
フラグを使用していることにご注意ください。これは開発者サーバーが接続するデータベースです。
次に、TypeScriptを使用する場合、以下を実行することでデータベースについてTypeScriptに知らせます。
$ npm run build-cf-types
このコマンドは、C3経由で作成されたすべてのフルスタックアプリケーション用に事前設定されており、Wranglerタイプ
を実行して、設定されたすべてのバインディングを含むCloudflareの環境のインターフェースを更新します。
これで、フレームワークが提供する開発サーバーを便利なショートカットを使って起動できます。
$ npm run dev
このショートカットにより、次のdev、nitro、viteのいずれかに関わらず、フレームワークの開発サーバーが起動されます。
これで、データベースにアクセスして製品をリストアップするために、フレームワーク固有のアプローチが使用できるようになりました。例えば、Appルーターを使用するNext.jsアプリケーションでは、app/api/hello/route.ts
を次のように更新できます。
const db = getRequestContext().env.DB;
const productsResults = await db.prepare('SELECT * FROM products').all();
return Response.json(productsResults.results);
また、Nuxtアプリケーションでは、server/api/hello.ts
ファイルを作成して設定することができます。
export default defineEventHandler(async ({ context }) => {
const db = context.cloudflare.env.DB;
const productsResults = await db.prepare('SELECT * FROM products').all();
return productsResults.results;
});
フレームワーク開発サーバーがポート3000で実行されていると仮定した場合は、http://localhost:3000/api/helloに移動すると、どちらのフレームワークでも新しいAPIルートをテストできます。簡単にするために、APIルートを例に挙げましたが、UIを生成するルートにも同様に適用できます。
各Webフレームワークは、ルートを定義し、アプリケーション全体にリクエストに関するコンテキスト情報を渡す独自の方法を持っているため、データベース、オブジェクトストア、その他のリソースへのアクセス方法はフレームワークによって異なります。詳細は、最新フルスタックフレームワークガイドをお読みください。
選択したフレームワークでCloudflareのリソースにアクセスする方法を把握したら、あとはフレームワークに関して知っていることはすべて同じです。フレームワークに最適化された開発サーバーを使用して、アプリケーションをローカルに開発できます。これには、多くの場合、ホットモジュール代替(HMR)、カスタム開発ツール、強化されたデバッグサポートなどが含まれますが、Cloudflare固有のAPIと機能のメリットも享受できます。いいことだらけですね!
こうした開発ワークフローを実現するために、実際何が変更されたのでしょうか?
開発の遅延を減らし、カスタムフレームワーク固有の体験を維持するために、Webフレームワークとその開発サーバーが、シームレスでまったく違和感なくWranglerとminiflareと統合できるようにする必要がありました。
Miniflareは、このパズルの重要な構成要素です。これはCloudflare固有のリソースのローカルシミュレータであり、当社のJavaScript(JS)ランタイムであるworkerdを搭載しています。workerdを利用すれば、CloudflareのJavaScript APIが、確実に、当社の本番環境を忠実にシミュレートし、ローカルで実行します。問題は、フレームワーク開発サーバーがアプリケーションを実行するためにすでにNode.jsに依存しているため、別のJSランタイムをMixに持ち込むと、これらの開発サーバーの構築方法に関する多くの前提が壊れてしまうことです。
しかし、当社のチームは2つのJSランタイム間のギャップを埋めるための興味深いアプローチを考案しました。これをgetPlatformProxy() APIと呼んでいます。これは現在、Wranglerの一部であり、miniflareのマジックプロキシによって強化されています。このAPIは、すべてのバインドリソースを含む通常のWorkers envオブジェクトと同じように動作するJSプロキシオブジェクトを公開します。プロキシオブジェクトにより、Node.jsから取得したコードがworkerdで実行されるJavaScriptコードを透過的に呼び出し、およびCloudflare固有のランタイムAPIにアクセスすることができます。
このNode.jsとworkerdランタイム間のブリッジによって、アプリケーションをNode.jsによる開発サーバーで実行しながら、D1、R2、KV、その他のストレージソリューションのCloudflareシミュレーターに直接アクセスできるようになります。また、Node.jsスクリプトを書いて同じことをすることもできます。
import {getPlatformProxy} from 'wrangler';
const {env} = getPlatformProxy();
console.dir(env);
const db = env.DB;
// Now let’s execute a DB query that runs in a local D1 db
// powered by miniflare/workerd and access the result from Node.js
const productsResults = await db.prepare('SELECT * FROM products').all();
console.log(productsResults.results);
getPlatformProxy()
APIが利用可能になったので、残りの作業は、すべてのフレームワークアダプター、プラグイン、そして場合によってはフレームワーク自体を更新してこのAPIを利用できるようにすることでした。この過程においてフレームワークチームから受けたサポート、特にAstroのAlex、Nuxtのpi0、RemixのPedro、SolidのRyan、SvelteのBenとRich、そして次のページで発表したプロジェクトの共同作業者、James Andersonに感謝します。
Viteによる開発ワークフローの今後の改善
getPlatformProxy()
APIは多くのシナリオに対して優れたソリューションですが、Cloudflareにはそれ以上に優れた方法があります。Node.jsではなくJSランタイムでアプリケーション全体を実行できたなら、本番環境をさらに忠実にシミュレートし、開発者にとっての摩擦や本番環境での想定外の動作を減らすことができました。
理想的には、本番環境にデプロイするのと同じランタイムで開発するのが望ましいのですが、これはworkerdをすべてのフレームワークの開発サーバーに直接統合することで達成できますが、世の中に存在するフレームワークの数や、フレームワーク間の違いを考慮すると、決して容易なことではありません。
しかし、幸運に恵まれました。この取り組みを始めるにあたり、多くのフルスタックフレームワークで使用される人気の開発者サーバーであるViteがますます普及していることにすぐに気付きました。実際、Remixは最近Viteに切り替えたことも、今日のWeb開発における共通の基盤としてViteの人気を裏付けています。
もしViteが代替のJavaScriptランタイムでフルスタックアプリケーションを実行するための最高のサポートを持っていれば、Viteを使う人すべてがCloudflare開発者プラットフォームへの完全なアクセスの下に、ローカルでアプリケーションを開発できるようになります。フレームワーク固有のカスタム統合や回避策は不要です。フルスタックフレームワーク、Vite、Cloudflareの機能すべてをすべての開発者がアクセスできるのです。
話がうますぎると感じますか?そうかもしれません。Vite環境提案についてViteチームと協力できることに興奮を覚えます。これにより、それを可能にすることができるからです。この提案はまだ進化中ですので、最新情報をお待ちください。
今日は何を構築しますか?
Cloudflareが目指すのは、Web開発者にとって最高の開発プラットフォームになることです。ユーザーがすでに使い慣れているフレームワークとツールを使用して、アプリケーションを迅速かつ簡単に開発できるようにすることは、当社のストーリーの大きな部分です。単一コマンドを実行して、ぜひ、この取り組みを始めてください。
$ npm create cloudflare@latest