Skip to content

ReferenceError: require is not defined in ES module scope

Problem

The error "ReferenceError: require is not defined in ES module scope" occurs when you attempt to use CommonJS require() syntax in a Node.js environment that's configured to use ES modules.

This typically happens when your package.json file contains "type": "module", or when you're using .mjs file extensions, which tell Node.js to treat your code as ES modules rather than CommonJS modules.

The original error was triggered by:

javascript
const sass = require('gulp-sass')(require('sass'));

When using ES modules, you can no longer use CommonJS-specific features like require() or module.exports directly.

Solutions

The most forward-compatible approach is to update your code to use ES module syntax:

javascript
// Replace CommonJS require
const sass = require('gulp-sass')(require('sass'));

// With ES module imports
import sass from 'gulp-sass';
import dartSass from 'sass';

const sassCompiler = sass(dartSass);

Similarly, replace module.exports with export default:

javascript
// Instead of module.exports = myFunction;
export default myFunction;

2. Use createRequire for Mixed Environments

If you need to use both ES modules and CommonJS packages, you can create a require function:

javascript
import { createRequire } from "module";
const require = createRequire(import.meta.url);

// Now you can use require alongside ES imports
import crypto from 'crypto';
const fs = require('fs');
const sass = require('gulp-sass')(require('sass'));

3. Change Module System in package.json

If you prefer to continue using CommonJS, modify your package.json:

json
{
  "type": "commonjs"
}

Or remove the "type" field entirely, as CommonJS is Node.js's default module system.

4. Change File Extension

Rename your files from .js to .cjs to explicitly indicate they should be treated as CommonJS modules:

bash
mv your-file.js your-file.cjs

Troubleshooting Additional Issues

TypeError: Cannot read property 'prod' of undefined

The second error you encountered:

javascript
const PRODUCTION = yargs.argv.prod;

This suggests yargs.argv is undefined. In ES modules, you might need to adjust how you access command line arguments:

javascript
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

const argv = yargs(hideBin(process.argv)).argv;
const PRODUCTION = argv.prod;

Node Version Compatibility

Ensure your Node.js version matches any engine requirements specified in your package.json:

json
{
  "engines": {
    "node": ">=20.0.0"
  }
}

Use nvm (Node Version Manager) to switch between Node versions if needed.

Testing Considerations

For Jest testing with TypeScript, you may need additional configuration:

javascript
// jest.config.js
module.exports = {
  transform: {
    "^.+\\.(j|t)s?$": ["ts-jest", {
      useESM: false,
      diagnostics: {
        ignoreCodes: [1343]
      },
      astTransformers: {
        before: ["node_modules/ts-jest-mock-import-meta"]
      }
    }]
  }
};

Best Practices

  1. Consistency: Stick to one module system (ES modules recommended for new projects)
  2. Migration: Gradually convert CommonJS to ES modules rather than mixing systems
  3. Dependencies: Check that your dependencies support ES modules
  4. File Extensions: Use .mjs for ES modules and .cjs for CommonJS when needed

WARNING

Avoid simply downgrading packages as a solution (like installing older versions of gulp-imagemin). This may introduce security vulnerabilities and compatibility issues.

By understanding the difference between CommonJS and ES modules, and applying the appropriate solution for your use case, you can resolve the "require is not defined" error while maintaining a modern, sustainable codebase.