Webpack 5’s default configuration dropped Node.js’s built-in polyfills for modules like Buffer and path, breaking code that relied on them for browser environments.

Common Causes and Fixes

  1. Missing node-polyfill-webpack-plugin:

    • Diagnosis: You’ll see errors like ReferenceError: Buffer is not defined or TypeError: Path is not a constructor during the build or runtime.
    • Fix: Install the plugin:
      npm install --save-dev node-polyfill-webpack-plugin
      
      Then, add it to your webpack.config.js:
      const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
      
      module.exports = {
        // ... other webpack config
        plugins: [
          new NodePolyfillPlugin()
        ]
      };
      
    • Why it works: This plugin explicitly tells Webpack to include polyfills for Node.js core modules, making them available in the browser bundle.
  2. Incorrect resolve.fallback Configuration:

    • Diagnosis: If you’re trying to manually polyfill using resolve.fallback and getting Module not found errors for the polyfill itself (e.g., Can't resolve 'buffer').
    • Fix: Ensure your resolve.fallback points to the correct package and that the package is installed. For buffer, you’d typically use buffer:
      module.exports = {
        // ... other webpack config
        resolve: {
          fallback: {
            "buffer": require.resolve("buffer/"),
            "path": require.resolve("path-browserify")
          }
        }
      };
      
      Make sure you have these packages installed:
      npm install --save-dev buffer path-browserify
      
    • Why it works: resolve.fallback tells Webpack how to resolve module requests. By mapping buffer and path to their browser-compatible polyfill packages, Webpack knows where to find the code it needs. require.resolve ensures it points to the actual file location of the polyfill.
  3. Outdated Dependencies:

    • Diagnosis: Even with the plugin or resolve.fallback configured, you might see errors if a library you’re using is also expecting Node.js globals and hasn’t been updated to respect Webpack 5’s changes or relies on older polyfilling mechanisms.
    • Fix: Update all your project dependencies, especially those related to build tools and libraries that might interact with Node.js modules.
      npm update
      
      If a specific library is causing issues, try updating it individually:
      npm update <library-name>
      
    • Why it works: Newer versions of libraries are more likely to be compatible with Webpack 5’s module resolution strategy and may have their own internal polyfills or avoid relying on global Node.js objects.
  4. Incorrect Webpack Configuration Order:

    • Diagnosis: The node-polyfill-webpack-plugin might be loaded after other plugins or loaders that attempt to process modules before the polyfills are available, leading to ReferenceErrors.
    • Fix: Ensure NodePolyfillPlugin is one of the first plugins in your plugins array.
      const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
      
      module.exports = {
        // ... other webpack config
        plugins: [
          new NodePolyfillPlugin(), // Place it early
          // ... other plugins
        ]
      };
      
    • Why it works: Plugins are processed in the order they appear in the array. Placing the polyfill plugin early ensures that the necessary global objects (Buffer, process, etc.) are defined before any code that might immediately try to use them is processed by other loaders or plugins.
  5. process Global Not Polyfilled:

    • Diagnosis: Errors like TypeError: Cannot read properties of undefined (reading 'env') when trying to access process.env or other properties of the process global.
    • Fix: The node-polyfill-webpack-plugin handles process by default. If you’re using resolve.fallback, you need to add it explicitly:
      module.exports = {
        // ... other webpack config
        resolve: {
          fallback: {
            "buffer": require.resolve("buffer/"),
            "path": require.resolve("path-browserify"),
            "process": require.resolve("process/browser") // For process polyfill
          }
        }
      };
      
      Install the process polyfill:
      npm install --save-dev process
      
    • Why it works: Similar to Buffer and path, the process object is a Node.js global. The process/browser package provides a browser-compatible version of this object, enabling code that expects process.env or other properties to function correctly.
  6. Specific Library Conflicts:

    • Diagnosis: A particular library might have hardcoded checks for Node.js globals or use specific module resolution patterns that interfere with Webpack’s polyfilling. You might see cryptic errors originating from within that library’s code.
    • Fix: Consult the library’s documentation for Webpack 5 compatibility or browser build instructions. Sometimes, you might need to configure Webpack to ignore certain modules or provide specific fallbacks for that library. For example, if a library foo has issues:
      module.exports = {
        // ...
        plugins: [
          new NodePolyfillPlugin(),
          // ...
        ],
        module: {
          rules: [
            {
              test: require.resolve('foo'), // Target the problematic library
              use: 'source-map-loader', // Example: re-process with a loader
              enforce: 'pre',
            },
          ],
        },
        resolve: {
          fallback: {
            // ... other fallbacks
            'crypto': require.resolve('crypto-browserify'), // Example fallback for crypto
          }
        }
      };
      
      You might need to install crypto-browserify if not already present.
    • Why it works: This approach allows you to apply specific Webpack rules or fallbacks that address the unique way a problematic library interacts with the build process, overriding or supplementing the general polyfilling strategy.

After fixing these, the next error you’ll likely encounter is related to the crypto module if it’s also being used and not polyfilled.

Want structured learning?

Take the full Webpack course →