At first glance, it seems like anonymous exports might provide a way for pre-ES6 (read: Node) modules and ES6 modules to coexist.  After all:<div><br></div><div>    exports = function A() {};</div><div><br></div><div>just looks so much like:</div>
<div><br></div><div>    module.exports = function A() {};</div><div><br></div><div>But is that the case?  Does this oddball syntax actually help?</div><div><br></div><div>My conclusion is that it does not, *unless* the loading environment is willing to statically analyze every single module it wishes to load.  Moreover, the desired interop is not even possible without performing static analysis.</div>
<div><br></div><div>There are two directions that an interop strategy will have to deal with.  First, we might want an ES6 module to be loaded by a pre-ES6 module:</div><div><br></div><div>    // "es5-module.js"</div>
<div>    var ES6Module = require("es6-module.js");</div><div><br></div><div>We might want to use this when a dependency is upgraded to ES6 modules and we want to leave the dependent alone.  Now, since ES6 modules are asynchronous, and require is synchronous, we must load "es6-module.js" *before* "es5-module.js" is executed.  The only way to do that is to statically analyze "es5-module.js", searching for calls to require.</div>
<div><br></div><div>However, since require allows an arbitrary expression argument, there are many cases in Node where this static analysis will fail.</div><div><br></div><div>What about the other direction?  Let's say that we want to load an ES5 module from an ES6 module:</div>
<div><br></div><div>    import ES5Module from "es5-module.js";</div><div><br></div><div>Let's say that the ES5 module looks like this:</div><div><br></div><div>    // "es5-module.js"</div><div>    module.exports = function A() {};</div>
<div><br></div><div>We could dynamically add the following text to the end of "es5-module.js":</div><div><br></div><div>    exports = module.exports;</div><div><br></div><div>And thereby export the necessary binding.  But if we use such a trick on an *ES6* module, we could run into problems:</div>
<div><br></div><div>    exports = "foo";</div><div>    // dynamically generated line:</div><div>    exports = module.exports;</div><div><br></div><div>This would presumably result in an error!   The only way to avoid such problems (without resorting to something like "package language version flags") is to statically analyze "es5-module.js" and only apply the trick if ES6 module declarations are *not* found.</div>
<div><br></div><div>So interop implies static analysis.  And since parsing and analyzing javascript, in javascript, for every single loaded module would be quite a performance hit, I think such a strategy is infeasible.</div>
<div><br></div><div>So where does that leave anonymous exports?  My personal opinion is "nowhere".</div><div><br></div><div>- Kevin</div><div><br></div>