Module not found: Can't resolve 'fs' の直し方
実際に出るエラー
Client Component から fs などのサーバー専用のモジュールにたどり着いたときに出るビルドエラーです。
何が起きているか
'use client' を書いたファイルは、ブラウザ用にも束ねられます。そこから読み込んだファイルも、その先で読み込んでいるファイルも、すべて束ねる対象です。
ブラウザにはファイルを読む仕組みがありません。だから、束ねる途中で fs にたどり着くと、行き先が見つからずにビルドが止まります。
'use client'
import fs from 'fs' // ← ブラウザ用に束ねられない
- Builduse client のファイルを見つける
ここから先はブラウザ用にも束ねる。
- Buildimport を順にたどる
そのファイルが読み込むファイルも、その先も全部。
- Buildfs にたどり着く
ブラウザ用の行き先が無い。Can't resolve 'fs' で止まる。
自分で fs を書いていないのに出る
いちばん多いのはこの形です。使っている関数ではなく、読み込んだファイルごと束ねられます。
// lib/mail.ts
import { connect } from 'net' // ← サーバー専用
export function sendMail(host: string) {
return connect(25, host)
}
export function isEmail(v: string) { // ← ブラウザでも使いたい
return /^[^@\s]+@[^@\s]+$/.test(v)
}
// app/form.tsx
'use client'
import { isEmail } from '../lib/mail' // ← isEmail しか使っていなくても止まる
実機で確かめました。Can't resolve 'net' で止まります。エラーが指す場所は lib/mail.ts の1行目ですが、直すべきは form.tsx の import です。
どのモジュールで止まるか
Node.js の組み込みモジュールを、1つの Client Component から読み込んで確かめました。
| モジュール | ビルド |
|---|---|
| fs | 止まる |
| net / tls / dns | 止まる |
| child_process | 止まる |
| path / os / crypto | 止まらなかった |
データベースやメールのライブラリは、中で net や tls を使っていることが多いです。そうしたライブラリを Client Component から読み込むと、同じ形で止まります。
止まらなかったものも、ブラウザで Node.js と同じように動くとは限りません。サーバーの処理はサーバーに置いてください。
直し方
1. ファイルを分ける
ブラウザでも使う関数と、サーバー専用の関数を、別のファイルにします。
// lib/validate.ts ← ブラウザでも使う
export function isEmail(v: string) {
return /^[^@\s]+@[^@\s]+$/.test(v)
}
フォームは lib/validate.ts だけを読み込みます。
2. サーバーで読んで、結果を渡す
ファイルの中身を画面に出したいなら、Server Component で読んで、文字として Client Component に渡します。
// app/page.tsx(Server Component)
import { readFileSync } from 'node:fs'
import View from './view'
export default function Page() {
const text = readFileSync(process.cwd() + '/data.txt', 'utf8')
return <View text={text} />
}
実機で、読んだ文字が画面に出ることを確かめました。
3. サーバー専用のファイルに印を付ける
サーバー専用のファイルの先頭に import 'server-only' を書くと、Client Component から読み込んだ時点で、サーバー専用のファイルだと分かる文言で止まります。Can't resolve より原因が分かりやすくなります(server-only の解説)。
出典
- nextjs.org/docs/messages/module-not-found
- nextjs.org/docs/app/getting-started/server-and-client-components
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。