Quantifying Default Exports

Brian Di Palma offler at gmail.com
Mon Jul 21 16:04:13 PDT 2014


What utility is that exactly? They are easier to import in terms of typing?

I would hope that with ES6 modules all a programmer would have to
write is the name of the import and the IDE would auto insert the
import statement.
The sort of IDE support you would see for Java or C#, of course that
will only work with named exports.

If everything is default then the IDE can't help that much when it
comes to auto complete and inserts.

I think that issue has already been addressed by people pointing out
that modules were written in the default style due to named exports
being ugly in CJS.

On Mon, Jul 21, 2014 at 11:30 PM, Calvin Metcalf
<calvin.metcalf at gmail.com> wrote:
> Wasn't the original issue single exports and their demonstrated utility in
> node and AMD?
>
> On Jul 21, 2014 5:49 PM, "John Barton" <johnjbarton at google.com> wrote:
>>
>> There are two issues here:
>>   1) Is 'default' essential?
>>   2) Should the spec. explicitly define commonjs loading?
>>
>> Brian is claiming 1) no and 2) no.  More important for me: does 2) require
>> 1). Evidently not.
>>
>> jjb
>>
>>
>> On Mon, Jul 21, 2014 at 1:34 PM, Brian Di Palma <offler at gmail.com> wrote:
>>>
>>> It doesn't seem an issue that requires the ES6 module spec to have
>>> something like default imports though.
>>>
>>> The compiler could output
>>>
>>> `
>>> newModule({
>>>   default: require('minimist')
>>> })
>>> `
>>>
>>> and importers could do
>>>
>>> `import {default as minimist} from 'minimist';`
>>>
>>> Or you could have
>>>
>>> `
>>> newModule({
>>>   minimist: require('minimist');
>>> })
>>> `
>>>
>>> and
>>>
>>> `import {minimist} from 'minimist';`
>>>
>>> depending on how the compiler is configured/written.
>>>
>>> This is implementation detail of compilers and loaders of legacy
>>> systems as opposed to spec concerns.
>>>
>>> On Mon, Jul 21, 2014 at 6:50 PM, Guy Bedford <guybedford at gmail.com>
>>> wrote:
>>> > Yes this is a bug that can be fixed at the compiler level. As you say
>>> > we can
>>> > generate a wrapper when loading a non-ES6 module in ES6:
>>> >
>>> > newModule({
>>> >   default: require('minimist')
>>> > })
>>> >
>>> > We then conditionally add this wrapper based on detecting if the import
>>> > is
>>> > an ES6 module. This is the same method we have for AMD compilations at
>>> > the
>>> > moment, which seems to have been working well.
>>> >
>>> >
>>> > On 21 July 2014 10:17, John Barton <johnjbarton at google.com> wrote:
>>> >>
>>> >>
>>> >>
>>> >>
>>> >> On Mon, Jul 21, 2014 at 10:06 AM, Guy Bedford <guybedford at gmail.com>
>>> >> wrote:
>>> >>>
>>> >>> In Brian's case we actually need default exports. This is because the
>>> >>> dynamic loader can't pick up the code he has written right now in
>>> >>> ES6.
>>> >>>
>>> >>> This is how he is loading a NodeJS module in ES6:
>>> >>>
>>> >>> module minimist from 'minimist';
>>> >>>
>>> >>> In ES6 this means "give me the Module object with getters to the
>>> >>> exports".
>>> >>>
>>> >>> But unfortunately in Traceur this is compiling into:
>>> >>>
>>> >>> var minimist = require('minimist');
>>> >>>
>>> >>> As a result the `module` syntax can possibly return him a 'function'
>>> >>> or
>>> >>> other non-Module object.
>>> >>
>>> >>
>>> >> You seem to be saying "The traceur implementation of 'module' fails in
>>> >> this case".  It seems to me that Traceur could generate code which
>>> >> would
>>> >> wrap functions in Module objects.  That is, this is not a fundamental
>>> >> limit,
>>> >> just an unreported bug.
>>> >>
>>> >>>
>>> >>> Thus we have broken the ability to parse his code in the ES6 dynamic
>>> >>> loader, as it is not capable of returning a non-Module object for a
>>> >>> module
>>> >>> import, which is pretty critical.
>>> >>>
>>> >>> Thus default export properties are critical to enabling this support
>>> >>> path.
>>> >>
>>> >>
>>> >> I believe that Caridy's point is: "fine, use dynamic linking".
>>> >>
>>> >>>
>>> >>>
>>> >>>
>>> >>> On 21 July 2014 09:51, Caridy Patino <caridy at gmail.com> wrote:
>>> >>>>
>>> >>>> Interoperability should not be a decisive factor here, we have
>>> >>>> fallen
>>> >>>> into that trap before, the conclusion was to let Loader to handle
>>> >>>> those
>>> >>>> cases rather than trying to drive it from the perspective of the
>>> >>>> module
>>> >>>> syntax. Let's focus on what is best and what makes sense for the ES
>>> >>>> Modules,
>>> >>>> and keep the dynamic module systems out of the picture since we know
>>> >>>> we have
>>> >>>> a lot of flexibility with the loader to deal with those dynamic
>>> >>>> modules.
>>> >>>>
>>> >>>> /caridy
>>> >>>>
>>> >>>>
>>> >>>> On Mon, Jul 21, 2014 at 12:37 PM, Brian Di Palma <offler at gmail.com>
>>> >>>> wrote:
>>> >>>>>
>>> >>>>> Yep, that makes sense. Highly unlikely but still possible and could
>>> >>>>> cause issues.
>>> >>>>> No doubt you could complicate your compiler to deal with these edge
>>> >>>>> cases but why force that?
>>> >>>>>
>>> >>>>> Yet more problems with default imports/exports. This feature
>>> >>>>> doesn't
>>> >>>>> seem worth its cost.
>>> >>>>>
>>> >>>>>
>>> >>>>> On Mon, Jul 21, 2014 at 5:21 PM, Calvin Metcalf
>>> >>>>> <calvin.metcalf at gmail.com> wrote:
>>> >>>>> > (woops hit reply instead of reply all)
>>> >>>>> >
>>> >>>>> > Because the `function mainThing(){}` might already have a method
>>> >>>>> > named
>>> >>>>> > helper or, more likely, the named export is something like call
>>> >>>>> > or
>>> >>>>> > bind.
>>> >>>>> >
>>> >>>>> >
>>> >>>>> >
>>> >>>>> >
>>> >>>>> > On Mon, Jul 21, 2014 at 12:06 PM, Brian Di Palma
>>> >>>>> > <offler at gmail.com>
>>> >>>>> > wrote:
>>> >>>>> >>
>>> >>>>> >> 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
>>> >>>>> >
>>> >>>>> >
>>> >>>>> >
>>> >>>>> >
>>> >>>>> > --
>>> >>>>> > -Calvin W. Metcalf
>>> >>>>> _______________________________________________
>>> >>>>> es-discuss mailing list
>>> >>>>> es-discuss at mozilla.org
>>> >>>>> https://mail.mozilla.org/listinfo/es-discuss
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>> _______________________________________________
>>> >>>> es-discuss mailing list
>>> >>>> es-discuss at mozilla.org
>>> >>>> https://mail.mozilla.org/listinfo/es-discuss
>>> >>>>
>>> >>>
>>> >>>
>>> >>> _______________________________________________
>>> >>> es-discuss mailing list
>>> >>> es-discuss at mozilla.org
>>> >>> https://mail.mozilla.org/listinfo/es-discuss
>>> >>>
>>> >>
>>> >
>>
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>


More information about the es-discuss mailing list