Dr. Axel Rauschmayer has announced the finalised details of the ECMAScript 6 (ES6) module syntax.
In his article "ECMAScript 6 modules: the final syntax", Rauschmayer gives a detailed overview of the complete ES6 module system, including ECMAScript 6 modules, module metadata, and the ECMAScript 6 module loader API.
Rauschmayer says that the goal for ES6 modules has been to create a format that users of CommonJS and of AMD are both happy with, and that being built into the language allows ES6 modules to go beyond CommonJS and AMD.
In ES6, there are two kinds of exports. These are named exports (several per module) and default exports (one per module). With named exports, a module can export multiple things by prefixing their declarations with the keyword export -- and are distinguished by their names.
Rauschmayer says:
There are other ways to specify named exports, but I find this one quite convenient: simply write your code as if there were no outside world, then label everything that you want to export with a keyword.
If you want to, you can also import the whole module and refer to its named exports via property notation.
Default exports in ES6 are the most important exported value, and Rauschmayer says Default exports are especially easy to import. He notes that Modules that only export single values are common in front end development where there are often constructors/classes for models, with one model per module.
ES6 also brings with it a way to access information about the current module (for example the module’s URL) from inside of the module. In this instance, the module is a token indicating that the meta-data is imported “as a module”. This is as below:
import { url } from this module;
console.log(url);
The meta-data can also be accessed via an object:
import * as metaData from this module;
console.log(metaData.url);
As well as the declarative syntax for working with modules, ES6 also includes a programmatic API, that lets developers both programmatically work with modules and scripts, and configure module loading. With the API, Rauschmayer says:
Loaders handle resolving module specifiers (the string IDs at the end of import...from), loading modules, etc. Their constructor is
Reflect.Loader
. Each platform keeps a customized instance in the global variableSystem
(the system loader), which implements its specific style of module loading.
Rauschmayer goes on to say that the module loader API has various hooks for configuration. Described as a "work in progress", Rauschmayer says the loader API "will permit many customizations of the loading process". For example:
- Lint modules on import (e.g. via JSLint or JSHint)
- Automatically translate modules on import (they could contain CoffeeScript or TypeScript code)
- Use legacy modules (AMD, Node.js)
Rauschmayer says that configurable module loading is an area where Node.js and CommonJS are limited.
Reactions from the JavaScript community to the finalised details of ES6's module syntax have been largely positive.
On Reddit, in the discussion, ECMAScript 6 modules: the final syntax, user brtt3000 commented: "I like it, seems to cover all the important parts and the syntax is pretty good." On Hacker News, Alan Johnson -- software engineer for The Hackerati -- commented "ES6 is such a breath of fresh air."
However, there was also confusion and apprehension in some areas.
Evan Winslow commented on Rauschmayer's article, saying
If the default export is just a named export, how does that prefer default export? Doesn't that implicitly mean that named exports are the preferred method, and default exports are just a hack on top of it? If you use the System.import method to asynchronously load a module, you have to use .default to get at the default export. This is going to be confusing.
Rauschmayer replied:
The JS modules community is diverse and ES6 has to support all of their use cases. That means that it is slightly more complicated than it needs to be, but it also has the potential to unify the community.
InfoQ readers that would like to submit a proposal for ES7+ should refer to the ECMAScript6 Github.