Let anon be the symbol denoting anonymous export.
Assume the following syntaxes:
export default [Expression]; // sets the anonymous export
export [Declaration] // sets a named export
import <[Identifier]> from "module url"; // imports named export
import [Identifier] from "module url"; // imports anonymous export
import "module url" as [Identifier]; // imports module instance object (MIO)// foo.js
export default "this is default";
// bar.js
import x from "foo.js";
assert(x === "this is default");
import "foo.js" as mio;
assert(mio[anon] === x);// foo.js
export function aFunction() { };
// bar.js
import <aFunction> from "foo.js";
assert(typeof aFunction === "function");
import x from "foo.js"; // `x` is the MIO by default!
assert(typeof x.aFunction === "function");
import "foo.js" as mio;
assert(mio === x);
assert(mio[anon] === x);This differs from the current thinking in that import x from "foo.js" returns the MIO, instead of failing.
// foo.js
export function aFunction() { };
export default "this is default";
// bar.js
import <aFunction> from "foo.js";
assert(typeof aFunction === "function");
import "foo.js" as mio;
assert(mio !== x);
assert(mio[anon] === x);
import x from "foo.js"; // `x` is the anon export we explicitly set, instead of the MIO.
assert(typeof x.aFunction === "undefined");
assert(x === "this is default");This helps the refactoring hazard identified in https://gist.github.com/domenic/4754483#refactoring-example, allowing libraries to transparently switch from MIOs to objects-or-functions with properties.
E.g., with this proposal, you could have
// libV1.js
export function async() { };
export function sync() { };
// consumer.js
import lib from "libV1.js";
lib.sync();
lib.async();
// libV2.js
export function sync() { };
export function async() { };
function theDefault() {
// User testing has revealed that async is by far the most common operation.
return async();
}
theDefault.sync = sync;
theDefault.async = async;
export default theDefault;Without Kevin's proposal of a default anonymous export equal to the MIO, with version 1 of the library the consumer would have to be using
import "libV1.js" as lib;But that would break the moment he switched to version 2 of the library! He'd be required instead to do
import lib from "libV1.js";This is a notable downside of current proposals vs. Node.js or AMD.
There are very few cases anymore where import ... as has any utility. Namely, it only matters when you are using a library that:
- Has overriden the default anonymous export
- Is also using named exports
- Does not expose those named exports as properties of the anonymous export
- Has enough properties that consumers usually want to import the module wholesale, instead of piecewise using
import <[Identifier]>syntax.
I'm on the fence on this one. It's pretty nice, but doesn't feel that clean, y'know?