Fix Dotenv Error in Create React App with Webpack Polyfills Guide

I’m facing an issue with my React app where I keep getting errors related to missing modules in dotenv while using create-react-app. Every time I try to compile, I see errors like “Can’t resolve ‘fs’,” “Can’t resolve ‘path’,” and “Can’t resolve ‘os’.” It turns out that Webpack 5 no longer includes polyfills for Node.js core modules by default, so now I need to configure polyfills manually. Following the provided instructions, I added a webpack.config.js file and tried adding a fallback for the missing modules, like "path": require.resolve("path-browserify"). However, even with these adjustments, the errors persist, and I’m trying to figure out the right configuration to get this working smoothly.

Error Code:

codeCompiled with problems: X

ERROR in ./node_modules/dotenv/lib/main.js 1:11-24

Module not found: Error: Can't resolve 'fs' in 'C:\Users\USER\Desktop\dapps\nefty\node_modules\dotenv\lib'


ERROR in ./node_modules/dotenv/lib/main.js 3:13-28

Module not found: Error: Can't resolve 'path' in 'C:\Users\USER\Desktop\dapps\nefty\node_modules\dotenv\lib'

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 }


ERROR in ./node_modules/dotenv/lib/main.js 5:11-24

Module not found: Error: Can't resolve 'os' in 'C:\Users\USER\Desktop\dapps\nefty\node_modules\dotenv\lib'

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: { "os": require.resolve("os-browserify/browser") }'
- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "os": false }

Afterward, I created webpack.config.js and added the fallback as shown below:

codemodule.exports = {
resolve: {
fallback: { "path": require.resolve("path-browserify") },
},
};

There’s still no difference after applying the changes. I checked a similar issue on their GitHub page, but couldn’t find a working fix. Most of the comments just highlighted the problem without offering any practical solutions.

The errors you’re encountering stem from Webpack 5 no longer providing polyfills for certain Node.js core modules (fs, path, and os) by default. This is why dotenv, which relies on these modules, throws errors when used with Webpack 5 in a React app. To resolve this, you need to install the necessary polyfill packages and add appropriate fallbacks in your webpack.config.js file.

Solution:

Install the polyfills for the missing modules:

codenpm install path-browserify os-browserify browserify-fs

Create or modify webpack.config.js to include fallbacks for fs, path, and os as shown below:

codeconst path = require('path');

module.exports = {
resolve: {
fallback: {
"fs": require.resolve("browserify-fs"),
"path": require.resolve("path-browserify"),
"os": require.resolve("os-browserify/browser")
}
}
};

Ensure your configuration is used by create-react-app: Since create-react-app doesn’t allow custom Webpack configurations directly, you’ll need to use a tool like react-app-rewired to apply your configuration.

  • First, install react-app-rewired:
codenpm install react-app-rewired --save-dev
  • Then, in your package.json, modify the scripts section to use react-app-rewired instead of react-scripts:
code"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test"
}
  • Next, create a config-overrides.js file in the root directory of your project and add your Webpack configuration to it:
const path = require('path');

module.exports = function override(config) {
config.resolve.fallback = {
"fs": require.resolve("browserify-fs"),
"path": require.resolve("path-browserify"),
"os": require.resolve("os-browserify/browser")
};
return config;
};

Explanation:

  1. Polyfills: Installing path-browserify, os-browserify, and browserify-fs provides browser-compatible versions of the path, os, and fs modules. These modules allow your app to handle dotenv functionality in a way compatible with Webpack 5’s new configuration.
  2. Fallback Configuration: By specifying fallbacks for fs, path, and os, you tell Webpack to use these browser-compatible modules instead of the Node.js versions. This is necessary since React applications run in the browser, which doesn’t have access to native Node.js modules.
  3. Using react-app-rewired: Since create-react-app doesn’t support custom Webpack configurations out of the box, react-app-rewired is a tool that enables you to override and modify the Webpack configuration without ejecting from create-react-app.

By following these steps, your application should compile successfully without throwing module resolution errors for dotenv.

Final Thought:

In handling polyfills in Webpack 5 can be tricky, especially when working with modules like dotenv that rely on Node.js core functionalities. By setting up polyfills for fs, path, and os and using react-app-rewired to customize your configuration, you can smoothly run your React app without hitting these compatibility issues. This solution provides a robust way to bridge the gap between Node.js modules and browser-based environments, ensuring your app remains stable and functional.

Related blog posts