Currently you can export things from a module in at least six different ways, and import things in at least six different ways, resulting in 36 different combinations, most of which are not semantically valid.
Here is a greatly simplified (and probably naive) suggestion for modules in ES6:
###export You can only export named things, including variables and functions.
let a = "hello";
export a;
export const b = {number: 5, text: "World"};
export function add(a, b){
return a + b;
};
###import The module consists of named bindings, which can be imported by other modules:
import {a, b, add} from "myModule";
console.log(add(a, b.text)); //helloWorld
static analysis can be used to ensure that the imported values exist in the exported module. If any of them are missing a load time error is produced.
ES6 object destructuring can be used when importing modules:
import {a: hello, b: {text: world}} from "myModule";
console.log(add(hello, world)); //helloWorld
Static analysis cannot be used to ensure that destructuring is correct, so a runtime error is produced if the destructuring does not work.
All of the exported bindings can be imported as a single object if the {}
is not used in the import statement:
import myModule from "myModule";
console.log(myModule.add(myModule.a, myModule.b.text)); //helloWorld
Again, static analysis is not possible, so a runtime error is produced if the properties does not exist in the module object.
This is great for libraries that export many things, for example underscore:
import _ from "underscore";
console.log(_.map([1, 2, 3], a => a*2); //2, 4, 6
###destructured export
export default
is replaced with object destructuring:
export var {a, b} = {a:"hello", b:"World"}
//this is the same as
export var a = "hello";
export var b = "World";
Destructured export can be combined with normal export, as long as no binding name is used twice. Static analysis can be used to check this, so a load time error can be produced if the module violates this.
Using destructured export existing code which produces an object of functions (like underscore) can be modernized and made to work with ES6 modules:
var _ = {
//The existing underscore code
};
export var {map, reduce, each, filter} = _;
The module is always an object, never a function or string, etc. This makes modules easy to reason about. If you expect a module to export a single function, you can know for certain that you need to wrap the import binding in curly braces. If you want to export a single function, export it like you would anything else:
export function $(){ /* ... */ };
//and to import it:
import {$} from "jQuery";
$('body');
import {x} from "y"
form you're suggesting encourages modules with many exports, whereas it's often preferable to have modules that export a single thing (a class or a function).