25

I'm converting a BackboneJS (v1.2.2) project to ES6 w/ BabelJS.

I noted that there's a difference between:

import Backbone from 'backbone'

and

import * as Backbone from 'backbone'

After reading here I understand that the former is importing the default export of Backbone where as the latter allows me to "import the whole module and refer to its named exports via property notation."

I'm struggling to understand the difference between these. Objects are returned in both instances, but the former appears to be decorated with additional properties/methods. At the very least I would presume importing "the whole module" would have more properties/methods... but I'm seeing the opposite.

Sean Anderson
  • 27,963
  • 30
  • 126
  • 237
  • What are examples of the "additional properties/methods"? – JMM Aug 26 '15 at 20:50
  • The first instance appears to be decorated with properties from other plugins. For instance, I load the 'backbone.localStorage' plugin and I see "LocalStorage" defined on Backbone, but, now that I think about it, that makes sense because 'backbone.localStorage' writes itself to the global Backbone object. The latter returns a namespaced instanced which would not be affected by 'backbone.localStorage'"s modifications. – Sean Anderson Aug 26 '15 at 20:55

2 Answers2

35

a module can export a single "default export" and / or one or more named exports.

Importing with the first syntax in your question only imports the default export, and sets a named identifier (Backbone in your sample) to that object.

The second syntax is known as a namespace import, and it imports the whole module under a single "namespace" object.

For example:

export.js

let b = {b: 2};
export default {a: 1}; // <- this is the ONLY default export
export {b};
export let c = {c: 3};

import.js

import SomeName from 'export'; // 'SomeName' is now the {a: 1} instance.
import {b} from 'export'; // 'b' is now the {b: 2} instance.
import * as ns from 'export'; /* 'ns' now has properties 'default', 'b' & 'c',
  representing {a: 1}, {b: 2} & {c: 3} respectively */
Amit
  • 45,440
  • 9
  • 78
  • 110
  • `export {b: 2} as b;` is invalid. – JMM Aug 26 '15 at 21:07
  • @JMM - Correct, fixed. – Amit Aug 26 '15 at 21:13
  • `export { {b: 2} as b }` is also invalid. I think what you're going for is `export var b = {b: 2};` or `var b = {b: 2}; export {b};` – JMM Aug 26 '15 at 21:17
  • @JMM - right again! I was under the impression you COULD export direct values while using the "as Name" syntax, but apparently you can't! modifying again! – Amit Aug 26 '15 at 21:20
  • good one. I don't even know that export let c = {c: 3}; is valid. thanks for that. – Frank Guo May 01 '22 at 14:37
  • for example, this https://github.com/chylvina/winston-sls/blob/master/winston-sls.js this one doesn't have export default, or export let b; or export const a; therefore you have to use import * as SLS from ... – Frank Guo May 01 '22 at 14:40
2

It depends on the interface of the module and how you want to utilize it. In the case of Backbone's npm package there isn't really a default export, so both versions should be roughly equivalent when transpiled by Babel.

At the very least I would presume importing "the whole module" would have more properties/methods

It depends what the default export is and what named exports there are. Here's an example of where that wouldn't be the case:

exporter.js

export default {
  one: "One",
  two: "Two",
  three: "Three",
};

export var a;

importer.js

// Has 3 props ['one', 'two', 'three']
import defaultExport from 'exporter';

// Has 2 props ['default', 'a'].
import * as allExports from 'exporter';
JMM
  • 26,019
  • 3
  • 50
  • 55