新規投稿のお知らせを受信されたい方は、サブスクリプションをご登録ください:

フルスタックフレームワークとCloudflareによる超高速開発

2024-04-05

6分で読了
この投稿はEnglish繁體中文한국어PortuguêsEspañolРyсский简体中文でも表示されます。
Blazing fast development with full-stack frameworks and Cloudflare

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アプリ」のカテゴリーとお好みのフルスタックフレームワークを選びます。当社がサポートするフレームワーク:AstroNext.jsNuxtQwikRemixSolidStartSvelteKitなど。

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

このショートカットにより、次のdevnitroviteのいずれかに関わらず、フレームワークの開発サーバーが起動されます。

これで、データベースにアクセスして製品をリストアップするために、フレームワーク固有のアプローチが使用できるようになりました。例えば、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のBenRich、そして次のページで発表したプロジェクトの共同作業者、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

Cloudflareは企業ネットワーク全体を保護し、お客様がインターネット規模のアプリケーションを効率的に構築し、あらゆるWebサイトやインターネットアプリケーションを高速化し、DDoS攻撃を退けハッカーの侵入を防ぎゼロトラスト導入を推進できるようお手伝いしています。

ご使用のデバイスから1.1.1.1 にアクセスし、インターネットを高速化し安全性を高めるCloudflareの無料アプリをご利用ください。

より良いインターネットの構築支援という当社の使命について、詳しくはこちらをご覧ください。新たなキャリアの方向性を模索中の方は、当社の求人情報をご覧ください。
Developer Week開発者Developer PlatformFull StackWranglerMiniflare

Xでフォロー

Igor Minar|@IgorMinar
Peter Bacon Darwin|@petebd
Cloudflare|@cloudflare

関連ブログ投稿

2024年10月31日 13:00

Moving Baselime from AWS to Cloudflare: simpler architecture, improved performance, over 80% lower cloud costs

Post-acquisition, we migrated Baselime from AWS to the Cloudflare Developer Platform and in the process, we improved query times, simplified data ingestion, and now handle far more events, all while cutting costs. Here’s how we built a modern, high-performing observability platform on Cloudflare’s network. ...