search
Javascript star Featured

[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.

person By Gautam Sharma
calendar_today January 2, 2026
schedule 13 min read
JavaScript ES6 Modules Node.js Module System Error Handling Bundlers

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 defined
  • Uncaught ReferenceError: exports is not defined
  • exports 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:

  1. Identify Module System: Determine if using CommonJS, ES6 modules, or mixed
  2. Check File Extensions: Verify .js, .mjs, or .cjs extensions are correct
  3. Review Build Configuration: Ensure bundler handles module systems properly
  4. Validate Import/Export Syntax: Confirm syntax matches module type
  5. Test in Target Environment: Verify functionality in actual deployment environment
  6. Check Package.json: Confirm “type” field and export maps are correct
  7. 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.

Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

Javascript

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.

January 2, 2026
Javascript

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.

January 2, 2026
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.

January 2, 2026