Wildcard or asterisk (*) vs named or selective import es6 javascript

JavascriptImportEcmascript 6WildcardEs6 Modules

Javascript Problem Overview


Just wondering which one is the best way to use import:

import * as Foo from './foo';

VS:

import { bar, bar2, bar3 } from './foo';

In terms of efficiency, say for example, I'm using webpack for bundling all the JavaScript files. Will the first one actually importing everything even though I'm not using them in the main code?

Some references that I can find are:

In Airbnb style guide, they are recommending no wildcard so there will always be default import object, and this.

Javascript Solutions


Solution 1 - Javascript

If you use webpack with the dead code elimination provided by the new uglify, or rollupjs with tree-shaking, then the unused imports will be stripped.

I partially agree with the airbnb styleguide to not to use wildcard imports, although javascripts wildcard imports do not suffer from the same diseases as for example pythons or javas wildcard imports, namely it does not pollute the scope with variable names defined in other modules (you can only access them by moduleB.foo, not foo when using import * as moduleB from ...).

About the article on testing: I kindof understand the concerns, but I see nothing that cannot be solved there. You can mock the imports themselves with some custom module loader (a custom amd module loader is literally 15 lines of code), so you dont have to mess with the local scope of the tested module.

Solution 2 - Javascript

Concerning this part of the question :

> Will the first one actually importing everything even though I'm not using them in the main code?

Here's how it gets compiled with Babel 6.26:

Named

import { bar, bar2, bar3 } from './foo';

... becomes ...

'use strict';

var _foo = require('./foo');

Wildcard

import * as Foo from './foo';

... becomes ...

'use strict';

var _foo = require('./foo');

var Foo = _interopRequireWildcard(_foo);

function _interopRequireWildcard(obj) { 
    if (obj && obj.__esModule) { 
        return obj;
    } else {
        var newObj = {}; 
        if (obj != null) { 
            for (var key in obj) { 
                if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
            }
        }
        newObj.default = obj; 
        return newObj;
    }
}

In both cases the whole file is imported through require.

With wildcards imports, an _interopRequireWildcard function is defined and used to assign all exports to the namespace variable.

It's worth noting that compiled code will only contain a single _interopRequireWildcard definition, and one call to require and _interopRequireWildcard for each import.

Ultimately, the use of wildcard imports will involve a bit more processing at run-time and cause a slight increase in size for the compiled js.

Solution 3 - Javascript

Since, with a modern WebPack setup, the two will generate the same compiled/transpiled JS, the real value in named imports is how much more expressive it is. By naming your imports you are telling any one that opens the file which functions from a module you are going to use. An example of where this can be helpful is when writing tests, if mocking is necessary, you have an explicit list of imports to mock.

Solution 4 - Javascript

I agree with @Tamas.
If you require the full access to all exports in the target file, then you can use the import * as Foo from './foo'; or import foo from './foo':

but if you need to use specific function or const then better avoid "import *" and be explicit what you needs to do.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionandiwinView Question on Stackoverflow
Solution 1 - JavascriptTamas HegedusView Answer on Stackoverflow
Solution 2 - JavascriptidmadjView Answer on Stackoverflow
Solution 3 - JavascriptKelly AndersonView Answer on Stackoverflow
Solution 4 - JavascriptMoeen BasraView Answer on Stackoverflow