🥪

Denoを使用した静的サイトをCloudflare Workersで公開したメモ

に公開


以前、Node.js上で構築した静的サイトをwranglerを用いてCloudflare Pagesで公開しました。とある事情によりDeno上で静的サイトの一部を再構築したため同様に公開しようと思っていたところ、CloudflareがPagesではなくWorkersを使用することを推奨し始めたことを知ったためWorkersで公開することにしました。静的サイトをGitHub ActionsでWorkersで公開する事と、Denoではwranglerを使用できない事を迂回したりした備忘メモです。

方針

個人開発が前提。

対応概要

GitHub Actions上でビルドし、成果物ファイルをwrangler(wrangler-action)を用いてCloudflare Workersにアップロードする。

対応内容の理由

  • Cloudflareではビルドしない
    • ローカルもしくはGitHub Actionsでビルドする
      • Cloudflareはホスティングサービスとしてのみ使用しているため
      • わざわざ依存先を増やして複雑にしたくない
  • GitHub Actionsでビルドする
    • 資格情報の管理から解放されるため
      • 資格情報の言わばroot権限を人間が持ち続けるのは信用できない
      • ローカルからのアップロードの場合、端末のリプレース等が面倒になる
        • 全プロジェクトはWSL(vhdx)上のためポータブルだが掃除が面倒になる
  • Cloudflareとのやり取りは長期的に安定使用可能であろう方法を使用する
    • 何にも依存しない単なる成果物アップロードのみ使用する
      • Cloudflareを使用しなくなってもこの方法は使用可能と思われるため
    • WorkersのFrameworksは使用しない(調査しない)
      • Web Framework系は変化が激しくいつまでサポートされるのか不明なため
      • SSGには関係ない話な気はする
  • アップロードには設定項目等よく変わる印象があるので公式を使用する
    • Denoflareというツールがあるが、非公式なため使用しない
  • GitHub Actionsでwranglerを使用する
    • wranglerはNode.jsが必須かつ開発環境にインストールしたくないため
    • CloudflareがGitHub Actionsサポートを打ち切る可能性は低いという願望

具体的な内容

対応したファイル

deploy.yaml
name: Deploy Site
on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    timeout-minutes: 3
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Mask secrets
        run: echo "::add-mask::${{ secrets.CLOUDFLARE_WORKERS_URL }}"

      - name: Install Deno
        uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x

      - name: Build package
        run: deno task build

      - name: Deploy to Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
deno.json
{
  "tasks": {
    "build": "mv ./svelte.config.mjs ./svelte.config.js && deno run -A npm:vite build && rm -r ./node_modules",
  }
}
wrangler.toml
name = "name-of-workers"
compatibility_date = "2025-05-06"

[assets]
directory = "./build/"
not_found_handling = "404-page"
html_handling = "auto-trailing-slash"

簡単な補足と追記

資格情報などの設定

こちらの記事が詳しい。ログのマスクについても記載あり。

wrangler設定

公式のWorkers Configurationヘルプにも記載はあるが、こちらのヘルプの方が纏まっていて分かりやすい。通常mainは必須項目だが、Pagesの代わりに使用する場合は任意項目になることはここにしか書いていない。

ビルド前処理

Deno上でSvelteを用いて開発する時、以前書いたようにsvelte.config.jsファイル名をsvelte.config.mjsに変更する必要がある。しかしmjsのままビルドすると"No adapter specified"となり成果物が生成されない。これはどうやらアダプター設定を取得する際に固定ファイル名svelte.config.jsを確認しているためと思われる。これを回避するため、ビルド前にファイル名を変更している。

ビルド後処理

Denoでビルドした後、wranglerを使用しようとするとうまく動作しない。これはnode_modulesの内容がnpm準拠になっていないためと思われる。そのため、wranglerでアップロード処理を行う前にnode_modulesを削除してnpmが内容を作り直すようにしている。

カスタムドメイン設定

Cloudflareダッシュボードから設定可能。具体的には Compute (Workers) => Workers & Pages => name-of-workers => Settingsタブ => Domains & Routes => Add で設定可能。

雑記

wrangler自体は既にv4.xになっているのですが、wrangler-actionはまだv3が最新のようです。ログを見ると"The version of Wrangler you are using is now out-of-date."と出ているので、v4になった時点でdeploy.yamlを変更することになると思います。たぶん忘れます。

参考文献

Discussion