RemixアプリをCloudflare Pagesへデプロイする際は、ライブラリ名に注意
Remixアプリ開発でCloudflare Pagesへデプロイ時に発生した”Could not resolve”エラーの対策をまとめました。ライブラリのインポート元を@remix-run/cloudflareに変更し、Node.js環境依存エラーを解消できました。Remixではライブラリの選択に注意し、プロキシーファイルを作成することで環境別のライブラリインポートも検討できます。
目次
Remixでアプリ開発を個人的に試しているところです。Cloudflare Pagesへのデプロイを試みた際、ちょっとしたエラーに遭遇したので、その原因と対策を簡単にまとめました。
遭遇したエラー
wranglerコマンドを利用してデプロイを試みると、次のようなエラーが発生しました。
$ wrangler pages deploy
▲ [WARNING] Warning: Your working directory is a git repo and has uncommitted changes
  To silence this warning, pass in --commit-dirty=true
✘ [ERROR] Could not resolve "crypto"
    ../node_modules/@remix-run/node/node_modules/cookie-signature/index.js:5:21:
      5 │ var crypto = require('crypto');
        ╵                      ~~~~~~~~
  The package "crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
✘ [ERROR] Could not resolve "stream"
    ../node_modules/stream-slice/index.js:3:24:
      3 │ var Transform = require('stream').Transform;
        ╵                         ~~~~~~~~
  The package "stream" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
cryptoやstreamなどに関するエラーなので、Node.js系のライブラリをインポートしているか、処理を実装しているかのどちらかであることはわかります。
wrangler.tomlの設定は問題がなかった
ここで不思議だったのは、wrangler.tomlでは互換性のフラグ設定ができていたことです。このようにnodejs_compatが入っているので、WranglerやCloudflare側の設定は問題がないといえます。
name = "remix-app"
compatibility_date = "2024-06-05"
compatibility_flags = [ "nodejs_compat" ]
pages_build_output_dir = "./build/client"読み込むライブラリを@remix-run/nodeから@remix-run/cloudflareに変更する
見落としていた点は、Remix系の関数をインポートする方法でした。いくつかのドキュメントとそのサンプルコードを見ながら実装していたため、次のサンプルコードのように、@remix-run/nodeと@remix-run/cloudflareの両方を使っている状態になっていました。ここで@remix-run/nodeをインポートしているため、初めに紹介したNode.js環境依存系のエラーが発生していたと考えられます。
import type { LoaderFunctionArgs } from "@remix-run/cloudflare";
import { json } from "@remix-run/node";
export async function loader({ context }: LoaderFunctionArgs) {
  return json({
    posts: [{
      id: 12
    }]
  });
}
対策はとてもシンプルで、インポート元を@remix-run/nodeから@remix-run/cloudflareに変えるだけです。
import { json } from "@remix-run/cloudflare";この変更を保存すると、デプロイが問題なく完了しました。
  To silence this warning, pass in --commit-dirty=true
✨ Compiled Worker successfully
🌎  Uploading... (11/11)
✨ Success! Uploaded 11 files (2.29 sec)
✨ Uploading _headers
✨ Uploading Functions bundle
✨ Uploading _routes.json
🌎 Deploying...
✨ Deployment complete! Take a peek over at https://xxxxx.pages.dev
✨  Done in 17.61s.
Remixでは利用するモジュールをどこからインポートするかを意識しておくことが、デプロイ時のトラブルなどを減らすことにつながりそうです。もし複数環境を利用する可能性がある場合などでは、export { A, B, C } from ”@remix-run/node”のようなプロキシー的なファイルを作ってみてもよいかもしれません。