Reputation: 2048
I try to repeat example from Mozilla Hacks (Export lists subtitle):
//export.js
export {detectCats, Kittydar};
function detectCats() {}
class Kittydar {}
//import.js
import {detectCats, Kittydar} from "./export.js";
console.log(detectCats); // function detectCats() {}
console.log(Kittydar); // undefined
Oops: Kittydar is undefined (btw., the problem is the same with simple Object
).
But if I put export
after Kittydar
declaration it's ok:
//export.js
class Kittydar {}
export {Kittydar};
//import.js
import {Kittydar} from "./export.js";
console.log(Kittydar); // function Kittydar() {_classCallCheck(this, Kittydar);}
Is this a typo in the article?
I transpile this with babel
and bundle with browserify
. Then I include output bundle in a usual .html
file (with <script>
tag).
Upvotes: 5
Views: 746
Reputation: 45116
The standard is hard to follow on this, but the article is correct. This code works in es6draft and in the SpiderMonkey shell: both the function and the class are initialized by the time those console.log
calls run.
Here's how it's supposed to work, in minute detail:
The JS engine parses import.js. It sees the import
declaration, so then it loads export.js and parses it as well.
Before actually running any of the code, the system creates both module scopes and populates them with all the top-level bindings that are declared in each module. (The spec calls this ModuleDeclarationInstantiation.) A Kittydar
binding is created in export.js, but it's uninitialized for now.
In import.js, a Kittydar
import binding is created. It's an alias for the Kittydar
binding in export.js.
export.js runs. The class is created. Kittydar
is initialized.
import.js runs. Both console.log()
calls work fine.
Babel's implementation of ES6 modules is nonstandard.
I think it's deliberate. Babel aims to compile ES6 modules into ES5 code that works with an existing module system of your choice: you can have it spit out AMD modules, UMD, CommonJS, etc. So if you ask for AMD output, your code might be ES6 modules, but the ES5 output is an AMD module and it's going to behave like an AMD module.
Babel could probably be more standard-compliant while still integrating nicely with the various module systems, but there are tradeoffs.
Upvotes: 6