webpack 5 で「process is not defined」やコアモジュールの解決に失敗する
webpack 5 は Node.js コアモジュールの自動 polyfill をやめた。
ブラウザ向けビルドで process や crypto を参照すると未定義や解決失敗になる。
必要なものだけ resolve.fallback と ProvidePlugin で明示的に補う。
公開: 更新:
要約
Uncaught ReferenceError: process is not defined や Module not found: Error: Can't resolve 'crypto' が webpack 5 へ上げた直後に出るのは、webpack 5 が Node.js コアモジュールの自動 polyfill を廃止したためだ。
webpack 4 は crypto や stream を自動で browserify 版に差し替えていたが、5 では何も入らない。
必要なものだけを自分で補うのが正しい対処になる。
まずバンドルサイズを増やさない選択肢から検討する。
// webpack.config.js
module.exports = {
resolve: {
fallback: { fs: false, path: require.resolve("path-browserify") },
},
};実行例
webpack 5.110.3 で path を import したまま束ねようとすると、Module not found とともに「webpack 5 は Node.js のコアモジュールを自動では補わない」という案内と、fallback を書くか false にするかの二択が同じメッセージの中に示される。resolve.fallback に path-browserify と process/browser を割り当てた版と、fs: false で空モジュールに倒した版は、どちらも終了コード 0 でビルドが通った。
$ npx webpack
asset main.js 1.09 KiB [emitted] (name: main)
runtime modules 211 bytes 1 module
./src/index.js 95 bytes [built] [code generated]
ERROR in ./src/index.js 1:0-24
Module not found: Error: Can't resolve 'path' in '/tmp/tmp.FUSPmjBJVH/src'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
resolve 'path' in '/tmp/tmp.FUSPmjBJVH/src'
Parsed request is a module
using description file: /tmp/tmp.FUSPmjBJVH/package.json (relative path: ./src)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
/tmp/tmp.FUSPmjBJVH/src/node_modules doesn't exist or is not a directory
looking for modules in /tmp/tmp.FUSPmjBJVH/node_modules
single file module
using description file: /tmp/tmp.FUSPmjBJVH/package.json (relative path: ./node_modules/path)
no extension
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path doesn't exist
.js
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path.js doesn't exist
.json
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path.json doesn't exist
.wasm
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path.wasm doesn't exist
.html
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path.html doesn't exist
.css
Field 'browser' doesn't contain a valid alias configuration
/tmp/tmp.FUSPmjBJVH/node_modules/path.css doesn't exist
/tmp/tmp.FUSPmjBJVH/node_modules/path doesn't exist
/tmp/node_modules doesn't exist or is not a directory
/node_modules doesn't exist or is not a directory
webpack 5.110.3 compiled with 1 error in 57 ms
終了コード: 1$ npx webpack
asset main.js 25.1 KiB [emitted] (name: main)
runtime modules 883 bytes 4 modules
cacheable modules 21.2 KiB
./src/index.js 95 bytes [built] [code generated]
./node_modules/path-browserify/index.js 15.8 KiB [built] [code generated]
./node_modules/process/browser.js 5.29 KiB [built] [code generated]
webpack 5.110.3 compiled successfully in 73 ms
終了コード: 0$ npx webpack
asset main.js 3.46 KiB [emitted] (name: main)
runtime modules 883 bytes 4 modules
cacheable modules 61 bytes
./src/index.js 46 bytes [built] [code generated]
fs (ignored) 15 bytes [built] [code generated]
webpack 5.110.3 compiled successfully in 50 ms
終了コード: 0— 2026-09-10 時点の出力
検証環境
- 検証日
- 実行環境
node:20Debian GNU/Linux 12 (bookworm)- バージョン
- Node.js 20.20.2
- npm 10.8.2
- Python 3.11.2
- Git 2.39.5
この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。
よくある原因
- 自動 polyfill の廃止: webpack 5 はブラウザ向けビルドで Node.js コアモジュールを自動補完しない。移行ガイド(新しいタブで開く)にも、必要なら npm から互換モジュールを入れて自分で指定するよう書かれている。
- 依存パッケージが Node 前提: 自分のコードに
processが無くても、依存の内部がprocess.env.NODE_ENVを読んでいれば同じエラーになる。 - webpack 4 の設定が残っている:
node: { fs: 'empty' }は webpack 5 では機能しない。resolve.fallback.fs: falseに書き換える必要がある。 - サーバー専用コードの巻き込み: DB クライアントなどサーバー専用パッケージが、共通モジュール経由でブラウザ側の依存グラフに入っている。
解決策
1. 必要なコアモジュールだけ fallback を指定する
polyfill パッケージを入れ、resolve.fallback で対応付ける。
npm install --save-dev path-browserify stream-browserify buffer// webpack.config.js
module.exports = {
resolve: {
fallback: {
path: require.resolve("path-browserify"),
stream: require.resolve("stream-browserify"),
buffer: require.resolve("buffer/"),
},
},
};crypto-browserify のように数百 KB になる polyfill もある。
全部入れる前に、本当にブラウザで必要かを確認したほうがよい。
2. process / Buffer のグローバルを注入する
process と Buffer はモジュールではなくグローバル変数として参照されるため、resolve.fallback だけでは解決しない。ProvidePlugin で注入する。
// webpack.config.js
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
],
};process/browser は process パッケージに含まれるブラウザ向け実装で、別途インストールが必要になる。
3. 使わないモジュールは空にする
到達しないコードパスで参照されているだけなら、polyfill を入れずに false を指定してバンドルから外す。
// webpack.config.js
module.exports = {
resolve: {
fallback: { fs: false, child_process: false, net: false },
},
};webpack 4 の node: { fs: 'empty' } はこの書き方に置き換わった。
設定の対応関係は公式の node オプション(新しいタブで開く)にまとまっている。
4. ブラウザに持ち込まない
一番確実なのは、そもそも巻き込まないことだ。
サーバー専用の処理を別モジュールへ切り出し、ブラウザ側のエントリから参照しないようにする。
環境変数を渡したいだけなら DefinePlugin で定数として埋め込めば process 自体が不要になる。