How to fix require is not defined in JS

Feb 8, 2023 | Read time 8 minutes

🔔 Table of contents

Introduction

I was working with a vanilla JS setup for a legacy application and came across the error:

Uncaught ReferenceError: require is not defined

ReferenceError: require is not defined
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)

I guess when you are working with Node JS server-side applications you forget that it is not supported in the browser.

The error “require is not defined” usually occurs when you’re trying to use the CommonJS module system in a browser environment where it’s not supported.

Require() is only for server-side code eg - in Node applications!

To fix this, you have several options:

  1. Use a bundler like Webpack or Rollup, which will compile your code and its dependencies into a single bundle that can be loaded by the browser.
  2. Use a library like Browserify, which will allow you to use CommonJS modules in the browser.
  3. We can use ES6 module import/ export syntax instead of require(). This is supported natively in modern browsers.
  4. Consider using RequireJS in the browser script tag

What is CommonJS anyway??

CommonJS is a specification for defining modules in JavaScript that run in a server-side environment. It was originally designed for use with Node.js, but can be used in other server-side JavaScript environments as well.

In CommonJS, each module is defined in its own file and exports values (e.g. functions, objects) that can be consumed by other modules. The exports of a module are made available through the module.exports object.

Here is an example of a CommonJS module:

// myModule.js

function greet(name) {
  console.log("Hello, " + name + "!");
}

module.exports = greet;

And here is an example of another module consuming the exported value from myModule.js:

// index.js

const greet = require("./myModule");

greet("John");
// Output: Hello, John!

1. Use a bundler like Webpack or Rollup.

Webpack which will compile your code and its dependencies into a single bundle that can be loaded by the browser.

Here is a basic example of using Webpack with CommonJS:

First, install the necessary packages using npm:

  • npm init -y
  • npm install --save-dev webpack webpack-cli

Create a CommonJS module in a file named index.js:

function greet(name) {
  console.log("Hello, " + name + "!");
}

module.exports = greet;

Create a Webpack configuration file named webpack.config.js:

module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js',
  },
};

Use the webpack command to bundle your module:

npx webpack

This will create a file named bundle.js that contains your module and all of its dependencies.

Load the bundled file in an HTML file:

<!DOCTYPE html>
<html>
<head>
  <script src="bundle.js"></script>
</head>
<body>
  <script>
    const greet = require("./index");
    greet("John");
  </script>
</body>
</html>

This will load the bundle.js file in the browser, which will make the greet function available for use.

2. Use a library like Browserify,

Browserify is a library that allows you to write in CommonJS modules in the browser.

It works by bundling your code and its dependencies into a single JavaScript file that can be loaded by the browser.

Here is a basic example of using Browserify:

First, install Browserify globally on your computer using npm:

npm install -g browserify Create a CommonJS module in a file named index.js:

function greet(name) {
  console.log("Hello, " + name + "!");
}
module.exports = greet;

Use the browserify command to bundle your module:

browserify index.js -o bundle.js

This will create a file named bundle.js that contains your module and all of its dependencies.

Load the bundled file in an HTML file:

<!DOCTYPE html>
<html>
<head>
  <script src="bundle.js"></script>
</head>
<body>
  <script>
    const greet = require("./index");
    greet("John");
  </script>
</body>
</html>

This will load the bundle.js file in the browser, which will make the greet function available for use.

3. We can use ES6 module import/ export syntax instead of require(). This is supported natively in modern browsers.

Here is an example of using the ES6 import syntax:

Create a module in a file named greet.js:

export function greet(name) {
  console.log(`Hello, ${name}!`);
}

This exports a single function named greet.

Import the module in another file, for example main.js:

import { greet } from './greet.js';
greet('John');

This imports the greet function from the greet.js module and calls it.

<!DOCTYPE html>
<html>
  <head>
    <script type="module" src="main.js"></script>
  </head>
  <body>
  </body>
</html>

4. Consider using RequireJS in the browser script tag

We can use RequireJS as follows:

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
  <script>
    requirejs(['math'], function(math) {
      console.log(math.add(1, 2));
    });
  </script>
</head>
<body>
</body>
</html>

Now in our math.js file looks like the following:

define(function() {
  return {
    add: function(a, b) {
      return a + b;
    }
  };
});

Issues with server-side require() - Node

Now this error of “ReferenceError: require is not defined” can still popup in the server side as well (since Node 14+).

Consider the following express application, I saw this error came up:

const express = require('express');
                ^
ReferenceError: require is not defined
    at ModuleJob.run (node:internal/modules/esm/module_job:152:23)
    at async Loader.import (node:internal/modules/esm/loader:166:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5)

The main cause of this issue because of the “type” attribute in the package.json:

{
    "type": "module"
}

The above setting tells Node, that we want our application to use the newer ES6 module import and export syntax rather than the CommonJS require() syntax.

You should not mix and match ES6 modules and CommonJS syntax together!

To this this issue, we can do the following:

  1. Change the “type” value from “module” to “commonjs”
{
    "type": "commonjs"
}
  1. Change all require() CommonJS syntax over to the new ES6 module syntax with import and export!

So instead of doing this:

const express = require('express');

We can convert to the new ES6 syntax with import/export. (Note: keep in mind that you still have the “type” value as “module”)

import express from 'express';

Summary

In this post I went over the error of “ReferenceError: require is not defined”. This error usually occurs in the browser - due to using the require() method in CommonJs which is not supported in browsers.

The require() CommonJS syntax is natively supported in server-side code such as Node applications.

To fix this error, we can use tools to convert our JavaScript so that it is supported in the browser. We can use Webpack, Browserify or the external library RequireJS.

An alternative option is to convert our require() CommonJS code to the new ES6 Module syntax with import and export keyword.

This “ReferenceError: require is not defined” error can sometimes even appear in Node apps. This is usualy due to the package.json having the “type” attribute as “module”!

We can fix this by changing the “type” attribute to “commonjs” or convert our code over to ES6!

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube