はじめに
これまでNext.jsで開発したWebアプリケーションを、Vercelで運用していました。
VercelはNext.jsとの相性がよく、GitHubリポジトリを連携するだけで、ビルドからデプロイまで簡単に行えます。
しかし、今回Cloudflare Workersへの移行を進める中で、思っていた以上に確認することが多いと感じました。
単純にデプロイ先を変更すればよいと思っていましたが、実際にはビルド方法やサーバーの実行環境、キャッシュ、画像の扱いなど、さまざまな違いがあります。
そこで気づいたのが、Vercelでは意識せずに利用していた機能が、実は数多くあったということです。
今回は、VercelからCloudflare Workersへの移行を通して見えてきた、Vercelが裏側で担っていた役割について整理してみます。
1. Next.jsのビルドとデプロイ
Vercelでは、GitHubリポジトリを連携するだけで、Next.jsのプロジェクトを自動的に検出してくれます。
基本的には、コードをpushするだけでビルドとデプロイが実行されます。
GitHubにpush
↓
Vercelが変更を検知
↓
Next.jsをビルド
↓
デプロイ
↓
公開URLでアクセス
Next.jsのビルド結果をどのように配置し、サーバー側の処理をどこで動かすかを、普段はほとんど意識する必要がありませんでした。
一方、Cloudflare Workersへ移行する場合は、Next.jsのアプリケーションをWorkers上で動かすための仕組みが必要になります。
そこで登場するのが、OpenNextやvinextです。
OpenNextはNext.jsのビルド結果をWorkers向けに変換するアダプターです。
vinextは、Viteを使ってNext.js互換のアプリケーションをビルドする仕組みです。
どちらも、Next.jsをCloudflare Workers上で動かすための選択肢になります。
Vercelでは自動的に整えられていたNext.jsの実行環境を、移行先では明示的に考える必要があるということです。
2. SSRやAPI Routesの実行環境
Next.jsでは、画面を表示するためのReactコンポーネントだけでなく、サーバー側の処理も実装できます。
例えば、以下のような機能です。
- SSR(サーバーサイドレンダリング)
- API Routes・Route Handlers
- Server Actions
- React Server Components
Vercelでは、これらのサーバー機能を実行するための基盤が用意されています。
開発者はNext.jsのコードを書くだけで、サーバー処理をデプロイできます。
しかし、Cloudflare Workersは一般的なNode.jsサーバーとは異なる実行環境です。
そのため、Next.jsのサーバー機能がWorkers上でどのように実行されるのかを確認する必要があります。
OpenNextやvinextは、この違いに対応するための仕組みですが、すべてのNode.js APIやライブラリの互換性まで保証するものではありません。
3. Node.js向けパッケージの互換性
今回の移行で、特に意識するようになったのがNode.js向けパッケージの扱いです。
Vercelでは、Next.jsのサーバー処理をNode.jsランタイムで実行できるため、多くのNode.js向けライブラリをそのまま利用できます。
一方、Cloudflare WorkersはV8ベースの実行環境で、Node.jsの互換機能も提供していますが、一般的なNode.js環境と完全に同じではありません。
そのため、利用しているパッケージがWorkersでも問題なく動作するかを確認する必要があります。
例えば、今回のプロジェクトでは画像アップロードにCloudinaryの公式Node.js SDKを利用していました。
移行準備では、このSDKへの依存を見直し、CloudinaryのREST APIをfetchで直接呼び出す実装に変更しました。
const response = await fetch(uploadUrl, {
method: "POST",
body: formData,
});
Cloudinary自体を変更したわけではなく、画像をアップロードする方法を変更した形です。
なお、これはCloudinaryのSDKが必ずWorkersで動かないという意味ではありません。
今回の移行では、Node.js向けSDKへの依存を減らし、Workersで利用しやすいWeb標準APIを使う方針にしました。
Vercelで問題なく動いていたパッケージでも、実行環境が変わる場合は互換性の確認が必要になるということを実感しました。
4. 静的ファイルの配信とCDN
Next.jsのアプリケーションでは、JavaScriptやCSS、画像などの静的ファイルも配信する必要があります。
Vercelでは、こうした静的ファイルをCDN経由で配信する仕組みが用意されています。
そのため、普段は静的ファイルがどこに配置され、どのように配信されているかを意識することはあまりありませんでした。
Cloudflare Workersへ移行する場合も、Cloudflareのネットワークを利用して静的ファイルを配信できます。
ただし、利用するビルド方式に合わせて、静的ファイルの出力先やWorkersとの連携を設定する必要があります。
OpenNextやvinextなどのツールが、この部分の構成を支援してくれます。
つまり、Cloudflare側でもCDNを利用できるものの、Next.jsのビルド結果と静的ファイル配信の仕組みをどうつなぐかが重要になります。
5. ISRやキャッシュの仕組み
Next.jsには、ページやデータをキャッシュする仕組みがあります。
例えば、ISR(Incremental Static Regeneration)は、生成済みのページを一定の条件で再生成する機能です。
Vercelでは、Next.jsのキャッシュ機能を支える基盤が提供されています。
そのため、Next.jsの設定を利用するだけで、キャッシュや再検証の仕組みを使えます。
一方、Cloudflare Workersへ移行する場合は、利用するアダプターや実行方式によって、キャッシュの保存先や再検証の動作が異なります。
例えば、構成によってはCloudflare R2やKVなどのサービスを利用してキャッシュを保持する場合があります。
特にISRを利用しているアプリケーションでは、ページの再生成やキャッシュの無効化が期待どおりに動作するかを確認する必要があります。
Vercelではあまり意識していなかったキャッシュの保存先や更新方法も、移行先では重要な検討事項になります。
6. 画像最適化
Next.jsでは、next/imageを利用することで画像の最適化を行えます。
例えば、画像のサイズ調整や適切な形式での配信などです。
Vercelでは、Next.jsの画像最適化に対応したサービスが提供されています。
そのため、next/imageを利用する際に、画像変換用のサーバーを自分で用意する必要は基本的にありません。
一方、Cloudflare Workersへ移行する場合は、利用するアダプターや画像配信の構成によって対応方法が変わります。
Cloudflare Imagesなどの画像変換機能を利用する方法もあります。
今回のプロジェクトでは、画像の保存先としてCloudinaryを利用しています。
そのため、画像の保存と、next/imageによる最適化・配信を分けて考える必要があります。
画像をどこに保存するかと、画像をどのように最適化して配信するかは別の問題です。
この点も、移行を考える中で改めて意識するようになりました。
7. 環境変数とシークレットの管理
Vercelでは、管理画面から環境変数を登録できます。
開発環境、プレビュー環境、本番環境ごとに値を分けて管理することも可能です。
Cloudflare Workersでも環境変数やシークレットを管理できますが、設定方法は異なります。
例えば、Wranglerの設定ファイルで通常の環境変数を定義したり、シークレットを別途登録したりします。
{
"vars": {
"APP_ENV": "production"
}
}
APIキーや認証情報などの機密情報は、通常の環境変数ではなくシークレットとして管理する必要があります。
また、Next.jsで使用していた環境変数が、Workersのビルド時と実行時のどちらで参照されるかにも注意が必要です。
これまでVercelの管理画面で設定していた値についても、移行先でどのように管理するかを整理する必要があります。
8. プレビュー環境とデプロイの管理
Vercelでは、GitHubのプルリクエストやブランチに対応したプレビューデプロイを簡単に利用できます。
変更内容を本番環境へ反映する前に、専用のURLで確認できる便利な機能です。
Cloudflare Workersでも、プレビューバージョンやCI/CDを利用して、同様の開発フローを構築できます。
ただし、Vercelとまったく同じ設定や動作になるわけではありません。
例えば、以下のような点を確認する必要があります。
- GitHubへのpushを契機にデプロイするか
- プレビュー環境をどのように作成するか
- 本番環境とプレビュー環境の設定をどう分けるか
- デプロイに失敗した場合にどう対応するか
Vercelでは標準的に用意されていた開発フローも、Cloudflare側の機能に合わせて構成する必要があります。
Vercelが裏で担っていた役割を整理すると
今回の移行で意識するようになった内容をまとめると、以下のようになります。
| 項目 | Vercel | Cloudflare Workersへの移行時 |
|---|---|---|
| Next.jsのビルド | Next.jsを自動検出して構成 | OpenNextやvinextなどを利用 |
| SSR・API | 対応する実行基盤を提供 | Workers向けの実行方式を確認 |
| Node.js互換性 | Node.jsランタイムを利用可能 | Workersでの互換性を確認 |
| 静的ファイル | CDN配信を提供 | Workersの静的アセット配信を利用 |
| ISR・キャッシュ | Next.js向けのキャッシュ基盤を提供 | キャッシュの構成と動作を確認 |
| 画像最適化 | Next.js向けの画像最適化を提供 | 画像変換・配信方法を確認 |
| 環境変数 | 管理画面で設定 | Wranglerやシークレット管理を利用 |
| プレビュー | Git連携によるプレビュー | Workersのプレビュー機能やCI/CDを利用 |
もちろん、Cloudflareにもこれらを実現するための機能が用意されています。
そのため、すべてを自分で実装する必要があるわけではありません。
ただし、VercelではNext.js向けに統合されていた仕組みを、Cloudflare Workersでは利用するツールやサービスに合わせて構成する必要があります。
まとめ
VercelからCloudflare Workersへの移行を進める中で、VercelがNext.jsの実行環境を幅広く支えていたことに気づきました。
これまではGitHubにpushするだけでデプロイできていましたが、その裏側ではビルド、サーバー処理、静的ファイル配信、キャッシュ、画像最適化など、多くの仕組みが動いていました。
Cloudflare Workersでも同様の機能を実現できますが、Next.jsとの連携方法や実行環境の違いを理解する必要があります。
今回の移行準備では、OpenNextやvinextといった技術を調べたり、Node.js向けパッケージへの依存を見直したりすることになりました。
その結果、当初想定していたよりも確認することが多く、移行には思った以上に時間がかかっています。
Vercelからの移行は、単にホスティング先を変更するだけではなく、Vercelが担っていた役割を別の環境でどう実現するかを考える作業でもある。
今回の移行を通して、Vercelの便利さと、Next.jsを動かすための仕組みを改めて理解することができました。