Quantifying Default Exports

Brian Di Palma offler at gmail.com
Mon Jul 21 09:06:03 PDT 2014


On Mon, Jul 21, 2014 at 4:16 PM, Calvin Metcalf
<calvin.metcalf at gmail.com> wrote:
> I have a CommonJS module which exports a single function
> ```js
> //cj.js
> module.exports = function (){}
> ```
>
> If I was to transform it into an ES6 module the best way to do so currently
> it so use a default export
>
> ```js
> //cj2es6.js
> export default function () {}
> ```
>
> now say I want to import those from another commonjs module, importing the
> first one is easy, but when importing the second one slightly less so, how
> should the loader treat that default export, a easy solution for this case
> is to simply have default exports act the same as a module.exports
>
> But then what would you do about es6 modules that use default and named
> exports like the example at http://jsmodules.io/ which can be sumerized as
>
> ```js
>
> export default function mainThing(){}
> export function helper (){};
>
> , if we return a default export if it exists then there is no way to access
> the named exports.

As mentioned in the GitHub issue I don't see why you couldn't compile to

`
module.export = function mainThing(){};

module.export.helper = function(){};
`

Allowing access to the default and named.

>
> So in that case it would make more sense to treat default as just another
> export name.  But if we do that then that means that if we go back to our
> second example
>
> ```js
> //cj2es6.js
> export default function () {}
> ```
>
> if that was to be treated that way then importing it from another commonjs
> module would be make it be equivalent to
>
> ```js
> //cj2es62cj.js
> exports.default = function (){}
> ```
>
> In other words treating default as a regular name prevents you from
> losslessly converting commonjs in a backwards compatible way.
>
> Making named and default exports be mutually exclusive would mean that you
> could treat default export like module.exports.
>
>
>
> On Mon, Jul 21, 2014 at 10:45 AM, Brian Di Palma <offler at gmail.com> wrote:
>>
>> On Mon, Jul 21, 2014 at 3:31 PM, Calvin Metcalf
>> <calvin.metcalf at gmail.com> wrote:
>> > that won't help if module.exports is a function
>>
>> That's exactly what `minimist` is, works just fine.
>>
>> https://github.com/substack/minimist/blob/master/index.js
>>
>> >
>> > Overall the import/exports semantics of es6 and cjs modules would be
>> > compatible if mixing named and default exports was prohibited, but the
>> > ability to have both is hard to represent in cjs modules.
>>
>> Don't understand this, do you have some code examples? I can't see why
>> that would be the case.
>>
>> >
>> >
>> > On Mon, Jul 21, 2014 at 10:24 AM, Brian Di Palma <offler at gmail.com>
>> > wrote:
>> >>
>> >> Which shows the how the backward compatability argument for default
>> >> export/imports doesn't stand up.
>> >>
>> >> If you want to import `module.exports` then use the the `module` form
>> >> if you want named imports use the named form.
>> >> Default import/exports are generating nothing more then complexity,
>> >> confusion and not serving their intended goals.
>> >>
>> >> On Mon, Jul 21, 2014 at 3:18 PM, Calvin Metcalf
>> >> <calvin.metcalf at gmail.com> wrote:
>> >> > similar discussion at systemjs
>> >> > https://github.com/systemjs/systemjs/issues/131 which boils down to
>> >> > if a
>> >> > CJS
>> >> > module imports an ES6 module that has a key named default, what
>> >> > should
>> >> > the
>> >> > default behavior be.
>> >> >
>> >> >
>> >> > On Mon, Jul 21, 2014 at 10:05 AM, Brian Di Palma <offler at gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> It's using traceur and building the modules to CJS, the project uses
>> >> >> other non transpiled CJS modules.
>> >> >>
>> >> >> The only thing traceur could do here is compile the imports into a
>> >> >> check for the named export `default` and use that if it exists.
>> >> >> If it doesn't then simply return the CJS module object.
>> >> >>
>> >> >> Here is the output from traceur
>> >> >>
>> >> >>
>> >> >>
>> >> >> https://github.com/briandipalma/global-compiler/blob/master/out/index.js
>> >> >>
>> >> >> The relevant line would be
>> >> >>
>> >> >> `var minimist = require('minimist');`
>> >> >>
>> >> >> For default import from a CJS module you'd need to output
>> >> >>
>> >> >> `
>> >> >> var minimist = require('minimist');
>> >> >> if (minimist.default) {
>> >> >>  minimist = minimist.default;
>> >> >> }
>> >> >> `
>> >> >>
>> >> >> Is that what you think traceur should do?
>> >> >>
>> >> >> On Mon, Jul 21, 2014 at 2:34 PM, Juan Ignacio Dopazo
>> >> >> <jdopazo at yahoo-inc.com> wrote:
>> >> >> >
>> >> >> >> On Saturday, July 19, 2014 1:53 PM, Brian Di Palma
>> >> >> >> <offler at gmail.com>
>> >> >> >> wrote:
>> >> >> >
>> >> >> >> When an npm package exports a named identifier it's trivial to
>> >> >> >> use
>> >> >> >> it
>> >> >> > in an ES6 module.
>> >> >> >
>> >> >> > import {
>> >> >> >     parse,
>> >> >> >     print
>> >> >> > } from 'recast';
>> >> >> >
>> >> >> >> When on the other hand it sets its export on `module.exports`
>> >> >> >> default
>> >> >> > exports provide no help at all.
>> >> >> >
>> >> >> > This sounds like an issue in your transpiler. Ideally CJS modules
>> >> >> > inside
>> >> >> > projects written using ES6 modules should be treated as modules
>> >> >> > that
>> >> >> > default
>> >> >> > export an object. CJS modules don't have the same static semantics
>> >> >> > as
>> >> >> > their
>> >> >> > ES6 counterpart, so they should be treated as mutable objects. An
>> >> >> > ES6
>> >> >> > Loader
>> >> >> > would do the same when loading CJS modules.
>> >> >> >
>> >> >> > Juan
>> >> >> _______________________________________________
>> >> >> es-discuss mailing list
>> >> >> es-discuss at mozilla.org
>> >> >> https://mail.mozilla.org/listinfo/es-discuss
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > --
>> >> > -Calvin W. Metcalf
>> >
>> >
>> >
>> >
>> > --
>> > -Calvin W. Metcalf
>
>
>
>
> --
> -Calvin W. Metcalf


More information about the es-discuss mailing list