Skip to content

default export handling in CJS and IIFE bundles #587

Description

@fregante

I'm sure this has been talked about before but I can't find it. :-/

The way default exports behave when there are additional exports is counterintuitive.

export default function () {}

Becomes in IIFE and CJS respectively:

var doStuff = (function () {
    'use strict';
    function index () {}
    return index;
}());
'use strict';
function index () {}
module.exports = index;

So far so good, even though I wish the code was shorter.

But then when adding a named export:

export default function () {}
export function other() {}

Becomes:

'use strict';

function index () {}
function other() {}

exports['default'] = index; // Boom, broken
exports.other = other;
(function (exports) {
    'use strict';

    function index () {}
    function other() {}

    exports['default'] = index; // Boom, broken
    exports.other = other;

}((this.doStuff = this.doStuff || {}))); // Also, why this check only here? In some cases the behavior changes completely.

The core problem is that the if with a single export I can just use

window.doStuff()

adding another one it becomes an unintuitive and unideal

window.doStuff['default']()

Same goes for the CJS export, which without this issue sorted out, a browserify user would have to use

var doStuff = require('do-stuff')['default'];

Or even

import doStuff from 'do-stuff';
doStuff['default']();

rollup is an amazing tool to bundle libraries, but using proper ESM exports with it is not advised and defeats the purpose of the ES6-style rollup output, because I have to do this instead:

function doStuff() {}
Object.defineProperty(doStuff, "other", {
    value:  function () {}
});
export default doStuff;

I understand the reasoning behind it, because this isn't possible for example:

var value = 5;
Object.defineProperty(value, "other", {
    value:  function () {}
});
export default value;

But it still remains a big issue for, what I believe is, the most common use case (i.e. exporting functions and objects as default). For others perhaps rollup could revert to the current behavior and output a warning.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions