← ブログ一覧
サブ記事

Cloudflare WorkersではNode.jsが使えない——fs.readFileで即死した話

AstroサイトをCloudflare Pagesにデプロイしたら node:fs が動かなかった。原因と?rawを使った解決法を解説


登場人物

  • リナ社長 … 高校生なのに会社経営するやり手ギャル。テックにも強くてAI活用が得意。
  • タクヤ … 入社3年目の男性社員。真面目で少しだけコードが書ける。

タクヤ「社長、Claudeにコード作ってもらったのに、デプロイしたら即エラーって何ですか」

リナ社長「あーそれ、Cloudflare Workersの罠にハマったやつじゃん。てか同じとこで詰まった人めちゃくちゃ多いと思う」

タクヤ「どういうことですか……?」


何が起きたのか

ミニロト解析ページでは、当選番号のCSVデータを読み込む必要があった。

最初にClaudeが生成したコードはこんな感じ:

import fs from 'node:fs';
import path from 'node:path';

const csv = fs.readFileSync(
  path.resolve('src/data/miniloto.csv'),
  'utf-8'
);

ローカルでは問題なく動いた。でもCloudflare Pagesにデプロイした瞬間、こうなった。

Error: No such module "node:fs"

タクヤ「え、fsって普通のNode.jsの機能ですよね?なんで動かないんですか」

リナ社長「そこ!Cloudflare Workersって実はNode.jsじゃないんだよね」


なぜ node:fs が動かないのか

Cloudflare Pagesの裏側で動いているのは Cloudflare Workers というランタイム。これはNode.jsではなく、V8エンジン直接で動くサンドボックス環境。

環境ランタイムnode:fs
ローカル (npm run dev)Node.js✅ 使える
Cloudflare PagesCloudflare Workers (V8)❌ 使えない

タクヤ「ローカルで動くのに本番で動かないのは最悪ですね……」

リナ社長「まじでね。でも解決策はシンプルだよ」


解決策:?raw インポートで直接読む

AstroにはViteの ?raw インポートという機能があって、ファイルの中身を文字列としてそのまま読み込める。これはビルド時に解決されるのでWorkersのランタイムに依存しない。

// ❌ Before(node:fsを使う方法)
import fs from 'node:fs';
const csv = fs.readFileSync('src/data/miniloto.csv', 'utf-8');

// ✅ After(?rawインポートを使う方法)
import rawCsv from '../data/miniloto.csv?raw';
const csv = rawCsv;

タクヤ?raw ってなんですか、初めて見ました」

リナ社長「Viteの機能でね、ファイルをそのまま文字列で取り込める。Astroの裏側はViteだから使えるんだよ」

タクヤ「ビルド時に解決されるってことは、Workersのランタイムに関係なくなるってことか」

リナ社長「そーそー。理解が早くなってきたじゃん」


ポイントまとめ

リナ社長「今回の学びをまとめるとこれ」

  • Cloudflare Workers は Node.js ではないnode:fsnode:path は使えない
  • ローカルで動いてもデプロイで死ぬことがある → 環境の違いを最初から意識する
  • 静的ファイルは ?raw で読む → ビルド時に解決されるのでランタイムに影響しない

タクヤ「最初からこれ知ってたら詰まらなかったんですね」

リナ社長「そういうこと。だからClaudeに指示するときも”Cloudflare Workersで動かすこと・node:fsは使わないこと”って最初に伝えるのがコツ。制約を先に教えると正しいコードを出してくれる」


ミニロト解析ページ作成の全体まとめ記事に戻る

コメント