node.jstypescriptnpmwebpackwebpack-dev-server

Webpack 5 error - Uncaught ReferenceError: require is not defined


I'm getting this error when trying to access main page of my app in the browser:

Uncaught ReferenceError: require is not defined
at Object.events (main.bundle.js:90508:1)
at __webpack_require__ (main.bundle.js:91217:33)
at fn (main.bundle.js:91451:21)
at eval (emitter.js:1:20)
at Object../node_modules/webpack/hot/emitter.js (main.bundle.js:90413:1)
at __webpack_require__ (main.bundle.js:91217:33)
at fn (main.bundle.js:91451:21)
at eval (reloadApp.js:4:80)
at Object../node_modules/webpack-dev-server/client/utils/reloadApp.js (main.bundle.js:90371:1)
at __webpack_require__ (main.bundle.js:91217:33)

The exact line in the main.bundle is:

module.exports = require("events");

I've seen other posts mentioning type and nodeExternals but my issue doesn't seem immediately related to that because type is not mentioned in my package.json and nodeexternals is not in my weboack file.

webpack (.js) file:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const DotEnv = require('dotenv-webpack');
    
module.exports = {
  target: 'web',
  externalsPresets: { node: true },
  entry: path.resolve(__dirname, '../src/index.tsx'),
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, '../dist'),
    publicPath: '/'
},
  plugins: [
    new CleanWebpackPlugin(),
    new DotEnv({
      path: path.resolve(__dirname, '../.env'),
      safe: true,
      systemvars: true,
      silent: false,
      defaults: true,
    }),
    new HtmlWebpackPlugin({
      title: 'My Test App',
      favicon: 'public/favicon.ico',
      template: 'public/index.html',
    }),
    new webpack.ProvidePlugin({
      process: 'process/browser',
    }),
  ],
  resolve: {
    extensions: ['*', '.js', '.jsx', '.tsx', '.ts'],
    alias: {
      '~': path.resolve(__dirname, '../src'),
      handlebars: 'handlebars/dist/handlebars.min.js',
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx|tsx|ts)$/,
        exclude: /node_modules/,
        include: [
          path.join(__dirname, '../src'),
          path.join(__dirname, '../config'),
        ],
        use: 'ts-loader',
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif|ico)$/i,
        type: 'asset/resource',
        exclude: /node_modules/,
        use: ['file-loader?name=[name].ext'],
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  devServer: {
    static: {
      directory: path.join(__dirname, '../public'),
    },
    compress: true,
    port: 8080,
    proxy: {
      '/api': {
        target: 'https://localhost:9443',
        pathRewrite: { '^/api': '' },
      },
    },
  },
  optimization: {
    usedExports: true,
  },
};

package.json

{
  "name": "test-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@material-ui/core": "^4.10.0",
    "@material-ui/icons": "^4.9.1",
    "@redux-saga/testing-utils": "^1.1.3",
    "@testing-library/react": "^10.4.5",
    "@types/react-redux": "^7.1.1",
    "@types/react-router": "^5.1.0",
    "@types/react-router-dom": "^5.1.0",
    "awesome-debounce-promise": "^2.1.0",
    "brace": "^0.11.1",
    "classnames": "^2.2.6",
    "connected-react-router": "^6.5.2",
    "dotenv": "4.0.0",
    "dotenv-expand": "4.2.0",
    "file-loader": "0.11.2",
    "fs-extra": "3.0.1",
    "handlebars": "^4.7.7",
    "history": "^4.7.2",
    "jimp": "^0.16.1",
    "lodash": "^4.17.21",
    "moment": "^2.29.3",
    "object-assign": "4.1.1",
    "oidc-client": "^1.5.0",
    "path": "^0.12.7",
    "postcss-flexbugs-fixes": "4.1.0",
    "postcss-loader": "3.0.0",
    "postcss-normalize": "8.0.1",
    "postcss-preset-env": "6.7.0",
    "postcss-safe-parser": "4.0.1",
    "print-js": "^1.0.61",
    "promise": "8.0.1",
    "ra-data-json-server": "^3.5.5",
    "ra-data-simple-rest": "^3.5.5",
    "raf": "3.4.0",
    "react": "16.14.0",
    "react-ace": "9.4.0",
    "react-admin": "^3.6.0",
    "react-date-range": "^1.0.3",
    "react-dev-utils": "^10.2.0",
    "react-dom": "16.14.0",
    "react-dropzone": "^11.1.0",
    "react-iframe-comm": "^1.2.2",
    "react-jss": "^8.6.1",
    "react-placeholder": "^3.0.2",
    "react-redux": "^7.1.0",
    "react-router": "^5.1.0",
    "react-router-dom": "^5.1.0",
    "react-select": "^2.4.2",
    "reactstrap": "^6.4.0",
    "recharts": "^1.8.5",
    "resolve": "1.15.0",
    "swagger-client": "^3.8.24",
    "typescript": "^4.7.3",
    "util": "^0.12.4",
    "uuid": "^3.3.2"
  },
  "scripts": {
    "build": "webpack build --config ./config/webpack.common.js --mode development",
    "start": "webpack serve --config ./config/webpack.common.js --mode development",
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.11.10",
    "@types/dotenv-webpack": "^7.0.3",
    "@types/enzyme": "^3.1.15",
    "@types/enzyme-adapter-react-16": "^1.0.3",
    "@types/html-webpack-plugin": "^3.2.6",
    "@types/jest": "^22.2.3",
    "@types/moment": "^2.13.0",
    "@types/node": "^12.7.11",
    "@types/prop-types": "^15.7.1",
    "@types/react": "^16.3.11",
    "@types/react-dom": "^16.0.5",
    "@types/webpack": "^5.28.0",
    "@typescript-eslint/eslint-plugin": "^5.27.0",
    "@typescript-eslint/parser": "^5.27.0",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.1",
    "dotenv-webpack": "^7.1.0",
    "enzyme": "^3.9.0",
    "enzyme-adapter-react-16": "^1.7.0",
    "enzyme-to-json": "^3.3.5",
    "eslint": "^8.16.0",
    "eslint-config-react-app": "^7.0.1",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-react": "^7.30.0",
    "html-webpack-plugin": "^5.5.0",
    "jest": "^24.0.0",
    "jest-fetch-mock": "^2.1.2",
    "jest-junit": "8.0.0",
    "lint-staged": "^7.2.0",
    "prettier": "1.13.5",
    "style-loader": "^3.3.1",
    "ts-jest": "^24.0.0",
    "ts-loader": "^9.3.0",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.9.2",
    "webpack-merge": "^5.8.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "outDir": "dist",
    "sourceMap": true,
    "module": "commonjs",
    "target": "es6",
    "jsx": "react",
    "noImplicitAny": false,
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "strictPropertyInitialization": false,
    "preserveSymlinks": true,
    "forceConsistentCasingInFileNames": false,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "baseUrl": ".",
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "paths": {
      "~/*": ["src/*"]
    },
    "rootDir": "./",
    "suppressImplicitAnyIndexErrors": true
  },
  "exclude": [
    "node_modules",
    "scripts",
    "acceptance-tests",
    "jest",
    "coverage",
    "config"
  ]
}

Can someone please help?


Solution

  • I solved the issues after looking at my webpack config file, after adding source maps to the config:

      devtool: 'inline-source-map',
    

    I noticed something weird when I looked at the error again in DevTools, it showed fs, events and other folders outside of the file structure which lead me to question this line of code within the config:

      externalsPresets: { node: true },
    

    According to the documentation, the description is

    Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.

    So I removed that and got more errors which lead me to resolving the issue by adding the following fallback:

      resolve: {
        extensions: ['*', '.js', '.jsx', '.tsx', '.ts'],
        alias: {
          '~': path.resolve(__dirname, '../src'),
          handlebars: 'handlebars/dist/handlebars.min.js',
        },
        fallback: {
          fs: false,
          tls: false,
          net: false,
          path: false,
          zlib: false,
          http: false,
          https: false,
          stream: false,
          crypto: false,
          assert: false,
        },