webpack 5 "process is not defined" - Fix Removed Node Polyfills
webpack 4 auto-polyfilled Node globals like process and Buffer for the browser. webpack 5 removed that, so code (or a dependency) referencing process now throws at runtime, and the build no longer auto-injects the shim.
What this error means
After moving to webpack 5, the app throws Uncaught ReferenceError: process is not defined (or Buffer/global), or the build errors that a Node core module needs a fallback. webpack 4 had no such issue.
Module not found: Error: Can't resolve 'process/browser'
# or at runtime:
Uncaught ReferenceError: process is not defined
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.Diagnose it: is it resolution, transform, or memory?
Bundler failures in CI fall into three families and the error text often points at the wrong one. A module that resolves on your machine and not on the runner is nearly always case sensitivity or a missing optional dependency; a transform error is a config or version mismatch; and an unexplained kill with no stack is the out-of-memory reaper, not a build error at all.
# 1. resolution: does the file exist with EXACTLY that case?
git ls-files | grep -i "the/imported/path"
# 2. transform: what versions is CI actually resolving?
npm ls webpack vite rollup esbuild typescript 2>/dev/null | head -20
# 3. memory: was it killed rather than failed?
# exit 137 = SIGKILL (OOM). Nothing in the bundler log will explain it.
node --max-old-space-size=4096 node_modules/.bin/vite buildCommon causes
webpack 5 dropped automatic Node polyfills
Code or a dependency reads process.env, Buffer, etc., expecting the browser polyfill webpack 4 injected automatically. webpack 5 ships none by default.
No ProvidePlugin/DefinePlugin shim configured
Without explicitly defining process.env or providing process/Buffer, the reference is undefined in the bundle.
How to fix it
Provide the polyfill and define process.env
Inject process/Buffer with ProvidePlugin and supply env values with DefinePlugin.
// webpack.config.js
const webpack = require('webpack')
plugins: [
new webpack.ProvidePlugin({ process: 'process/browser', Buffer: ['buffer', 'Buffer'] }),
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }),
],
resolve: { fallback: { process: require.resolve('process/browser'), buffer: require.resolve('buffer') } },Stop relying on Node globals in browser code
- Replace
process.env.Xreads with bundler-provided env (e.g. DefinePlugin orimport.meta.env). - Avoid
Buffer/globalin browser bundles; use Web APIs instead. - Add
resolve.fallbackonly for the specific core modules a dependency truly needs.
Make the build reproducible before you debug it
- Pin the Node major in
setup-nodeand inengines. A bundler that resolves native bindings will pick a different prebuilt binary across majors. - Delete
node_moduleslocally and reinstall from the lockfile before concluding the runner is at fault; most "works locally" reports are stale local state. - Set
CI=truelocally to reproduce. Several toolchains change behaviour under it, including treating warnings as errors. - Exit code 137 is an out-of-memory kill. Raise
--max-old-space-sizeor move to a larger runner rather than searching the bundler config.
How to prevent it
- Audit for
process/Buffer/globalusage before upgrading to webpack 5. - Inject env via DefinePlugin rather than expecting an ambient
process. - Add only the specific
resolve.fallbackpolyfills your deps require.