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

フロントエンド、バックエンド、データベースが1つのCloudflare Workerに

2025-04-08

11分で読了
この投稿はEnglish繁體中文FrançaisDeutsch한국어Español简体中文でも表示されます。

2024年9月、当社は静的アセットをホスト、保存、配信するためのベータサポートをCloudflare Workersで無料で利用できるようにしました。以前はCloudflare Pagesでのみ利用可能だったものです。静的アセット(クライアントサイドのJavaScript、HTML、CSS、フォント、画像)をホストする能力は、それまでのWorkersに欠けていて、単一Worker内でフルスタックアプリケーションを構築したい開発者が待ち望んでいた重要なサービスです。

本日、Cloudflareでのアプリ構築における10の大きな改善点を発表します。これらの新しい追加機能により、シンプルな静的サイトからフルスタックアプリケーションまで、すべてをCloudflare Workers上で構築し、ホストすることができます:

これらの改善により、シンプルな静的サイトも、より複雑なサーバーサイドレンダリングアプリケーションも構築できます。Pagesと同様に、Workerコードを実行したときのみ課金されます。つまり、静的サイトのホスティングや配信は無料でできます。サーバー上でレンダリングを行いたい場合や、APIを構築する必要がある時は、バックエンドを扱うWorkerを追加するだけです。アプリでデータの読み取りや書き込みが必要な時は、Hyperdriveで既存のデータベースに接続するか、当社のストレージソリューションであるWorkers KVR2Durable ObjectsD1のいずれかを使うことができます。

すぐコードに取り掛かりたい場合は、下の「Cloudflareへデプロイ」ボタンをクリックすることで、ViteとReactで構築されたシングルページアプリケーションをデプロイできます。Hyperdriveでホストされているデータベースに接続するというオプションもあります。

Cloudflareへデプロイ

Workersで始める

以前は、Cloudflare Pagesで構築するかWorkersで構築するか(あるいは、アプリの一部にPagesを使用し、別の部分にはWorkersするか)をはじめに選択する必要がありました。これは、アプリに何が必要かを最初から理解し、プロジェクトが進化しても間違ったプラットフォームやアーキテクチャに縛られる事態にならないことを願うということです。Workersは柔軟なプラットフォームであるように設計されており、開発者が必要に応じてプロジェクトを進化させられるようになっています。そこで当社は、数年にわたってPagesの諸機能をWorkersに取り込む作業に取り組んできました。

Workersが静的アセットの配信とサーバーサイドレンダリングの両方をサポートするようになったので、Workersから始めるのがよいでしょう。Cloudflare Pagesは引き続きサポートしますが、今後の投資、最適化、機能開発の作業はすべてWorkersの改善に向けられます。当社は、Pagesでうまくいった点や改善点について皆様からいただいたフィードバックを基に、Workersを最高のフルスタックアプリ構築プラットフォームにすることを目指しています。

以前は、Pagesでアプリを構築する際、こだわりがうかがえるオンランプが本当に使いやすかったのですが、アプリケーションが複雑になると終いには壁に突き当たるということがよくありました。Durable Objectsで状態を管理したい場合は、そのためにまったく別のWorkerを設定する必要があり、デプロイメントが複雑になって、オーバーヘッドもかさみました。また、リアルタイムログしかなく、変更を一度にロールアウトよりほかありませんでした。

Workersで構築すれば、他のどの開発者プラットフォームサービス(Durable ObjectsEmail Workersなど)へもすぐにバインドでき、単一のプロジェクトでフロントエンドとバックエンドの両方を管理することができます。すべて一回のデプロイメントで行えます。さらに、Workersの可観測性ツール一式(Workers Logsなど)がプラットフォームに組み込まれています。トラフィックの特定の割合だけに変更をロールアウトしたければ、Gradual Deploymentsでできます。

こうした最新の改善は、Pagesの優れた部分をWorkersに取り込むという目標の一部です。例えば、静的な_headers_redirectsの設定ファイルがサポート対象になったため、Pages(または別のプラットフォーム)から既存プロジェクトをWorkersへ簡単に移動できます。プロジェクトを変更する必要はありません。また、GitHubやGitLabをWorkers Buildsと直接統合し、ビルドとデプロイメントを自動化します。そして本日より、プレビューURLコメントとしてリポジトリに投稿されるようになりました。機能ブランチのエイリアスと環境は近日公開予定です。

既存のプロジェクトをPagesからWorkersに移行する方法については、移行ガイドをご覧ください。

次に、Workersで異なるレンダリングモードでアプリケーションを構築する方法についてお話します。

Workersで静的サイト、SPA、SSRを構築

まずはじめに、Workersでサポートされているすべてのアーキテクチャとレンダリングモードを簡単に説明します:

  • 静的サイト:静的サイトにアクセスすると、サーバーは事前に構築された静的アセット(HTML、CSS、JavaScript、画像、フォントなど)をすぐに返します。リクエスト時にサーバーで動的レンダリングが行われることはありません。静的アセットは通常ビルド時に生成され、CDNから直接配信されるため、静的サイトは高速で簡単にキャッシュ可能になります。このアプローチは、コンテンツの変更がほとんどないサイトに適しています。

  • シングルページアプリケーション(SPA):SPAを読み込むと、サーバーは最初に最小限のHTMLシェルとJavaScriptバンドル(静的アセットとして配信)を送信します。ブラウザがこのJavaScriptをダウンロードし、続いてユーザーインターフェース全体をクライアントサイドでレンダリングします。最初の読み込みの後は、すべてのナビゲーションが通常クライアントサイドルーティングで、ページ全体を更新することなく行われます。これにより、高速でアプリのような使用感が実現します。

  • サーバーサイドレンダリング(SSR)アプリケーション:SSRを使っているサイトを初めて訪問した時に、サーバーはそのリクエストに応じてフルレンダリングのHTMLページをオンデマンドで生成します。ブラウザはこの完全なHTMLを即座に表示するため、最初のページの読み込みが速くなります。読み込みが終わると、JavaScriptがページの「ハイドレーション」を行い、インタラクティブ性を付与します。その後のナビゲーションは、新しいサーバーレンダリングページをトリガーするか、多くの最新フレームワークではSPAに似たクライアントサイドレンダリングに移行します。

次に、Workersでこの種のアプリケーションを構築する方法について掘り下げます。まず開発環境の準備から説明します。

セットアップ:buildとdev

アプリケーションをアップロードする前に、クライアントサイドのコードをすべて静的アセットのディレクトリにバンドルする必要があります。wrangler devを実行するとWranglerがコードをバンドルしてビルドしますが、今は新しいViteプラグインでViteもサポートされています。Viteプラグインは、既にViteのビルドツールと開発サーバーを使用している方に最適なオプションです。Viteの開発サーバーを使用して、引き続き開発(およびVitestによるテスト)を行うことができます。すべてWorkersランタイムを使用します。

Cloudflare Viteプラグインの使用を開始する際は、以下の実行により、Viteと当社のプラグインを使用してReactアプリケーションをスキャフォールディングします。

npm create cloudflare@latest my-react-app -- --framework=react

プロジェクトを開くと、次のようなディレクトリ構造が表示されるはずです:

...
├── api
│   └── index.ts
├── public
│   └── ...
├── src
│   └── ...
...
├── index.html
├── package.json
├── vite.config.ts
└── wrangler.jsonc

npm run buildを実行すると、/distという名前の新しいフォルダが表示されます。

...
├── api
│   └── index.ts
├── dist
│   └── ...
├── public
│   └── ...
├── src
│   └── ...
...
├── index.html
├── package.json
├── vite.config.ts
└── wrangler.jsonc

Viteプラグインは、そのプロジェクトでビルドされた静的アセット(この場合はクライアントサイドコード、いくつかのCSSファイル、画像など)がこの/distディレクトリに含まれていることを、Wranglerに知らせます。

このシングルページアプリケーション(SPA)アーキテクチャは、デプロイすると以下のようになります:

リクエストが来ると、Cloudflareはパス名を見て、そのパス名に一致する静的アセットを自動的に配信します。例えば、静的アセットディレクトリにblog.htmlファイルが含まれていれば、example.com/blogのリクエストはそのファイルを取得します。

静的サイト

Astroのような静的サイトジェネレーター(SSG)で作成された静的サイトがある場合、必要なのはwrangler.jsoncファイル(またはwrangler.toml)を作成して、構築したアセットがどこにあるかをCloudflareに知らせることだけです:

// wrangler.jsonc 

{
  "name": "my-static-site",
  "compatibility_date": "2025-04-01",
  "assets": {
    "directory": "./dist",
  }
}

その設定を追加したら、あとはプロジェクトを構築してwrangler deployを実行するだけです。そうするとサイト全体がアップロードされ、Workers上でトラフィックを処理する準備が整います。デプロイして、リクエストが入り始めると、静的サイトはCloudflareのネットワーク全体にキャッシュされます。

以下を実行することで、Workersで新しいAstroプロジェクトを今すぐ始めることができます:

npm create cloudflare@latest my-astro-app -- --framework=astro

サポートされている他のフレームワークと使用開始方法については、フレームワークガイドでご覧いただけます。

シングルページアプリケーション(SPA)

シングルページアプリケーションの場合は、Wranglerの設定でシングルページアプリケーションモードを明示的に有効化します:

{
 "name": "example-spa-worker-hyperdrive",
 "main": "api/index.js",
 "compatibility_flags": ["nodejs_compat"],
 "compatibility_date": "2025-04-01",
 },
 "assets": {
   "directory": "./dist",
   "binding": "ASSETS",
   "not_found_handling": "single-page-application"
 },
 "hyperdrive": [
   {
     "binding": "HYPERDRIVE",
     "id": "d9c9cfb2587f44ee9b0730baa692ffec",
     "localConnectionString": "postgresql://myuser:mypassword@localhost:5432/mydatabase"
   }
 ],
 "placement": {
   "mode": "smart"
 }
}

これを有効にすることで、プラットフォームが、ナビゲーションリクエスト(Sec-Fetch-Mode: navigateヘッダーを含むリクエスト)はすべて静的アセットを意図したものであると想定し、一致する静的アセットが見つからない時はいつでもindex.htmlを返します。静的アセットと一致しない非ナビゲーションリクエスト(データ要求など)の場合は、CloudflareがWorkerスクリプトを呼び出します。このセットアップによって、Reactでフロントエンドをレンダリングし、Workerでバックエンドの操作を処理し、Viteでこの2つをつなぎ合わせることができます。これは、create-react-appで構築された古いSPA(最近廃止)のポーティングに最適なオプションです。

このWrangler設定ファイルに関してもう一つ注記すべき点は、Hyperdriveバインディングを定義してSmart Placementを有効にしていることです。Hyperdriveは既存のデータベースの使用を可能にし、接続プーリングを処理します。これで、Workers(高度に分散されたサーバーレス環境で稼働)を従来型のデータベースに直接接続するという長年の課題が解決します。設計上、Workersは軽量のV8 Isolateで動作します。永続的なTCPソケットはなく、CPU/メモリには厳しい制限があります。この分離はセキュリティと速度の面ではいいのですが、データベース接続をオープンな状態に保持することが困難になります。Hyperdriveは、Cloudflareのネットワークとお客様のデータベースの間の「橋」として機能し、こういった制約に対処しています。安定した接続やプールの維持という重い作業を引き受けて、Workersで再利用できるようにしているのです。また、Smart Placementをオンにすることで、Workerへのリクエストの送信元がデータベースから遠い場合(遠ければ遅延が発生します)は、データベース接続を扱うWorkerとHyperdriveの「ブリッジ」の両方をデータベースの近くへ移すことをCloudflareが選択し、ラウンドトリップタイムを短縮できるようにしています。

SPAの例:Workerコード

このブログで最初に見た「Cloudflareへデプロイ」の例を見てみましょう。api/index.jsで、Hyperdriveを経由してホストデータベースに接続するAPIを(Honoを使用して)定義しました。

import { Hono } from "hono";
import postgres from "postgres";
import booksRouter from "./routes/books";
import bookRelatedRouter from "./routes/book-related";

const app = new Hono();

// Setup SQL client middleware
app.use("*", async (c, next) => {
 // Create SQL client
 const sql = postgres(c.env.HYPERDRIVE.connectionString, {
   max: 5,
   fetch_types: false,
 });

 c.env.SQL = sql;

 // Process the request
 await next();

 // Close the SQL connection after the response is sent
 c.executionCtx.waitUntil(sql.end());
});

app.route("/api/books", booksRouter);
app.route("/api/books/:id/related", bookRelatedRouter);


export default {
 fetch: app.fetch,
};

デプロイすると、アプリのアーキテクチャは次のようになります:

Smart PlacementがWorkerをデータベースの近くに移すると、こんな感じになります:

サーバーサイドレンダリング(SSR)

サーバー上でレンダリングを処理したいなら、当社は多くの一般的な フルスタックフレームワークをサポートしています。

以下は先ほどの例の別バージョンで、React Router v7のサーバーサイドレンダリングを使用しています:

Cloudflareへデプロイ

また、Next.jsをOpenNextアダプタフレームワークガイドに記載されている他のフレームワークで使用することもできます。

できる限り少ない変更でWorkersにデプロイする

Node.js互換性

Node.js APIのサポートも引き続き進めており、最近cryptotlsnetdnsのモジュールのサポートが追加されています。これにより、これらのNode.jsモジュールに依存する既存のアプリケーションやライブラリを、Workersで実行できるようになりました。例を見てみましょう:

以前は、mongodbパッケージを使用しようとすると、次のエラーが発生しました:

Error: [unenv] dns.resolveTxt is not implemented yet!

この問題は、mongodbnode:dnsモジュールを使用してホスト名のDNSルックアップを行った時に発生しました。この問題を回避しても、mongodbnode:tlsを使用してデータベースにセキュアに接続しようとした時に、別のエラーが発生したでしょう。

現在、mongodbは期待通り使えます。node:dnsnode:tlsがサポートされているからです。node:cryptonode:netに依存するライブラリについても、同じことが言えます。

また、Workersは、process.envオブジェクトの環境変数と機密情報を表示するようになっています。nodejs_compat互換性フラグがオンになっていて、互換性の日付が2025-04-01以降に設定されている場合です。一部のライブラリ(および開発者)はこのオブジェクトに変数が入力されることを想定して、それをトップレベルの設定に使っています。微調整せずにいれば、ライブラリが不意に壊れ、開発者はCloudflare Workersで変数を処理するための追加ロジックを作成しなければならなかったかもしれません。

現在は、Node.jsにアクセスするのと同じように変数にアクセスできるようになりました。

const LOG_LEVEL = process.env.LOG_LEVEL || "info";

WorkerのCPU処理時間を延長

WorkerリクエストあたりのCPU時間の上限を引き上げ、30秒から5分にしました。これにより、計算負荷の高い操作をより長い時間、タイムアウトなしで実行できます。例えば、新しくサポートされたnode:cryptoモジュールを使用して非常に大きなファイルをハッシュする場合、CPU負荷の高い操作を外部のコンピューティングに依存せず、Workersで行うことができます。

Workers Builds

Workers Buildsも改善しました。GitリポジトリをWorkerに接続できるため、変更をプッシュするたびにビルドとデプロイが自動でできます。Workers BuildsはBuilder Day 2024で発表されましたが、当初はリポジトリを既存のWorkerに接続することしかできませんでした。今では、リポジトリを持ち込んで新しいWorkerとしてすぐにデプロイできるので、プロジェクトの移行に必要なセットアップやボタンクリックの量を減らすことができます。Workers Buildsのビルドの起動遅延を6秒短縮して、パフォーマンスを改善しました。現在は平均10秒以内に起動します。APIの応答性も上がり、Smart Placementのおかげで遅延は7分の1に短縮されています。

  • Builder Day 2024中に発表した通り、2025年4月2日からWorkers Buildsは新しい料金体系モデルに移行しました。Freeプランユーザーのビルド時間は3,000分が上限となり、Workers有料サブスクリプションユーザーには、「6,000分の無料枠が含まれ、それ以降はビルド1分あたり0.005ドル」という新しい従量課金モデルが適用されます。また、同時ビルドのサポート強化として、有料プランに同時ビルド6回を含めました。複数のプロジェクトやMonorepoでの作業が容易になります。料金の詳細はドキュメントでご確認ください。

また、Workers Buildsを非本番ブランチで実行するように設定することもできます。プレビューURLがコメントとしてGitHubに投稿されます。

Images APIをWorkerにバインド

私たちは先週、Imagesのバインディングによって柔軟でプログラマティックな画像最適化のワークフローがどう実現するかについて、ブログ記事を書きました。

これまでは、Workerでfetch()を呼び出すことで画像最適化機能にアクセスできました。この方法では、オリジナルの画像がURLで取得可能である必要があります。しかし、場合によってはURLからアクセスできない画像もあります。例えば、ユーザーがアップロードした画像を圧縮してからストレージにアップロードしたい場合などです。Imagesのバインディング機能を使うと、画像のボディをバイトストリームとして操作することで、画像を直接最適化できます。

詳しくは、R2にアップロードする前に画像を変換するためのCloudflareガイドをご参照ください。

本日構築を開始

皆さんが何を構築されるのか楽しみです。当社は引き続き、Workersでのアプリケーション作成をより簡単にするための新機能や改善に注力します。そうした取り組みは、コミュニティからのフィードバックを反映してさらに改善されます。皆さんもぜひDiscordに参加して、議論に参加していただければ嬉しいです。

開始するための有用なリソース:

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

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

より良いインターネットの構築支援という当社の使命について、詳しくはこちらをご覧ください。新たなキャリアの方向性を模索中の方は、当社の求人情報をご覧ください。
Developer Week開発者フロントエンドフルスタック全体的な使いやすさCloudflare PagesCloudflare WorkersMySQLHyperdrive

Xでフォロー

Cloudflare|@cloudflare

関連ブログ投稿