Do Anonymous Exports Solve the Backwards Compatibility Problem?

James Burke jrburke at gmail.com
Thu Dec 20 11:44:20 PST 2012


On Thu, Dec 20, 2012 at 8:22 AM, Kevin Smith <khs4473 at gmail.com> wrote:
> This is exactly the use case that my OP addresses.  The logic goes like
> this:  in order to apply that boilerplate, you have to know whether the
> module is ES5 or ES6.  In order to know that, you have to parse it.
> Pre-parsing every single module is not practical for a production system.
> Therefore applying such boilerplate is not practical for a production
> system.

That was not my impression of how backcompat would be done. I was
under the impression it would be more like this:

* The module loader API exposes a "runtime" API that is not new
syntax, just an API. From some earlier Module Loader API drafts, I
thought it was something like System.get() to get a dependency,
System.set() to set the value that will be used as the export.

* Base libraries that need to live in current ES and ES.next worlds
(jquery, underscore, backbone, etc…) would *not* use the ES.next
module syntax, but feature detect the System API and call it to
participate in an ES.next module scenario, similar to how a module
today detects if it wants to register for node, AMD or browser
globals:

https://github.com/umdjs/umd/blob/master/returnExportsGlobal.js

* Modules using the ES.next module syntax will most likely be
contained to "app logic" at first because not all browsers will have
ES.next capabilities right away, and only apps that can restrict
themselves to ES.next browsers will use the module syntax. Everything
else will use the runtime API.

Otherwise, forcing existing libraries that need to exist in
non-ES.next browsers to provide a "ES.next" copy of their library that
force the use of new JS module syntax is effectively creating a "2JS"
system, and if that is going to happen, might as well do more
backwards incompatible changes for ES.next. Previous discussion on
this list seem to indicate a desire to keep with 1JS.

For using ES5 libraries that do not call the ES Module Loader runtime
API, a "shim" declarative config could be supported by the ES Module
Loader API, similar to the one in use by AMD loaders:

http://requirejs.org/docs/api.html#config-shim

this allows the end developer to consume the old code in a modular
fashion, and the parsing is done by the ES Module Loader, not userland
JS.

So, there is not a case where someone would try to ship a module
loader that does full JS parsing to detect new module syntax, except
for more experimental purposes. Or just one used in dev, but then do a
build to translate to ES5 syntax, converting module syntax to the
runtime API forms so that it could run in either ES.next browsers or
in ES5 browsers with an API shim.

> No - the solution for Node WRT ES6 modules, in my mind, is to "pull off the
> bandaid".  The solution should not be to make compromises on the module
> design side.

With the runtime System API, node can adapt their module system to use
the ES.next Module Loader API hooks for resolve/fetch and hopefully a
way to register a require function for each module that underneath
calls System.get() and module.exports calling System.set.

However, the ES.next Module Loader API is doing the actual parsing of
the file, scanning for ES.next module syntax, so Node itself does not
need to deliver an in-JS parser.

Maybe instead of (I would like to see in addition to) System.set()
there is a System.exports, like the CommonJS `exports`, that would
allow avoiding the "exports assignment" pattern for modules that want
to do that.

Summary:

If that all of the above holds true (getting clarification on the
Module Loader API is needed), then I do not believe the original post
about parsing of old and new code is a strong case for avoiding export
assignment.

James


More information about the es-discuss mailing list