Skip to content

Commit f76e38d

Browse files
committed
es6+beyond: ch3, more on module loading
1 parent 2f8a6d1 commit f76e38d

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

es6 & beyond/ch3.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,12 +1440,24 @@ hello.baz = 42; // (runtime) TypeError!
14401440

14411441
Recall earlier in the "`export`ing API Members" section that we talked about how the `bar` and `baz` bindings are bound to the actual identifiers inside the `"world"` module. That means if the module changes those values, `hello.bar` and `hello.baz` now reference the updated values.
14421442

1443-
But the immutable/read-only nature of your local imported bindings enforces that you cannot change them from the importing code, hence the `TypeError`s. That's pretty important, because without those protections, your changes would end up affecting all other consumers of the module (remember: singleton), which could create some very surprising side-effects.
1443+
But the immutable/read-only nature of your local imported bindings enforces that you cannot change them from the imported bindings, hence the `TypeError`s. That's pretty important, because without those protections, your changes would end up affecting all other consumers of the module (remember: singleton), which could create some very surprising side-effects!
14441444

14451445
Moreover, though a module *can* change its API members from the inside, you should be very cautious of intentionally designing your modules in that fashion. ES6 modules are *supposed to be* static, so deviations from that principle should be rare and should be carefully and verbosely documented.
14461446

14471447
**Warning:** There are module design philosophies where you actually intend to let a consumer change the value of a property on your API, or module APIs are designed to be "extended" by having other "plugins" add to the API namespace. As we just asserted, ES6 module APIs should be thought of and designed as static and unchangeable, which strongly restricts and discourages these alternate module design patterns. You can get around these limitations by exporting a plain object, which of course can then be changed at will. But be careful and think twice before going down that road.
14481448

1449+
From inside a module, you can access its own metadata information using the `this module` target in place of a string module specifier:
1450+
1451+
```js
1452+
import { url as moduleURL } from this module;
1453+
import * as meta from this module;
1454+
1455+
console.log( moduleURL ); // ..
1456+
1457+
console.log( meta.url ); // ..
1458+
console.log( meta.name ); // ..
1459+
```
1460+
14491461
Finally, the most basic form of the `import` looks like this:
14501462

14511463
```js
@@ -1525,14 +1537,16 @@ bar( 25 ); // 11.5
15251537

15261538
The static loading semantics of the `import` statement mean that a `"foo"` and `"bar"` which mutually depend on each other via `import` will ensure that both are loaded, parsed, and compiled before either of them runs. So their circular dependency is statically resolved and this works as you'd expect.
15271539

1528-
### Module Loader
1540+
### Module Loading
15291541

1530-
We asserted at the beginning of this "Modules" section that the `import` statement uses a separate mechanism, provided by the hosting environment (browser, Node.js, etc.) to actually resolve the module specifier string into some useful instruction for finding and loading the desired module. That process is handled by a *Module Loader*.
1542+
We asserted at the beginning of this "Modules" section that the `import` statement uses a separate mechanism, provided by the hosting environment (browser, Node.js, etc.), to actually resolve the module specifier string into some useful instruction for finding and loading the desired module. That mechanism is the system *Module Loader*.
15311543

15321544
The default module loader provided by the environment will interpret a module specifier as a URL if in the browser, and (generally) as a local file system path if on a server such as Node.js. The default behavior is to assume the loaded file is authored in the ES6 standard module format.
15331545

15341546
For the vast majority of users and uses, the default loader will be sufficient.
15351547

1548+
The module loader is not specified by ES6. It is a separate, parallel standard (http://whatwg.github.io/loader/) controlled by the WHATWG browser standards group. At the time of this writing, the following is the expected API design, but of course things are subject to change.
1549+
15361550
#### Loading Modules Outside Of Modules
15371551

15381552
One use for the module loader is if your main program (non-module) needs to load a module. Consider:
@@ -1544,11 +1558,13 @@ One use for the module loader is if your main program (non-module) needs to load
15441558
System.import( "foo" )
15451559
// returns a promise
15461560
.then( function(foo){
1547-
1561+
foo.bar();
15481562
} );
1549-
15501563
```
15511564

1565+
The `System.import(..)` utility imports the entire module into the named parameter as a namespace, just like the `import * as foo ..` namespace import we discussed earlier.
1566+
1567+
**Note:** The `System.import(..)` utility returns a promise that is fulfilled once the module is ready. To import multiple modules, you can compose promises from multiple `System.import(..)` calls using `Promise.all([ .. ])`. For more information about promises, see "Promises" in Chapter 4.
15521568

15531569
#### Customized Loading
15541570

0 commit comments

Comments
 (0)