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:
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
1. Convert to ES Module Syntax (Recommended)
The most forward-compatible approach is to update your code to use ES module syntax:
// 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
:
// 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:
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
:
{
"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:
mv your-file.js your-file.cjs
Troubleshooting Additional Issues
TypeError: Cannot read property 'prod' of undefined
The second error you encountered:
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:
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
:
{
"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:
// 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
- Consistency: Stick to one module system (ES modules recommended for new projects)
- Migration: Gradually convert CommonJS to ES modules rather than mixing systems
- Dependencies: Check that your dependencies support ES modules
- 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.