Quantifying Default Exports
Great work on the analysis, very thorough.
For what it's worth I disagree with
3) Default exports improve interoperability with legacy modules.
Based on my experience default exports do not help interoperability with legacy module systems.
I'm currently working on a global namespaced script code to ES6/CJS module compiler using node.js. The compiler is written in ES6 and I'm using CJS npm packages in the project.
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.
There is no export named default
to import, so I'm forced to use the
module form.
module minimist from 'minimist';
Examples taken from briandipalma/global-compiler/blob/master/src/index.js
Default imports/exports seem totally unnecessary to me. Nothing more then a distraction, providing no value but overhead.
Great work on the analysis, very thorough. For what it's worth I disagree with 3) Default exports improve interoperability with legacy modules. Based on my experience default exports do not help interoperability with legacy module systems. I'm currently working on a global namespaced script code to ES6/CJS module compiler using node.js. The compiler is written in ES6 and I'm using CJS npm packages in the project. 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. There is no export named `default` to import, so I'm forced to use the module form. module minimist from 'minimist'; Examples taken from https://github.com/briandipalma/global-compiler/blob/master/src/index.js Default imports/exports seem totally unnecessary to me. Nothing more then a distraction, providing no value but overhead.
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
> 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
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
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?
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
similar discussion at systemjs systemjs/systemjs#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.
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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/cf9f49cc/attachment.html>
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.
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
that won't help if module.exports is a function
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.
that won't help if module.exports is a function 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. 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/64d73f99/attachment-0001.html>
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.
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 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
I have a CommonJS module which exports a single function
//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
//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 jsmodules.io which can be sumerized as
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.
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
//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
//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.
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. 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/d6177266/attachment.html>
Making named and default exports be mutually exclusive would mean that you could treat default export like module.exports.
Or just drain the swamp and remove default exports, rather than fighting these alligators.
> > > Making named and default exports be mutually exclusive would mean that you > could treat default export like module.exports. > Or just drain the swamp and remove default exports, rather than fighting these alligators. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/ea3ec708/attachment.html>
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
//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
//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 jsmodules.io which can be sumerized as
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.
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
(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.
(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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/e92cdcdd/attachment.html>
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.
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
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.
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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/59c22cc1/attachment.html>
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. 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.
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. 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. 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 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/5a49cdbd/attachment-0001.html>
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 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 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/10e5e5d6/attachment-0001.html>
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.
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 >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/897c4fe1/attachment-0001.html>
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.
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 >>> >> >
There are two issues here:
- Is 'default' essential?
- 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
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 > >>> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/ad3abf04/attachment-0001.html>
From my understanding there was no spec work done to support bundling.
The reasoning I heard was due to HTTP/2 making this obsolete. I agree with that and think that's a sensible decision, the community have come up with their own shared solution which seems to work. At least that's my understanding of the System.register work.
Could the same approach not be taken for compatability with legacy
module systems?
If traceur and the ES6ML polyfills decide that default
or exports
is the export name they will provide module.exports
with I will use
that when interfacing with legacy code until it's upgraded.
One day in the future this will no longer be a concern, just like bundling, so specing it seems to give it undue permanence.
>From my understanding there was no spec work done to support bundling. The reasoning I heard was due to HTTP/2 making this obsolete. I agree with that and think that's a sensible decision, the community have come up with their own shared solution which seems to work. At least that's my understanding of the System.register work. Could the same approach not be taken for compatability with legacy module systems? If traceur and the ES6ML polyfills decide that `default` or `exports` is the export name they will provide `module.exports` with I will use that when interfacing with legacy code until it's upgraded. One day in the future this will no longer be a concern, just like bundling, so specing it seems to give it undue permanence. On Mon, Jul 21, 2014 at 10:48 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 >> >>> >> >> >> > > >
Wasn't the original issue single exports and their demonstrated utility in node and AMD?
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 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140721/8a6d5822/attachment-0001.html>
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.
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 >> >
On 22 Jul 2014 00:30, "Calvin Metcalf" <calvin.metcalf at gmail.com> wrote:
Wasn't the original issue single exports and their demonstrated utility
in node and AMD?
Default can be used with named exports, and therefore does not indicate that a module is single export. And you can make a single export module by exporting a single named export. Therefore there is no correlation between default and single exporting modules.
The default import is a useful syntactic sugar, but the default export does not map well with it, especially because rather than saving keystrokes it is (potentially) longer to use than a named export.
Marius Gundersen
On 22 Jul 2014 00:30, "Calvin Metcalf" <calvin.metcalf at gmail.com> wrote: > > Wasn't the original issue single exports and their demonstrated utility in node and AMD? Default can be used with named exports, and therefore does not indicate that a module is single export. And you can make a single export module by exporting a single named export. Therefore there is no correlation between default and single exporting modules. The default import is a useful syntactic sugar, but the default export does not map well with it, especially because rather than saving keystrokes it is (potentially) longer to use than a named export. Marius Gundersen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140722/e7037773/attachment.html>
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.
Just a side note, but for performance reasons in a real runtime system you can't pre-determine whether the target is an ES6 module or not - that would imply double-parsing and would necessarily be heuristic and incomplete.
In the end, either the import side or some preconfigured application state will have to explicitly specify which targets are ES6 and which are not.
I've worked though most of these issues already in es6now, which provides a complete picture of a backward compatible ES6 module system running on Node.
> > > 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. > Just a side note, but for performance reasons in a real runtime system you can't pre-determine whether the target is an ES6 module or not - that would imply double-parsing and would necessarily be heuristic and incomplete. In the end, either the import side or some preconfigured application state will have to explicitly specify which targets are ES6 and which are not. I've worked though most of these issues already in es6now, which provides a complete picture of a backward compatible ES6 module system running on Node. https://github.com/zenparsing/es6now/blob/master/docs/modules.md -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140722/45928e7a/attachment-0001.html>
This is why I have previously posted asking for a function to determine if a given object is a module object.
Given such a function, Reflect.isModule say, we can convert our code to AMD or CommonJS like the following:
import p from 'module';
Converts to CommonJS:
var module = require('module'); if (!Reflect.isModule(module)) { module = { default: module }; } var p = module['default'];
Now whether the module is an ES6 module or another CommonJS module, we get what we expect.
This is why I have previously posted asking for a function to determine if a given object is a module object. Given such a function, *Reflect.isModule* say, we can convert our code to AMD or CommonJS like the following: import p from 'module'; Converts to CommonJS: var module = require('module'); if (!Reflect.isModule(module)) { module = { default: module }; } var p = module['default']; Now whether the module is an ES6 module or another CommonJS module, we get what we expect. On 22 July 2014 20:43, Kevin Smith <zenparsing at gmail.com> wrote: > >> 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. >> > > Just a side note, but for performance reasons in a real runtime system you > can't pre-determine whether the target is an ES6 module or not - that would > imply double-parsing and would necessarily be heuristic and incomplete. > > In the end, either the import side or some preconfigured application state > will have to explicitly specify which targets are ES6 and which are not. > > I've worked though most of these issues already in es6now, which provides > a complete picture of a backward compatible ES6 module system running on > Node. > > https://github.com/zenparsing/es6now/blob/master/docs/modules.md > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140722/c66ea735/attachment.html>
On 21 juil. 2014, at 17:16, Calvin Metcalf <calvin.metcalf at gmail.com<mailto:calvin.metcalf at gmail.com>> wrote:
I have a CommonJS module which exports a single function
//cj.js
module.exports = function (){}
Just to be exact this wouldn't be exactly a "CommonJS" module wiki.commonjs.org/wiki/Modules
module.exports isn't part of any of the 1.0, 1.1, or 1.1.1 versions of the CommonJS modules specification CommonJS doesn't support neither to replace the original exports object reference by another, so:
exports = function (){}
First implemented in node.js, then in few SSJS implementations to better support node modules it never was accepted as part of the standard, because considered as too error prone groups.google.com/forum/#!searchin/commonjs/cyclic/commonjs/DECN5h4Lfms/-BrIu7TpKQkJ and is still not supported by some other CommonJS implementations
[cid:81032e.png at a90d966c.47bea091] Alexandre Morgaut Wakanda Community Manager Email : Alexandre.Morgaut at 4d.com<mailto:Alexandre.Morgaut at 4d.com>
Web : www.4D.comwww.4D.com
4D SAS 60, rue d'Alsace 92110 Clichy - France Standard : +33 1 40 87 92 00
[cid:89448b.png at dd969963.47bf9b71]www.4d.com/fr/company/events/summiteu2014.html
Hi Calvin, On 21 juil. 2014, at 17:16, Calvin Metcalf <calvin.metcalf at gmail.com<mailto:calvin.metcalf at gmail.com>> wrote: I have a CommonJS module which exports a single function ```js //cj.js module.exports = function (){} ``` Just to be exact this wouldn't be exactly a "CommonJS" module http://wiki.commonjs.org/wiki/Modules module.exports isn't part of any of the 1.0, 1.1, or 1.1.1 versions of the CommonJS modules specification CommonJS doesn't support neither to replace the original exports object reference by another, so: ```js exports = function (){} ``` First implemented in node.js, then in few SSJS implementations to better support node modules it never was accepted as part of the standard, because considered as too error prone https://groups.google.com/forum/#!searchin/commonjs/cyclic/commonjs/DECN5h4Lfms/-BrIu7TpKQkJ and is still not supported by some other CommonJS implementations [cid:81032e.png at a90d966c.47bea091] Alexandre Morgaut Wakanda Community Manager Email : Alexandre.Morgaut at 4d.com<mailto:Alexandre.Morgaut at 4d.com> Web : www.4D.com<http://www.4D.com> 4D SAS 60, rue d'Alsace 92110 Clichy - France Standard : +33 1 40 87 92 00 [cid:89448b.png at dd969963.47bf9b71]<http://www.4d.com/fr/company/events/summiteu2014.html> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140729/318ae413/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: 81032e.png Type: image/png Size: 4628 bytes Desc: 81032e.png URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140729/318ae413/attachment-0002.png> -------------- next part -------------- A non-text attachment was scrubbed... Name: 89448b.png Type: image/png Size: 91073 bytes Desc: 89448b.png URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140729/318ae413/attachment-0003.png>
In the "ModuleImport" thread, I pointed out that the user experience gains from default exports would be marginal. I thought it might be interesting to put some numbers behind that claim, so I performed a rough analysis on a sampling of NPM packages.
Methodology
I compiled a list of the 500 "most-dependended-upon" NPM packages using the data found at www.npmjs.org/browse/depended . For each package, I downloaded the package archive from the NPM registry, used
npm install
to install the package's dependencies, and then loaded the package using Node'srequire
. For each loaded package, I recorded the following information:typeof === "object"
, whether the object's prototype was Object.prototype.typeof !== "object"
, a list of the object's own keys.The installation and loading process failed for a small selection of packages (usually because of binary compilation issues). In those cases, I opened the package code in a text editor and manually recorded the data.
In addition, I performed static analysis on a Python codebase I'm familiar with containing over 6000 files, counting the number of occurrences of import declarations with and without import renaming.
Results
(a) NPM packages scanned: 500
(b) Packages with custom exports (*): 280 (56%)
(c) Packages with a function-valued export: 257 (51.4%)
(d) Packages with an expanded function export (**): 148 (29.6%)
(*)
typeof exports !== "object || Object.getPrototypeOf(exports) !== Object.prototype
(**) Exported function has own keys (expandos)
(e) Python modules scanned: 6096
(f) Imports: 46276
(g) Renamed imports: 1472 (3.18%)
Analysis
There are three known arguments supporting default exports. Let's take a look at each one in turn.
This argument is unsound, since the user always has to know the API of the source module before use, regardless of whether or not default exports are used.
However, we also see that roughly 30% of packages export a function with custom properties attached as expandos. These packages are in effect multiple-export modules. In ES6, they would be written as named exports with a default export. In such cases, the benefit of implicit import renaming must be balanced against the added API complexity of having both a default export and named exports: the user has to remember which exports are named and which one is anonymous. We assume that the net effect is no improvement to user experience. As such, we can eliminate these cases from the pool that is expected to benefit from default exports.
That leaves us with 132 packages (26.4% of the total) which will receive a net benefit from implicit renaming. Let's call this group B, and its inverse ~B. From the Python data (g), we see that imported bindings are renamed, on average, in only 3.18% of cases. If we make a simplifying assumption that packages from B and ~B will be imported on average the same number of times, we can multiply percentages to find an estimate for the amount of renames we can expect to save, which turns out to be 0.84%.
Therefore, we can expect to save the user one explicit rename for every 119 imported bindings.
All legacy modules which export a custom object will benefit from default exports, since it will allow the user to write:
import x from "x";
instead of:
import { default as x } from "x";
Since 56% of the packages in this study export a custom object, we can expect this benefit to apply in 56% of cases. However, two points must be noted.
First, this is a retrograde optimization. Optimizations should favor future usage of the language, not legacy usage. The value of the optimization should be viewed in this light.
Secondly, the optimization can be made entirely redundant by simply modifying the legacy packages in this study to expose their custom export object as a named expando property. For example:
function Foo() {} module.exports = Foo; Foo.Foo = module.exports;
Then the following will work without supporting syntax:
import { Foo } from "foo";
Such a strategy will allow users to experience the same benefit as default exports.
Conclusion
The default export feature creates a two-tiered module system, where a favored export is made the "default", and subordinate exports are named. Such a system is confusing to users and API developers. From analyzing NPM packages and import-renaming frequencies in Python, we see that the optimization provided by default exports for ES6 modules is insignificant.
The optimization for legacy modules is more significant, but there are other, equally effective solutions which do not require burdening the language with a confusing two-tiered module system.
It's been suggested that default exports merely paves a cowpath trod by CommonJS, Node and AMD. A more appropriate way to view the situation is to see that ES6 modules (without defaults) builds a highway over the cowpath, making the cowpath itself obsolete.