70

I read minimized tensorflow.js file for understanding module structure. Tensorflow.js is written in typescript and the above file(link) may be result of transpiling.

Anyway, I understood this module written with IIEF pattern for UMD module format. But, at end of factory function, Object.defineProperty(exports, "__esModule", { value: !0 }) exists. I know its grammatical meaning. But I do not know the purpose of this code. As far as I googled, this code seems to mark the module as ES Module. But it is not clear enough to me. So, some questions follow.

  1. This code seems to be removable. Does it really?
  2. Are there any cases for using this property?
Hyuck Kang
  • 1,671
  • 2
  • 16
  • 24
  • 3
    *"The marker property `__esModule` lets importing modules know that this is a transpiled ES module (which matters especially for default exports)."* http://2ality.com/2017/01/babel-esm-spec-mode.html – Felix Kling Jun 20 '18 at 08:34
  • Yes, I already glanced at that page. So is it just designed marker property which is not used widely? Or is it important property affecting actual module usage? – Hyuck Kang Jun 20 '18 at 08:43
  • 2
    It's needed if you want to be able to import the default export in an other ES6 module. Just look at what Babel compiles `import foo from 'bar';` to: https://babeljs.io/en/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=JYWwDg9gTgLgBAMwhRUIjgcgEYEMqYDcAUAMYQB2AzhADYCmAdLRAOYAUSEAlIUA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&sourceType=module&lineWrap=true&presets=es2015%2Creact%2Cstage-2&prettier=false&targets=&version=6.26.0&envVersion=. Note how it checks the value of `__esmodule`. – Felix Kling Jun 20 '18 at 08:46
  • Thanks, I think you, Mr. Kling, solved my question. How about converting the above comment as anwser? – Hyuck Kang Jun 20 '18 at 14:10
  • 1
    I'll provide a more extensive answer later... – Felix Kling Jun 20 '18 at 20:01

2 Answers2

70

It helps to correctly import a default export in CommonJS/AMD/UMD module format.

A default import (i.e. import d from "foo") for a CommonJS/AMD/UMD module is equivalent to

const d = require("foo").default

But most of the CommonJS/AMD/UMD modules available today do not have a default export, making this import pattern practically unusable to import non-ES modules (i.e. CommonJS/AMD/UMD). For instance

import fs from "fs" 

or

import express from "express" 

are not allowed.

To allow default imports in CommonJS/AMD/UMD (e.g. import fs from "fs"), the typescript compiler adds __esModule flag and checks it in a transpiled code (from ES6 to CommonJS). It imports default exports by using an __importDefault helper function (which checks the __esModule flag).

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
}
exports.__esModule = true;
var bar_1 = __importDefault(require("bar"));
Maxim T
  • 1,077
  • 9
  • 11
  • `react-native-dash` implemented [this pattern](https://github.com/obipawan/react-native-dash/blob/master/dist/index.js) but was still causing a warning message. Changing my import to `import * as Dash from 'react-native-dash'` fixed the warnings from webpack. – citadelgrad Nov 28 '20 at 20:59
6

Maxim had a great answer.

It could be also helpful to poke around with typescript playground with https://www.typescriptlang.org/tsconfig#esModuleInterop flag on/off.

off

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const foo_1 = require("foo");
console.log(foo_1.default);

on

"use strict";
+ var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+ };
Object.defineProperty(exports, "__esModule", { value: true });
- const foo_1 = require("foo");
+ const foo_1 = __importDefault(require("foo"));
console.log(foo_1.default);
Allen
  • 4,431
  • 2
  • 27
  • 39