question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Write a FAQ entry for `export =` vs `export default` / `import ` variants

See original GitHub issue

People don’t understand the difference between these things:

export default class Foo {}
/* or */
class Foo {}
export = Foo;
/* or */
export class Foo { }

People also don’t understand the difference between these things:

import x = require('y');
import x from 'y';
import { x } from 'y'
import * as x from 'y';

We need to write a comprehensive answer that explains which import statements correctly acquire which exports, and also describe auto-lifting behavior present in some loaders.

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:253
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

76reactions
brianjenkins94commented, Sep 15, 2018

export default … (Default Export)

// calculator.ts                                // compiled.js
// =============                                // ===========
export default class Calculator {               // var Calculator = /** @class */ (function () {
    public add(num1, num2) {                    //     function Calculator() {}
        return num1 + num2;                     //     Calculator.prototype.add = function (num1, num2) {
    }                                           //         return num1 + num2;
}                                               //     };
                                                //     return Calculator;
                                                // }());
                                                // exports["default"] = Calculator;

import … from “module”;

// importer.ts                                  // compiled.js
// ===========                                  // ===========
import Calculator from "./calculator";          // exports.__esModule = true;
                                                // var calculator = require("./calculator");
let calc = new Calculator();                    // var calc = new calculator["default"]();
                                                // console.log(calc.add(2, 2));
console.log(calc.add(2, 2));                    //
Notes:
  • A default export can be imported with any name.
  • Functionally equivalent to import * as Calculator from "./calculator"; and then instantiating it using new Calculator.default().

export = …

// calculator.ts                                // compiled.js
// =============                                // ===========
export = class Calculator {                     // module.exports = /** @class */ (function () {
    public add(num1, num2) {                    //     function Calculator() {}
        return num1 + num2;                     //     Calculator.prototype.add = function (num1, num2) {
    }                                           //         return num1 + num2;
}                                               //     };
                                                //     return Calculator;
                                                // }());

import … = require(“module”);

// importer.ts                                  // compiled.js
// ===========                                  // ===========
import Calculator = require("./calculator");    // exports.__esModule = true;
                                                // var Calculator = require("./calculator");
let calc = new Calculator();                    // var calc = new Calculator();
                                                // console.log(calc.add(2, 2));
console.log(calc.add(2, 2));                    //
Notes:
  • This syntax is only used when importing a CommonJS module.

export … (Named Export)

// calculator.ts                                // compiled.js
// =============                                // ===========
export class Calculator {                       // exports.__esModule = true;
    public add(num1, num2) {                    // var Calculator = /** @class */ (function () {
        return num1 + num2;                     //     function Calculator() {}
    }                                           //     Calculator.prototype.add = function (num1, num2) {
}                                               //         return num1 + num2;
                                                //     };
                                                //     return Calculator;
                                                // }());
                                                // exports.Calculator = Calculator;

import { … } from “module”;

// importer.ts                                  // compiled.js
// ===========                                  // ===========
import { Calculator } from "./calculator";      // exports.__esModule = true;
                                                // var calculator = require("./calculator");
let calc = new Calculator();                    // var calc = new calculator.Calculator();
                                                // console.log(calc.add(2, 2));
console.log(calc.add(2, 2));                    //
Notes:
  • Named exports are useful to export several values.
  • During the import, you must use the same name of the corresponding object.
21reactions
DanielRosenwassercommented, Apr 14, 2018

TL;DR: export = or import = require implies the module was written as CommonJS, export default implies it’s been authored as an ECMAScript module.

export = and import x = require('./x') corresponds to CommonJS/AMD/etc.'s notion of module.exports:

// ./a.js
module.exports = { a: 10, b: 20 };

// ./b.js
let a = require('./a');

A lot of the time, people will have exactly one thing that they’re exporting, like a function:

// ./a.js
module.exports = function foo() { /*...*/ }

// ./b.js
var a = require('./a');
a();

export default is a construct in ES2015 modules that is supposed to give an easy way to say “hey, here’s the main thing you import from this module”. ES2015 gives it a special syntax.

// a.js
export default function foo() {
    // ...
}

// b.js
import a from './a.js';
a();

But it’s just special syntax; really, default is like any member on an ES2015 module record. b.js could have been written like the following:

import * as a from './a.js';
a.default();

import { default as aFujnc } from './a.js'
aFunc();
Read more comments on GitHub >

github_iconTop Results From Across the Web

Named Export vs Default Export in ES6 | by Alankar Anand
Named exports are useful to export several values. During the import, one will be able to use the same name to refer to...
Read more >
16. Modules - Exploring JS
There are two kinds of exports: named exports (several per module) and default exports (one per module). As explained later, it is possible...
Read more >
Export and Import - The Modern JavaScript Tutorial
Export and import directives have several syntax variants. In the previous article we saw a simple use, now let's explore more examples.
Read more >
export - JavaScript - MDN Web Docs
Every module can have two different types of export, named export and default export. You can have multiple named exports per module but...
Read more >
NgModule FAQ - Angular
An NgModule can export a combination of its own declarations, selected imported classes, and imported NgModules. Don't bother re-exporting pure service modules.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found