🧑‍🏭

Cloudflare Workersにフロントエンドを載せた話

2024/12/21に公開

今年にリリースされたCloudflare Workersのアップデートで、Static Assets(静的ウェブサイト)とFrameworks(フルスタックアプリケーション)のデプロイが可能になりました。この2つはともにフロントエンドを指しており、これまでのWorkersとは少し毛色が異なっています。
私自身はこれまでフロントエンドのアプリケーションはCloudflare Pagesにデプロイしたことはありましたが、弊社ではWorkersを積極的に活用していることもあり、Workersのフロントエンドデプロイを試すことにしました。

なお今回の記事は2024年10月ごろに実施した経験をベースに書いています。Static Assets(とFrameworks)のデプロイに関してはベータ版とされており、アップデートで記事の内容が既に陳腐化している可能性がありますので、その点はご容赦ください🙇

Frameworks

今回はNext.jsのApp routerをデプロイしました。実施したプロジェクトは元々Pagesにデプロイしており、それを移行する形で実施しました。
進め方としては基本的に公式の手順に従いました。
https://developers.cloudflare.com/workers/frameworks/framework-guides/nextjs/#existing-nextjs-apps

また、WorkersへのNext.jsアプリケーションのデプロイはOpennextを使用しています。Opennextの公式ドキュメントはCloudflareの公式と大体同じことが書いてありますが、Cloudflareの公式には書いていないこともいくつか記載がありましたので、こちらも並行して確認することをお勧めします。
https://opennext.js.org/cloudflare

注意点

Pages用のライブラリなどが残っているとビルドができない

Opennextのドキュメントに記載があったのですが、Pages用のライブラリなどが残っているとWranglerでのビルドなどがエラーになります。具体的には、

  • @cloudflare/next-on-pagesはパッケージごと削除する
  • runtimeの指定を削除する
export const runtime = "edge"; //これを全て消した

この辺りを実施する必要がありました。

もう一つくらいあったかなと思いましたが、ドキュメントの記述ミスに踊らされたくらいでした。これは既に解決しています。
https://github.com/cloudflare/cloudflare-docs/issues/17291

Static Assets

上記のNext.jsプロジェクトで使用しているStorybookを静的ページとしてデプロイしました。こちらも基本的な流れは公式に記載の通りです。
https://developers.cloudflare.com/workers/static-assets/get-started/

注意点

wranglerファイルを分ける

同じプロジェクト内で2つのworkersへのデプロイを用意する場合は当然ではありますが別のwranglerファイルを用意する必要があります。Storybook用のwranglerファイルはstorybook-wrangler.tomlという名前で用意しました。
wranglerファイルはCLIで指定する(--configオプション)ことができますので、別々のnpm scriptを用意するのが運用しやすいかと思います。

"deploy:worker": "pnpm run build:worker && wrangler deploy",
"deploy:storybook": "storybook build && wrangler deploy --config storybook-wrangler.toml",

ビルドプロセスを別で用意している場合はwranglerでビルドしないようにする

Storybookをデプロイしたかったということもあり、ビルドプロセスはStorybookに任せたいという気持ちがありました。非推奨のようですがやり方は用意してくれています。
https://developers.cloudflare.com/workers/wrangler/bundling/#disable-bundling
結果としてnpm scriptはこうなりました↓

"deploy:storybook": "storybook build && wrangler deploy --no-bundle --config storybook-wrangler.toml",

ダッシュボードから見える情報が一部制限される

Cloudflareのダッシュボードから各Workersの情報が確認できますが、静的アセットのみの場合、メトリクスとログが利用できません。


この辺は--no-bundleオプションによるものかもしれません。

Versions と Preview URLs

Next.jsのFrameworks、StorybookのStatic Assetsをそれぞれデプロイしましたが、できればPagesのようにブランチごとの環境を立てたいところです。
残念ながらPagesと全く同じことはできませんが、WorkersのVersionsとPreview URLsという機能を使うことで環境を分けるということはある程度可能になりました。
https://developers.cloudflare.com/workers/configuration/versions-and-deployments/
https://developers.cloudflare.com/workers/confriguration/previews/

すごくざっくりまとめると、versionごとにプレビュー用のURLが自動で発行されるという仕組みです。
CLIを実行したときのターミナルは大体こんな感じで出力されます↓

~/d/a/a/front ❯❯❯ npx wrangler versions upload                                                                          ✘ 130 

 ⛅️ wrangler 3.80.3 (update available 3.80.5)
-------------------------------------------------------

🌀 Building list of assets...
🌀 Starting asset upload...
🌀 Found 2 new or modified static assets to upload. Proceeding with upload...
{{ 省略 }}
Uploaded 1 of 2 assets
Uploaded 2 of 2 assets
✨ Success! Uploaded 2 files (40 already uploaded) (1.28 sec)

Total Upload: 8958.94 KiB / gzip: 1641.10 KiB
Worker Startup Time: 29 ms
Your worker has access to the following bindings:
Uploaded {{ workersの名前 }} (8.27 sec)
Worker Version ID: {{ 固有のid }}
Version Preview URL: https://{{ preview用のサブドメイン }}.workers.dev

To deploy this version to production traffic use the command wrangler versions deploy

Changes to non-versioned settings (config properties 'logpush' or 'tail_consumers') take effect after your next deployment using the command wrangler versions deploy

Changes to triggers (routes, custom domains, cron schedules, etc) must be applied with the command wrangler triggers deploy

ブランチもしくはPRごとにWorkersを完全に別で立てるとかの方法もあると思います。が、CI/CDの作り込みは一層必要になりそうです。

VersionsにタグとGitメッセージをつける

versionのアップロードはGithub Actionsで行うようにしました。またVersionsの目印としてタグとメッセージが付与できます。私はタグとしてブランチ名を、メッセージとしてコミットハッシュを付与しました。

Pagesとの比較

https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/
公式のマトリックスが最もまとまっているので、詳細はそちらを確認いただくのがよいと前置きしつつ、個人的には大体以下2つの印象です。

WorkersのランタイムはV8なので余計なことがEdge Runtimeなどが不要

WorkersのランタイムはV8です。PagesでNext.jsをデプロイするためにEdge Runtimeを有効にするということが、Workersでは不要になります。
またマトリックスに記載の通り、使える機能の数自体はWorkersのほうが多いので、雑な考えではありますが、実現できることがPagesよりも多いことが推測されます。(だいぶ雑)

ちなみにWorkersの、Node.jsとの互換性は以下にまとまっています。
https://workers-nodejs-compat-matrix.pages.dev/

静的ページはPagesの方がよさそう

前述の通り静的ページをWorkersにデプロイしても、ダッシュボードで得られる情報は制限されます。
また、プレビュー用の環境はversionと完全に1:1の関係であり、同じversionを上書きすることができないので、CI/CDを工夫しない限りはURLの管理がややこしくなります。
フロントエンドのプレビューはデザイナーやPdMにも見てもらいたいものなので、この辺は少し厄介に感じました。
ちなみにWorkersへのデプロイサイズは10月の段階では結構制限が厳しかった記憶があります(1MBとか10MBとか。具体数は忘れました…)が、この記事を書きながら公式ドキュメントを確認したところ、今はPagesと同じサイズ制限になっているようです。その点ではPagesの優位性は薄れているかと思います。
https://developers.cloudflare.com/workers/static-assets/#limitations

CI/CDはPagesの方が設定が楽

WorkersでCI/CD的なことをやるためには、Github Actionsを使う必要があります。一方PagesはGithubと連携させればCloudflareのダッシュボードからGUIで設定が可能なので、かなり簡単です。
Deploy HookもWorkersには今の所無さそうなので、CMSでコンテンツを作ってサイトを更新するような運用は、Pagesでやったほうが簡単に済ませられそうです。
これらはWorkersも同じようになればいいんですが……今後に期待ですね🤤

おわりに

今回はFrontend on Cloudflare Workers的なことを実現してみた時のことを書き出してみました。冒頭でも記載した通り、この機能に関しては現状Beta版とされていて、ドキュメントだけを見てもアップデートが色々と入っていました。またPagesとの互換性向上も期待できそう[1]で、今後は統一等もあり得るのかなぁと思っています。

この記事を書きながらドキュメントや実装、Github Actionsのworkflowを見直していたら、ブラッシュアップや修正ができそうな余地が見つかりました。時間を見つけて色々試し、また記事化できればいいな〜とふんわり思っています。

ということでだいぶ早いですが良いお年を〜ノシ

脚注
  1. We plan to bridge the gaps between Workers and Pages and provide ways to migrate your Pages projects to Workers. とのこと。 ↩︎

Aidemy Tech Blog

Discussion