The AMD output of traceur has me a bit confused. The return value looks a lot like an ES6 class - shouldn't this be converting all the way to ES5? FWIW, my options (to traceur) are:
{
modules: "amd",
outputLanguage: 'es5'
}
define([], function() { | |
"use strict"; | |
var myVar = {}; | |
var $__default = myVar; | |
return { | |
get default() { | |
return $__default; | |
}, | |
__esModule: true | |
}; | |
}); |
var myVar = {}; | |
export default myVar; |
[Edit: I removed much of this comment, especially what I wrote about cyclic dependencies.]
ECMAScript 6 modules export bindings, not values. The indirection via getters emulates this behavior.
@domenic - I'm sorry. This exposed a gap in my knowledge on apparent shorthand syntax for creating a defined prop. When this wasn't working in IE (I'm cross testing the output in multiple browsers...the last being IE11...where { get default() {} } lands you with default = undefined.), it prompted the assumption that perhaps I: 1.) don't properly understand what traceur's doing here and 2.) wondered if I was dealing with interim transpiler output...
UPDATE: oh good lord it's been one of those days for me (brain not working AND fighting IE). I was looking at the wrong output in IE in my tests. Sigh. 👊 to my face....
So - I chalk this up to my ignorance (hence why I asked for help).
@rauschma - thanks for the explanation. That makes sense.
Glad it makes sense. There is certainly room to argue removing these guards for older IE support / performance.
@rauschma, I believe your CommonJS cycle example actually would work properly. It has the potential to cause an infinite loop depending on how you fill in the blanks, but so does the ES6 version. Could you come up with another example that can be run to show the difference?
@eventualbuddha You may be right. I’ll have to give this more thought (which will take a while – busy ATM).
@eventualbuddha: ES6 and (node flavored) CJS both have different cyclic dependency strategies so
ES6 cyclic dependencies that don't work in CJS
//even.js
import { odd } from './odd'
export var counter = 0;
export function even(n) {
counter++;
return n == 0 || odd(n - 1);
}
//odd.js
import { even } from './even';
export function odd(n) {
return n != 0 && even(n - 1);
}
//app.js
import { even } from './even';
even(); //this works
CJS circular dependencies that don't work in ES6
//a.js
exports.obj = {};
var b = require('./b');
b.something();
//b.js
var a = require('./a');
a.obj.val = 'asdf';
exports.something = function() {};
//app.js
require('./a'); // this doesn't throw
Agreed with @eventualbuddha, that example would work because of partially loaded modules.
Modules are cached after the first time they are loaded. This means (among other things) that every call to
require('foo')
will get exactly the same object returned, if it would resolve to the same file. Multiple calls torequire('foo')
may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.
edit: This was posted way after composing it, and a few comments were posted before it.
This is valid ES5 syntax; why would you think it's not?