AstroCloudflareJavaScriptSaaS / FaaS

AstroのSSRモードで作成したサイトを、Cloudflare Pagesにデプロイする際の覚書

Astroは、サーバーサイドレンダリング(SSR)モードを持つが、Cloudflare Pages / Workersにデプロイする場合、Node.jsではない実行環境に注意が必要。AstroにCloudflareのSSRモードを追加するには、`astro add cloudflare`コマンドを実行。`astro.config.mjs`の変更を自動で行い、プレビューが表示される。しかし、Markdocファイルを読み込む際のエラーが発生した場合、Cloudflare Workers / Pages Functionsの実行環境ではfsモジュールがサポートされていないため、Markdownファイルの読み込みに関しては静的にビルドしてデプロイする必要がある。

広告ここから
広告ここまで

Astroには、サーバー側で処理を実行できるSSRモードが搭載されています。ただ、Cloudflare Pages / Workersにデプロイする場合は、実行環境がNode.jsではないことに注意が必要です。

AstroプロジェクトにCloudflareモジュールを追加する

CloudflareのSSRモードをAstroに足す場合、astro add cloudflareコマンドを実行します。

% npx astro add cloudflare
  Astro will run the following command:
  If you skip this step, you can always run it yourself later

 ╭────────────────────────────────────────────╮
 │ yarn add @astrojs/cloudflare astro@^2.1.0  │
 ╰────────────────────────────────────────────╯

? Continue? › (Y/n)

astro.config.mjsの変更まで自動で行ってくれます。実行時にプレビューが表示されるので、気になる方は確認しておきましょう。

Astro will make the following changes to your config file:

 ╭ astro.config.mjs ──────────────────────────────╮
 │ import { defineConfig } from 'astro/config';   │
 │ import mdx from '@astrojs/mdx';                │
 │ import sitemap from '@astrojs/sitemap';        │
 │ import markdoc from "@astrojs/markdoc";        │
 │                                                │
 │ import cloudflare from "@astrojs/cloudflare";  │
 │                                                │
 │ // https://astro.build/config                  │
 │ export default defineConfig({                  │
 │   site: 'https://example.com',                 │
 │   integrations: [mdx(), sitemap(), markdoc({   │
 │     nodes: {                                   │
 │       heading: {                               │
 │         render: 'Heading',                     │
 │         attributes: {                          │
 │           level: {                             │
 │             type: String                       │
 │           }                                    │
 │         }                                      │
 │       }                                        │
 │     }                                          │
 │   })],                                         │
 │   output: "server",                            │
 │   adapter: cloudflare()                        │
 │ });                                            │
 ╰────────────────────────────────────────────────╯

  For complete deployment options, visit
  https://docs.astro.build/en/guides/deploy/

問題なければ、yesと回答して編集を完了させます。


✔ Continue? … yes
  
   success  Added the following integration to your project:
  - @astrojs/cloudflare

AstroをCloudflareでSSRして使う際に踏んだエラー

試していたプロジェクトでは、次のエラーが出ました。

 error   post.render is not a function
  File:
    /Users/okamotohidetaka/sandbox/astro-markdoc/src/pages/docs/[...slug].astro:23:34
  Stacktrace:
TypeError: post.render is not a function
    at eval (/Users/okamotohidetaka/sandbox/astro-markdoc/src/pages/docs/[...slug].astro:23:34)

追いかけていくと、このエラーが根元にある様子でした。

 error   Could not resolve "module"
  File:
    dist/$server_build/_worker.mjs:10:7
  Code:
    9 | import 'string-width';
    > 10 | import 'module';
         |       ^
      11 | import 'node:fs/promises';
      12 | import 'node:url';
      13 | import 'html-escaper';

どうやら、fsとそれに関連するモジュールが利用できない(Cloudflare Workers / Pages Functionsの実行環境にない)ため、Markdownファイルを読み込めず、後続のrender関数が未定義になっていた・・・様子です。

そのため、このケースではMarkdownをやめて、microCMSなどのHeadless CMSでコンテンツを管理するようにしました。

まとめ: Cloudflare Pages / WorkersではMarkdownを含むサイトのSSRは難しい

Markdownファイルを読み込む際に、fsを利用します。コード内でimportしていなくとも、利用しているライブラリが内部的に使用している可能性も高く、「ファイルを読み込む処理を、サーバー側でやる場合はだいたいfsが使われている」と思って良いかと思います。

ただしこのfsモジュールは、2023/10時点でCloudflare Workers / Pages functionsの実行環境でサポートされていません。そのため、Markdownファイルを読み込むタイプのサイトについては、少なくともその部分だけは、静的にビルドした状態でCloudflareへデプロイするようにしましょう。

参考

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts