No articles found
Try different keywords or browse our categories
[SOLVED] ReferenceError: exports is not defined in JavaScript Tutorial
Learn how to resolve the common exports undefined error in JavaScript, ES6 modules, and modern frameworks. Complete guide with solutions for module compatibility issues.
The ‘exports is not defined’ error is a frequent issue developers encounter when working with JavaScript modules, especially when mixing CommonJS and ES6 module systems. This error occurs when code attempts to use the exports object, which is specific to Node.js CommonJS modules, in environments where it’s not available.
This comprehensive guide provides complete solutions to resolve the exports is not defined error across different JavaScript environments with practical examples and troubleshooting techniques.
Understanding the exports Undefined Error
The exports object is a Node.js CommonJS feature that allows modules to expose functionality to other modules. The error occurs when:
- Using CommonJS syntax in ES6 module environments
- Browser environments without proper module bundling
- Webpack or bundler configurations that don’t handle CommonJS
- Mixing module systems incorrectly
Common Error Scenarios:
ReferenceError: exports is not definedUncaught ReferenceError: exports is not definedexports is not defined at Object...TypeError: Cannot set property of undefined
Environment-Specific Solutions
Browser Environment Issues
When using JavaScript modules in browsers, CommonJS exports is not available by default.
❌ Problem Scenario:
// This will fail in browser environments
function myModule() {
// CommonJS syntax
exports.myFunction = function() {
return 'Hello World';
};
}
// This causes: ReferenceError: exports is not defined
✅ Solution: Use ES6 Modules
// ES6 module syntax (modern browsers and bundlers)
export function myFunction() {
return 'Hello World';
}
export const myVariable = 'Some value';
// Or export as default
export default function myDefaultFunction() {
return 'Default export';
}
Node.js Module Compatibility
When working with different module systems in Node.js, compatibility issues can arise.
❌ Problem Scenario:
// Trying to use exports in ES6 module
// file.mjs
const myData = 'Hello';
exports.data = myData; // ReferenceError: exports is not defined
✅ Solution: Use Proper Module Syntax
// ES6 module (file.mjs)
export const data = 'Hello';
export default function myFunction() {
return data;
}
// Or for CommonJS compatibility (file.cjs)
// const myData = 'Hello';
// module.exports = { data: myData };
Solution 1: Module System Conversion
Convert between CommonJS and ES6 module syntax appropriately.
CommonJS to ES6 Conversion:
// Before (CommonJS - file.js)
function greet(name) {
return `Hello, ${name}!`;
}
function farewell(name) {
return `Goodbye, ${name}!`;
}
// CommonJS exports
exports.greet = greet;
exports.farewell = farewell;
module.exports = { greet, farewell }; // Alternative syntax
// After (ES6 - file.mjs)
export function greet(name) {
return `Hello, ${name}!`;
}
export function farewell(name) {
return `Goodbye, ${name}!`;
}
// Or as default export
// export default { greet, farewell };
ES6 to CommonJS Conversion:
// ES6 module (source.mjs)
export const API_URL = 'https://api.example.com';
export function fetchData() {
return fetch(API_URL);
}
export default class ApiService {
// class implementation
}
// CommonJS usage (destination.cjs)
const { API_URL, fetchData, default: ApiService } = require('./source.cjs');
// Or with destructuring
const module = require('./source.cjs');
const { API_URL, fetchData } = module;
Solution 2: Webpack Configuration for Module Compatibility
Configure Webpack to handle both CommonJS and ES6 modules properly.
Webpack 5 Configuration:
// webpack.config.js
module.exports = {
// ... other config
resolve: {
// Handle different module extensions
extensions: ['.js', '.mjs', '.cjs', '.jsx'],
fallback: {
// Fallback for Node.js built-ins in browser
"path": require.resolve("path-browserify"),
"buffer": require.resolve("buffer"),
"stream": require.resolve("stream-browserify"),
}
},
module: {
rules: [
{
test: /\.m?js$/,
resolve: {
fullySpecified: false // Allow importing without file extension
}
}
]
},
// Enable CommonJS compatibility
experiments: {
outputModule: true, // Enable module output
},
output: {
module: true, // Output as module
// ... other output config
}
};
Webpack 4 Configuration:
// webpack.config.js (Webpack 4)
module.exports = {
// ... other config
node: {
// Mock Node.js globals
global: true,
__filename: false,
__dirname: false,
},
// Handle CommonJS modules
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead',
modules: false, // Keep ES6 modules for Webpack to handle
}]
]
}
}
}
]
}
};
Solution 3: Babel Configuration for Module Transpilation
Use Babel to transpile modules for compatibility.
Babel Configuration:
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
targets: {
node: 'current', // or specify version
},
modules: 'auto', // Automatically handle modules based on environment
}],
],
plugins: [
// Transform modules if needed
['@babel/plugin-transform-modules-commonjs', {
loose: true,
allowTopLevelThis: true
}]
]
};
Package.json Configuration:
{
"name": "my-package",
"type": "module", // Enables ES6 modules
"main": "index.cjs", // CommonJS entry point
"module": "index.mjs", // ES6 module entry point
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.cjs"
}
}
}
Solution 4: Universal Module Definition (UMD)
Create modules that work across different environments.
// universal-module.js
(function (global, factory) {
// Check for different module systems
if (typeof exports === 'object' && typeof module !== 'undefined') {
// CommonJS
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
// AMD
define(factory);
} else {
// Browser globals
global.MyModule = factory();
}
})(typeof self !== 'undefined' ? self : this, function () {
// Module implementation
function myFunction() {
return 'Universal function';
}
function anotherFunction() {
return 'Another universal function';
}
// Return public API
return {
myFunction: myFunction,
anotherFunction: anotherFunction
};
});
// Usage
// In CommonJS: const myModule = require('./universal-module');
// In browser: Access via global.MyModule
// In ES6: import not directly supported, but works in bundled environments
Solution 5: Dynamic Module Loading
Use dynamic imports to handle module compatibility.
// dynamic-module-loader.js
async function loadModule(modulePath) {
try {
// Try ES6 module import first
if (modulePath.endsWith('.mjs') ||
(typeof module !== 'undefined' && module.type === 'module')) {
const module = await import(modulePath);
return module;
}
// Fallback to CommonJS
if (typeof require !== 'undefined') {
return require(modulePath);
}
throw new Error('No module system available');
} catch (error) {
console.error('Module loading failed:', error);
return null;
}
}
// Usage
async function useModule() {
const module = await loadModule('./myModule');
if (module) {
// Use the module
const result = module.someFunction();
console.log(result);
}
}
Solution 6: Environment Detection and Conditional Exports
Create modules that adapt to their environment.
// smart-module.js
function myFunction() {
return 'Hello from smart module';
}
function anotherFunction() {
return 'Another function';
}
// Detect environment and export accordingly
if (typeof module !== 'undefined' && module.exports) {
// CommonJS environment
module.exports = {
myFunction: myFunction,
anotherFunction: anotherFunction
};
} else if (typeof exports !== 'undefined') {
// Alternative CommonJS check
exports.myFunction = myFunction;
exports.anotherFunction = anotherFunction;
} else {
// Browser or ES6 environment
// Define as global or use ES6 exports if in module context
if (typeof window !== 'undefined') {
window.SmartModule = {
myFunction: myFunction,
anotherFunction: anotherFunction
};
}
// For ES6 modules, you'd need to use export statements at the top level
}
For ES6 modules specifically:
// es6-module.js
export function myFunction() {
return 'Hello from ES6 module';
}
export function anotherFunction() {
return 'Another ES6 function';
}
// Conditional default export
const api = {
myFunction,
anotherFunction
};
export default api;
Solution 7: Framework-Specific Implementations
React with Module Compatibility:
// utils/moduleHelper.js
// Universal module helper for React applications
export const safeModuleExport = (obj) => {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS environment
module.exports = obj;
} else if (typeof exports !== 'undefined') {
// Alternative CommonJS
exports.default = obj;
}
// For ES6 modules, use export statements at top level
return obj;
};
// react-component.js
import { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
// Component logic that doesn't rely on exports
setData('Component loaded');
}, []);
return <div>{data}</div>;
}
// Safe export for different environments
export default MyComponent;
if (typeof module !== 'undefined' && module.exports) {
module.exports = MyComponent;
}
Next.js Module Configuration:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
// Handle module compatibility
if (!isServer) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
path: require.resolve('path-browserify'),
};
}
// Handle different module types
config.module.rules.push({
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
'@babel/plugin-transform-modules-commonjs'
]
}
}
});
return config;
},
// Enable experimental ES6 module support
experimental: {
esmExternals: 'loose'
}
};
Solution 8: Build Tool Configurations
Vite Configuration:
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
define: {
global: 'globalThis',
},
resolve: {
alias: {
// Handle CommonJS modules
'./commonjs-module': './commonjs-module.cjs',
}
},
optimizeDeps: {
include: [
// Pre-bundle CommonJS dependencies
],
},
build: {
commonjsOptions: {
transformMixedEsModules: true, // Transform mixed ES and CommonJS
},
}
});
Rollup Configuration:
// rollup.config.js
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife', // or 'cjs', 'es', 'umd'
},
plugins: [
resolve(),
commonjs({
// Handle require statements in modules
requireReturnsDefault: 'auto',
}),
],
};
Solution 9: Testing Environment Setup
Configure your testing environment to handle different module systems.
Jest Configuration:
// jest.config.js
module.exports = {
testEnvironment: 'node', // or 'jsdom' for browser tests
transform: {
'^.+\\.jsx?$': 'babel-jest',
'^.+\\.mjs$': 'babel-jest',
},
moduleNameMapper: {
// Handle different module extensions
'^(\\.{1,2}/.*)\\.js$': '$1',
'^(\\.{1,2}/.*)\\.cjs$': '$1',
'^(\\.{1,2}/.*)\\.mjs$': '$1',
},
extensionsToTreatAsEsm: ['.ts', '.tsx'],
globals: {
'ts-jest': {
useESM: true,
},
},
};
// setupTests.js
// Mock module system for tests
global.module = { exports: {} };
global.exports = global.module.exports;
Testing Different Module Types:
// module.test.js
describe('Module compatibility', () => {
test('should handle ES6 imports', async () => {
// Test ES6 module functionality
const { myFunction } = await import('./es6-module');
expect(myFunction()).toBe('Hello from ES6 module');
});
test('should handle CommonJS requires', () => {
// For CommonJS modules
const module = require('./commonjs-module');
expect(module.myFunction()).toBe('Hello from CommonJS module');
});
});
Debugging Strategies
1. Environment Detection:
// Debug module system availability
function debugModuleEnvironment() {
const envInfo = {
hasModule: typeof module !== 'undefined',
hasExports: typeof exports !== 'undefined',
hasRequire: typeof require !== 'undefined',
hasImport: typeof import !== 'undefined',
moduleType: typeof module !== 'undefined' ? module.exports ? 'CommonJS' : 'ES6' : 'Unknown',
isNode: typeof process !== 'undefined' && process.versions && process.versions.node,
isBrowser: typeof window !== 'undefined'
};
console.log('Module Environment Info:', envInfo);
return envInfo;
}
debugModuleEnvironment();
2. Safe Module Access Pattern:
// Universal module access pattern
const safeModuleAccess = (callback) => {
if (typeof module !== 'undefined' && module.exports) {
return callback(module);
} else if (typeof exports !== 'undefined') {
return callback({ exports });
} else {
console.warn('Module system not available in this environment');
return null;
}
};
// Usage
safeModuleAccess((mod) => {
mod.exports.myFunction = () => 'Hello World';
});
Performance Considerations
Efficient Module Loading:
// Optimized module manager
class ModuleManager {
constructor() {
this.isNode = typeof process !== 'undefined' &&
process.versions &&
process.versions.node;
this.hasModule = typeof module !== 'undefined';
this.hasExports = typeof exports !== 'undefined';
}
createExports(obj) {
if (this.hasModule && module.exports) {
// CommonJS path
module.exports = obj;
return module.exports;
} else if (this.hasExports) {
// Alternative CommonJS
Object.assign(exports, obj);
return exports;
} else {
// Browser or ES6 environment
// Return object for ES6 export
return obj;
}
}
async loadModule(path) {
if (this.isNode) {
// Node.js specific loading
return import(path);
} else {
// Browser-specific loading
return await import(path);
}
}
}
// Usage
const moduleManager = new ModuleManager();
const myModule = {
greet: () => 'Hello World',
farewell: () => 'Goodbye World'
};
moduleManager.createExports(myModule);
Security Considerations
Safe Module Operations:
// Secure module handling
function secureModuleExport(obj, allowedKeys = null) {
// Validate input to prevent prototype pollution
if (typeof obj !== 'object' || obj === null) {
throw new Error('Invalid module object for export');
}
// Sanitize object if allowedKeys specified
if (allowedKeys && Array.isArray(allowedKeys)) {
const sanitized = {};
for (const key of allowedKeys) {
if (obj.hasOwnProperty(key)) {
sanitized[key] = obj[key];
}
}
obj = sanitized;
}
// Check for module system availability
if (typeof module !== 'undefined' && module.exports) {
// Validate module object
if (module.exports === obj) {
return module.exports;
}
module.exports = obj;
return module.exports;
} else if (typeof exports !== 'undefined') {
Object.assign(exports, obj);
return exports;
} else {
// Return for ES6 modules or other environments
return obj;
}
}
// Usage
const myModule = {
__proto__: null, // Prevent prototype pollution
safeFunction: () => 'Safe result'
};
const exported = secureModuleExport(myModule, ['safeFunction']);
Common Mistakes to Avoid
1. Mixing Module Systems Incorrectly:
// ❌ Don't do this
import { someFunction } from './module.cjs'; // ES6 import
exports.myFunction = someFunction; // CommonJS export
2. Forgetting File Extensions:
// ❌ Don't forget extensions in ES6 modules
import myModule from './myModule'; // May fail
// ✅ Do this instead
import myModule from './myModule.js'; // Explicit extension
3. Not Configuring Build Tools:
// ❌ Don't assume modules work without proper configuration
// Always configure your bundler for module compatibility
Alternative Solutions
Using Modern JavaScript Features:
// Use dynamic imports for flexibility
async function loadModuleDynamically(modulePath) {
try {
const module = await import(modulePath);
return module;
} catch (error) {
console.error('Dynamic import failed:', error);
// Fallback to CommonJS if available
if (typeof require !== 'undefined') {
return require(modulePath);
}
throw error;
}
}
// Usage
loadModuleDynamically('./myModule.js')
.then(module => {
console.log(module.default || module);
})
.catch(error => {
console.error('Module loading failed:', error);
});
Feature Detection:
// Check for module system availability
const hasCommonJS = typeof module !== 'undefined' && module.exports;
const hasES6Modules = typeof import !== 'undefined';
const hasRequire = typeof require !== 'undefined';
// Use appropriate method based on available features
function createModule(obj) {
if (hasCommonJS) {
module.exports = obj;
} else if (hasES6Modules) {
// For ES6, use export statements at top level
return obj;
} else if (hasRequire) {
// For AMD or other systems
if (typeof define === 'function' && define.amd) {
define(() => obj);
}
}
}
Troubleshooting Checklist
When encountering the exports is not defined error:
- Identify Module System: Determine if using CommonJS, ES6 modules, or mixed
- Check File Extensions: Verify .js, .mjs, or .cjs extensions are correct
- Review Build Configuration: Ensure bundler handles module systems properly
- Validate Import/Export Syntax: Confirm syntax matches module type
- Test in Target Environment: Verify functionality in actual deployment environment
- Check Package.json: Confirm “type” field and export maps are correct
- Review Dependencies: Ensure third-party libraries support your module system
Conclusion
The ‘exports is not defined’ error occurs when attempting to use Node.js CommonJS module syntax in environments that don’t support it. By understanding the differences between module systems and implementing proper configuration, you can ensure your JavaScript applications work seamlessly across different environments.
The key to resolving this error is choosing the appropriate module system for your environment and configuring your build tools properly. Whether you’re working with Node.js, browsers, or modern frameworks, the solutions provided in this guide will help you handle module exports appropriately across different execution environments.
Remember to maintain consistency in your module system choice, configure your build tools appropriately, and test your modules in their target environments to ensure compatibility and proper functionality.
Related Articles
How to Handle & Fix Failed to resolve import Error Tutorial
Learn how to fix 'failed to resolve import' errors in JavaScript. Complete guide with solutions for ES6 modules, Node.js, and bundler configurations.
How to Fix __dirname is not defined Error: Node.js & JS Tutorial
Learn how to resolve the __dirname not defined error in Node.js and browser environments. Complete guide with solutions for ES6 modules and modern JavaScript.
[SOLVED] Cannot use import statement outside a module Error in JavaScript
Learn how to fix the 'Cannot use import statement outside a module' error in JavaScript applications. This comprehensive guide covers ES6 modules, Node.js, and browser compatibility.