Closed thomasboyt closed 10 years ago
Prior work from #85 discussion:
test case from harmony wiki (which tends to be super out of date, but this one seems okay): http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples#cyclic_dependencies
// easy!
module 'Even' {
import odd from 'Odd';
export default function even(n) {
return n == 0 || odd(n - 1);
}
}
// woo-hoo!
module 'Odd' {
import even from 'Even';
export default function odd(n) {
return n != 0 && even(n - 1);
}
}
current output:
// a.js
"use strict";
var even = require("./a")["default"];
exports["default"] = function odd(n) {
return n === 0 || even(n - 1);
}
// b.js
"use strict";
var odd = require("b")["default"];
exports["default"] = function even(n) {
return n === 0 || odd(n - 1);
}
err:
> require('./tmp/b')['default'](5)
TypeError: undefined is not a function
at Object.odd [as default] (/Users/thomasboyt/Code/es6-module-transpiler/test/cycles/tmp/b.js:5:21)
I'm currently working on a solution using @wycats' Gist, seems like it should work well. It looks like the exports
special argument in AMD modules should be able to use the same solution, too: http://requirejs.org/docs/api.html#circular
branch to watch: https://github.com/square/es6-module-transpiler/tree/cycles
Worth mentioning this branch has regressed by removing compatFix
:
import DefaultExport from "non-es6-module";
new DefaultExport();
becomes
__imports__['non-es6-module'] = require('non-es6-module');
__imports__['non-es6-module'] = __imports__['non-es6-module'].__es6_module__ || __imports__['non-es6-module'];
new __imports__['non-es6-module'].default();
which, of course, explodes. Potential fix:
__imports__['non-es6-module'] = require('non-es6-module');
if (__imports__['non-es6-module'].__es6_module__) {
__imports__['non-es6-module'] = __imports__['non-es6-module'].__es6_module__;
__imports__['non-es6-module'].__is_es6__ = true;
}
new (__imports__['non-es6-module'].__is_es6__ ? __imports__['non-es6-module'].default || __imports__['non-es6-module'])();
which is unwieldy, to say the least.
(also, it occurs to me that if you need this behavior right now, you could, uh, just use require()
for non-es6 modules. I wonder if this is actually not a crazy solution, considering that Node presumedly will continue supporting require
after it actually introduces ES6 modules support sometime in 2018).
Why not use getter?
//Even.js
"use strict";
Object.defineProperty(exports, "default", {
get: function () {
return even
}
})
var odd = require("Odd")["default"];
function even(n) {
return n == 0 || odd(n - 1);
}
// Odd.js
"use strict";
Object.defineProperty(exports, "default", {
get: function () {
return odd
}
})
var even = require("Even")["default"];
function odd(n) {
return n != 0 && even(n - 1);
}
Quick nit: If using Object.defineProperty then the platform is modern enough that default
can be used as an IdentifierName instead of a string property accessor
Porting my project from requirejs to es6 module. Stuck with the cycle dep problem. @thomasboyt Are you still working on this ? :)
@merlinchen this work is now part of the recast refactor: https://github.com/square/es6-module-transpiler/pull/126
and yes, we are committed to preserve the semantics of ES6 modules for ES5 runtimes, and it might come in different flavors :)
This should now work properly in v0.5.1. Please give it a shot!
Here's what we need to even get started:
Implementation details