Update 2013-11-22: David Herman has published the slide deck “Status Report: ES6 Modules”.
[1] is an introduction to ECMAScript 6 modules and how they can be used in current browsers. In contrast, this blog post explains how future browsers will support them natively. As part of that support, we will get the <module> tag, a better version of the <script> tag.
Scripts. Scripts are normally loaded or executed synchronously. The JavaScript thread stops until the code has been loaded or executed.
Given the synchronicity of scripts, it is obvious that you can’t simply add import and export capability and turn them into modules. There must be a way to handle module code differently. Therefore, there will be a new tag <module> for modules that replaces the <script> tag and is completely asynchronous:
<module> import $ from 'lib/jquery'; var x = 123; // The current scope is not global console.log('$' in window); // false console.log('x' in window); // false // `this` still refers to the global object console.log(this === window); // true </module>As you can see, the tag has its own scope and variables “inside” it are local to that scope. Note that module code is implicitly in strict mode [2]. This is great news – no more 'use strict';
Similar to <script>, <module> can also be used to load external modules. For example, the following tag starts a web application via a main module (the attribute name import is my invention, it isn’t yet clear what name will be used).
<module import="impl/main"><module>For legacy browsers, the following tag is a polyfillable [3] alternative (either with inner text or an attribute import):
<script type="module">
url-for-package SEPARATOR path-inside-packageTo support graceful degradation, the separator must be sent to the server by current browsers, must not be rejected by current servers and must not appear in current web content. Furthermore, package URL and separator must not impede the resolution of relative paths (including those with two dots in them). That means, for example, that neither of them can include a question mark, because that limits the resolution of relative paths to what comes before that symbol.
One candidate for the separator is "!/". With this separator, a URL that refers to a file main.js inside a package looks like this:
http://example.com/app.pack!/impl/main.jsThe following two tags use package URLs. The first starts a web application, the second displays a logo. In both cases, the files are inside the package.
<script src="app.pack!/impl/main.js"> <img src="app.pack!/img/logo.jpg">The nice thing about packaging is that old servers and browsers can use it, too:
Intriguingly, packages could become a cross-browser format for archiving web pages (including images, CSS, etc.).
How to best set up modules to be loaded from a package is still being worked out. At the very least you can plug into the module loader API and set it up manually.
In its inline version, the <module> tag nicely cleans up the problematic <script> tag: