javascriptreactjswebpackbabeljs

Error in build file (babel-node): ReferenceError: require is not defined in ES module scope, you can use import instead


EDIT: Minimal Reproducible Code attached below

I am able to successfully build an old codebase of ours but when running the code using node ui/dist/server, I am getting an error:

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/Users/user/code/node/myapp/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at Object.@babel/runtime/helpers/interopRequireDefault (file:///Users/user/code/node/myapp/ui/dist/server/index.js:19088:1)
    at __webpack_require__ (file:///Users/user/code/node/myapp/ui/dist/server/index.js:20072:40)
    at file:///Users/user/code/node/myapp/ui/dist/server/index.js:20119:30
    at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
    at ModuleLoader.import (node:internal/modules/esm/loader:473:24)
    at asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)

My babelrc is:

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "esmodules": true
        },
        "modules": false
      }
    ],
    ["@babel/preset-react", {
      "runtime": "automatic" 
    }]
  ],
  "sourceType": "unambiguous",
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-transform-modules-commonjs",
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-transform-destructuring",
    "@babel/plugin-transform-parameters",
    "transform-decorators-legacy",
    "@babel/plugin-transform-class-properties",
    "syntax-dynamic-import"
  ],
  "env": {
    "development": {
      "plugins": [
        "transform-react-jsx-self"
      ]
    },
    "production": {
      "presets": [
        "react-optimize"
      ]
    },
    "test": {
      "plugins": [
        // "transform-es2015-modules-commonjs", 
        "dynamic-import-node"
      ]
    }
  }
}

I tried experimenting with the @babel/plugin-transform-modules-commonjs plugin but the error persists. The error is in a build file.

Line 20119:

var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "@babel/runtime/helpers/interopRequireDefault");

Line 19088:

module.exports = require("@babel/runtime/helpers/interopRequireDefault");

Package.json snippets:

"type: module"

"dependencies": {

"@babel/plugin-transform-react-jsx": "^7.25.2",
"@babel/runtime": "^7.25.0",
"babel-plugin-transform-react-jsx-self": "^6.22.0",
}

Minimal Reproducible Code: https://github.com/Exter-dg/minimalBabel

Edit: I created a minimal reproducible example where I just print today's date (in server.js) using moment. I have used same babel config and webpack config. The dist/server/index.js file that babel-node generates is using import statements from my coedebase as expected. However, it also uses __webpack_modules__ which uses require to import dependencies. This is causing the error. Seems like a configuration mistake in babel/Webpack


Solution

  • I was doing 2 things incorrectly. One was using a plugin in babelrc that transforms ECMAScript modules to CommonJS which was generating require statements in the build file. Removing this plugin from babel was one of the fixes required.

    Plugin was - @babel/plugin-transform-modules-commonjs

    Another thing was how webpack was handling externals. For setting node_modules as externals we made use of nodeExternals which is a part of webpack-node-externals package. This, by design, uses require to import these external packages at runtime. This can be changed by setting the importType property in nodeExternals:

    nodeExternals({
          importType: 'module',
          allowlist: [/\.(?!(?:jsx?|json)$).{1,5}$/i, /react-toolbox/],
    }),
    

    This results in a build file which does not use require to fetch external packages and hence is compatible with ES module.