54

I have a node.js library lib written in ES6 (compiled with Babel) in which I export the following submodules:

"use strict";

import * as _config from './config';
import * as _db from './db';
import * as _storage from './storage';

export var config = _config;
export var db = _db;
export var storage = _storage;

If from my main project I include the library like this

import * as lib from 'lib';
console.log(lib);

I can see the proper output and it work as expected { config: ... }. However, if I try to include the library like this:

import lib from 'lib';
console.log(lib);

it will be undefined.

Can someone explain what is happening here? Aren't the two import methods supposed to be equivalent? If not, what difference am I missing?

left4bread
  • 1,514
  • 2
  • 15
  • 25

3 Answers3

79
import * as lib from 'lib';

is asking for an object with all of the named exports of 'lib'.


export var config = _config;
export var db = _db;
export var storage = _storage;

are named exports, which is why you end up with an object like you did.


import lib from 'lib';

is asking for the default export of lib.


e.g.

export default 4;

would make lib === 4. It does not fetch the named exports. To get an object from the default export, you'd have to explicitly do

export default {
  config: _config,
  db: _db,
  storage: _storage
};
Boaz
  • 19,892
  • 8
  • 62
  • 70
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
19

Just adding to Logan's solution because understanding import with brackets, * and without solved a problem for me.

import * as lib from 'lib';

is the equivalent of:

import {config, db, storage} as lib from 'lib';

Where the * is similar to a wildcard that imports all of the export var from lib.

export var config;
export var db;
export var storage;

Alternatively, using:

import lib from 'lib';

Allows you to only access the default export:

// lib.js
export default storage;

Using {} also only imports specific components from the module, which reduces the footprint with bundlers like Webpack.

While:

import storage, { config, db } from './lib'

would import all modules including export default storage;

See Dan Abramov's answer: When should I use curly braces for ES6 import?

tgrrr
  • 706
  • 6
  • 16
  • 3
    Only that there is no `import {…} as … from …` syntax – Bergi Nov 03 '17 at 04:24
  • Edited. You're right, there is no spread operator for {...}, I should have used etc instead. – tgrrr Nov 05 '17 at 23:47
  • (Of course there's no spread/rest syntax, as this is not object literal/destructuring). Still there is no `{…} as …` syntax in imports, so "*is the same as*" is meaningless. (I don't think you meant "*produces the same syntax error as*") – Bergi Nov 06 '17 at 00:05
  • That's correct. Updated the answer for clarity. I used 'is the same as' because smaller words are more accessible. I've changed it to 'equivalent of' to be more specific. – tgrrr Nov 06 '17 at 00:48
  • 1
    But can you explain what `import {config, db, storage} as lib from 'lib';` does? It's not described anywhere – Bergi Nov 06 '17 at 02:06
4

import X from Y; is a syntax sugar.

import lib from 'lib';

is equal to

import { default as lib } from 'lib';

foxiris
  • 3,125
  • 32
  • 32