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

code typescript

You're using Typescript in a frontend project, and import a module into your code. Something like:
import { Observable } from 'rxjs';

You're using a bundler like Webpack that squeezes those modules into a single minimized javascript file, so you want to keep that line as-is.

However, when Typescript compiles into javascript, it adds the line Object.defineProperty(exports, "__esModule", { value: true }); which causes an error Uncaught ReferenceError: exports is not defined or something similar in your browser's console.

You search for solutions, but everyone is talking about using RequireJS like it's 2014!

You want to get rid of this unwanted Object.defineProperty line but leave the rest of your code untouched.

Solution: Modify these two lines in your tsconfig.json to the following:
"module": "es6",
"lib": ["dom","es6"]

Explanation:

  • commonjs (the current Typescript default) or one of the other suggested options assumes you are writing a Node.js application, or
  • that you will use a module loader (like RequireJS) which loads files into your web application at runtime.
  • es6 is a working standard that will keep your import line intact.
  • But es6 assumes you are importing from a javascript file (e.g. import { this } from './that.js').
  • However, you are using a package manager, you hipster, and that module is not in an external javascript file, but is sitting in a node_modules directory somewhere waiting for your package bundler to roll it on up.
  • Typescript sees the es6 module style, but not the es6 lib, and so believes you are loading an external javascript file. This is why you need to add the es6 to lib:
  • But once you enable lib:, the browser-specific code in your typescript will break without the dom library, so you need to add that, too.

Step-by-step: Still need help? Follow these instructions:

  1. If you do not have a tsconfig.json: In your project directory, type tsc --init
  2. In the tsconfig.json file, find the line starting module: and change its value to es6 like so: "module": "es6"
  3. Further down, find the line starting lib: and add dom and es6 to the array, like so: "lib": ["dom","es6"]. Make sure to uncomment it if necessary.

More info:

  • The tsconfig.json schema contains all of the options for every key-value pair, including:
  • Current module options (one of): "commonjs", "amd", "umd", "system", "es6", "es2015", "esnext", or "none"
  • Current lib options (any combination of): "es5", "es6", "es2015", "es7", "es2016", "es2017", "es2018", "esnext", "dom", "dom.iterable", "webworker", "scripthost", "es2015.core", "es2015.collection", "es2015.generator", "es2015.iterable", "es2015.promise", "es2015.proxy", "es2015.reflect", "es2015.symbol", "es2015.symbol.wellknown", "es2016.array.include", "es2017.object", "es2017.intl", "es2017.sharedmemory", "es2017.string", "es2017.typedarrays", "es2018.intl", "es2018.promise", "es2018.regexp", "esnext.asynciterable", "esnext.array", "esnext.intl", "esnext.symbol"

Comments:

Leave a comment

There was an error. It's me, not you. You could try again later? Or try another method? Email? Smoke signals? Tell me what went wrong!

please enter a substantive message with no link or website address
please enter your name
please enter an email

Comment successfully sent, and it awaits moderation.