Typescript ReferenceError: exports is not defined

TypescriptModule

Typescript Problem Overview


Trying to implement a module following the official handbook, I get this error message:

> Uncaught ReferenceError: exports is not defined > > at app.js:2

But nowhere in my code do I ever use the name exports.

How can I fix this?


Files

app.ts
let a = 2;
let b:number = 3;

import Person = require ('./mods/module-1');
module-1.t
 export class Person {
  constructor(){
    console.log('Person Class');
  }
}
export default Person;
tsconfig.json
{
   "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true,
        "outDir": "scripts/"
    },
    "exclude": [
        "node_modules"
    ]
}

Typescript Solutions


Solution 1 - Typescript

Few other Solutions for this issue

  • Add the following line before other references to Javascript. This is a nice little hack.

   <script>var exports = {};</script>

Solution 2 - Typescript

EDIT:

This answer might not work depending if you're not targeting es5 anymore, I'll try to make the answer more complete.

Original Answer

If CommonJS isn't installed (which defines exports), you have to remove this line from your tsconfig.json:

 "module": "commonjs",

As per the comments, this alone may not work with later versions of tsc. If that is the case, you can install a module loader like CommonJS, SystemJS or RequireJS and then specify that.

Note:

Look at your main.js file that tsc generated. You will find this at the very top:

Object.defineProperty(exports, "__esModule", { value: true });

It is the root of the error message, and after removing "module": "commonjs",, it will vanish.

Solution 3 - Typescript

A solution:

Remove "type": "module" from package.json.

Solution 4 - Typescript

This is fixed by setting the module compiler option to es6:

{
  "compilerOptions": {     
    "module": "es6",
    "target": "es5",    
  }
}

Solution 5 - Typescript

npm install @babel/plugin-transform-modules-commonjs

and add to to .babelrc plugins resolved my question.

Solution 6 - Typescript

my solution is a sum up of everything above with little tricks I added, basically I added this to my html code

<script>var exports = {"__esModule": true};</script>
<script src="js/file.js"></script>

this even allows you to use import instead of require if you're using electron or something, and it works fine with typescript 3.5.1, target: es3 -> esnext.

Solution 7 - Typescript

I ran into this issue a few weeks ago and used the exports hack above in the short term but finally figured out another way around this that's working great for me.

So unlike some of the other responses above, I actually wanted the code I'm compiling to be a module. By setting "target": "es6", "module": "esnext" and then linking to my compiled JS file with type="module" instead of type="text/javascript", my compiled code no longer has the Object.defineProperty(exports, "__esModule", { value: true }); line and it's still a module 

My tsconfig:

{
  "compilerOptions": {
    "target": "es6",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "esnext",
    "moduleResolution": "node",
    "lib": ["es2016", "esnext", "dom"],
    "outDir": "build",
    "strict": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
  },
  "include": ["src/index.ts"],
  "exclude": ["build"]
}

My link to my compiled code in HTML head tags:

<script src="../build/index.js" type="module" defer></script>

As a bonus, now I can also import anything that I export in that index.js file in a separate type="module" script down below the main HTML body code:

 <script type="module">
   import { coolEncodingFunction, coolDecodingFunction } from "../build/index.js";
   /* Do stuff with coolEncodingFunction and coolDecodingFunction */
   /* ... */
</script>

Solution 8 - Typescript

I had the same problem and solved it adding "es5" library to tsconfig.json like this:

{
    "compilerOptions": {
        "target": "es5", //defines what sort of code ts generates, es5 because it's what most browsers currently UNDERSTANDS.
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true, //for angular to be able to use metadata we specify in our components.
        "experimentalDecorators": true, //angular needs decorators like @Component, @Injectable, etc.
        "removeComments": false,
        "noImplicitAny": false,
        "lib": [
            "es2016",
            "dom",
            "es5"
        ]
    }
}

Solution 9 - Typescript

For people still having this issue, if your compiler target is set to ES6 you need to tell babel to skip module transformation. To do so add this to your .babelrc file

{
  "presets": [ ["env", {"modules": false} ]]
}

Solution 10 - Typescript

I had this same error too. In my case it was because we had an old-fashioned import statement in our TypeScript AngularJS project like this:

import { IAttributes, IScope } from "angular";

which was compiled to JavaScript like this:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

This was needed back in the old days because we then used IAttributes in the code and TypeScript wouldn't have known what to do with it otherwise. But after removing the import statement, and converting IAttributes to ng.IAttributes those two JavaScript lines disappeared - and so did the error message.

Solution 11 - Typescript

for me, removing "esModuleInterop": true from tsconfig.json did the trick.

Solution 12 - Typescript

I had similar issue as the original poster of the question:

I better tell you what mistakes I made and how I corrected it, that might help someone.

I had javascript nodejs project and converted it to typescript.

Previously in package.json I had "type":"module" when I was running in JavaScript.

When I converted it to TypeScript project and started converting files in .ts files and started running using following command:

npx tsc test.ts && node test.ts

I would get the above error.

I got rid of the error by simply removing the "type":"module" from package.json

My tsconfig.json would like below:

{
    "compilerOptions": {
        "target": "esnext",
        "lib": ["es6", "es5", "es7", "dom"],
        "allowJs": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": "es6",
        "outDir": "./build",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "skipLibCheck": true
    },
    "exclude": ["node_modules", "build"]

I am using node 14 and TypeScript 4.2.4

Solution 13 - Typescript

Simply add libraryTarget: 'umd', like so

const webpackConfig = {
  output: {
    libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
  }
};

module.exports = webpackConfig; // Export all custom Webpack configs.

Solution 14 - Typescript

in package.json add in "type": "module" in terminal type in

npx tsc --init

it will create a tsconfig.json change "target": "es5" to "target": "es6"

comment out //"module": "commonjs", uncomment "moduleResolution": "node",

you should be good to go in package.json create a build script

"build": "tsc -p tsconfig.json"

then when you want to build you just compile npm run build

then execute and should be good

Solution 15 - Typescript

For some ASP.NET projects import and export may not be used at all in your Typescripts.

The question's error showed up when I attempted to do so and I only discovered later that I just needed to add the generated JS script to the View like so:

<script src="~/scripts/js/[GENERATED_FILE].Index.js" asp-append-version="true"></script>

Solution 16 - Typescript

Note: This might not be applicable for OP's answer, but I was getting this error, and this how I solved it.

So the problem that I was facing was that I was getting this error when I retrieved a 'js' library from a particular CDN.

The only wrong thing that I was doing was importing from the CDN's cjs directory like so: https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/cjs/popper.min.js

Notice the dist/cjs part? That's where the problem was.

I went back to the CDN (jsdelivr) in my case and navigated to find the umd folder. And I could find another set of popper.min.js which was the correct file to import: https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js.

Solution 17 - Typescript

To solve this issue, put these two lines in your index.html page.

<script>var exports = {"__esModule": true};</script>
<script type="text/javascript" src="/main.js">

Make sure to check your main.js file path.

Solution 18 - Typescript

Try what @iFreilicht suggested above. If that didn't work after you've installed webpack and all, you may have just copied a webpack configuration from somewhere online and configured there that you want the output to support CommonJS by mistake. Make sure this isn't the case in webpack.config.js:

module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: { 
    index: "./src/js/index.ts"
  },
  ...
  ...
  output: {
    libraryTarget: 'commonjs',         <==== DELETE THIS LINE
    path: path.join(__dirname, 'build'),
    filename: "[name].bundle.js"
  }
};

Solution 19 - Typescript

Had the same issue and fixed it by changing the JS packages loading order.

Check the order in which the packages you need are being called and load them in an appropriate order.

In my specific case (not using module bundler) I needed to load Redux, then Redux Thunk, then React Redux. Loading React Redux before Redux Thunk would give me exports is not defined.

Solution 20 - Typescript

I had the same issue, but my setup required a different solution.

I'm using the create-react-app-rewired package with a config-overrides.js file. Previously, I was using the addBabelPresets import (in the override() method) from customize-cra and decided to abstract those presets to a separate file. Coincidentally, this solved my problem.

I added useBabelRc() to the override() method in config-overrides.js and created a babel.config.js file with the following:

module.exports = {
    presets: [
        '@babel/preset-react',
        '@babel/preset-env'
    ],
}

Solution 21 - Typescript

I stuck with such error in a SSR client part because it used a lib which was built with tsconfig.json compilerOptions as target: ES5 what brought using CommonJS for module resolution tsc CLI Options Compiler Options: target === "ES3" or "ES5" ? "CommonJS" : "ES6". While it used the target ESNext.

Solution 22 - Typescript

As ES5/ES2009 doesn't support modules (import/export/require) on the client / browser you have to use libraries, which bundle the modules into a single file, which can be included via <script> tag, such as

See also this answer.

Solution 23 - Typescript

I think the problem may be the mismatched configuration.

  1. Working solution 1 below give you a correct configuration for ES Module.
  2. Working solution 2 below give you a correct configuration for CommonJS.
  3. Mixed solution 1+2 give you an Error.

I just post partial content here, for clarity. Github project https://github.com/jmmvkr/ts-express/ have a complete set of files demonstrate the working solution 1 and solution 2.

Working solution 1, ES Module

/* Configuration for ES Module */

// tsconfig.json
{
    "compilerOptions": {
        "module": "es6", // or "esnext"
    }
}
// package.json
{
    "type": "module", // type is module
}

Working solution 2, CommonJS

/* Configuration for CommonJS */

// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
    }
}
// package.json
{
    "type": "", // type is NOT module
}

Mixed, do NOT work

/* Mixed, got ReferenceError: exports is not defined in ES module scope */

// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
    }
}
// package.json
{
    "type": "module", // type is module
}

Solution 24 - Typescript

  {
    "compileOnSave": false,
    "compilerOptions": {
      "baseUrl": "./",
      "outDir": "./dist",
      "sourceMap": true,
      "declaration": false,
      "module": "esnext",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": ["node_modules/@types"],
      "lib": ["es2018", "dom"]
    }
  }

Solution 25 - Typescript

If you are just using interfaces for types, leave out the export keyword and ts can pick up on the types without needing to import. They key is you cannot use import/export anywhere.

export interface Person {
   name: string;
   age: number;
}

into

interface Person {
   name: string;
   age: number;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorge C.View Question on Stackoverflow
Solution 1 - TypescriptVenkatesh MuniyandiView Answer on Stackoverflow
Solution 2 - TypescriptiFreilichtView Answer on Stackoverflow
Solution 3 - TypescriptMasih JahangiriView Answer on Stackoverflow
Solution 4 - TypescriptCode WhispererView Answer on Stackoverflow
Solution 5 - TypescriptYi ZhangView Answer on Stackoverflow
Solution 6 - TypescriptHocine Abdellatif HouariView Answer on Stackoverflow
Solution 7 - Typescriptmhanley00View Answer on Stackoverflow
Solution 8 - TypescriptrubensaView Answer on Stackoverflow
Solution 9 - TypescriptCezar AugustoView Answer on Stackoverflow
Solution 10 - TypescriptMatXView Answer on Stackoverflow
Solution 11 - Typescriptuser3033599View Answer on Stackoverflow
Solution 12 - TypescriptKrunal ShahView Answer on Stackoverflow
Solution 13 - TypescriptDaniel DanieleckiView Answer on Stackoverflow
Solution 14 - TypescriptSpencer DavisView Answer on Stackoverflow
Solution 15 - TypescriptCPHPythonView Answer on Stackoverflow
Solution 16 - TypescriptArpan SrivastavaView Answer on Stackoverflow
Solution 17 - TypescriptRupesh ShitoleView Answer on Stackoverflow
Solution 18 - TypescriptdulibaView Answer on Stackoverflow
Solution 19 - TypescriptPatView Answer on Stackoverflow
Solution 20 - TypescriptDoug WilhelmView Answer on Stackoverflow
Solution 21 - TypescriptAlex PoView Answer on Stackoverflow
Solution 22 - TypescriptUser ReboView Answer on Stackoverflow
Solution 23 - TypescriptJivikView Answer on Stackoverflow
Solution 24 - TypescriptCarlos AlvesView Answer on Stackoverflow
Solution 25 - TypescriptMattView Answer on Stackoverflow