Optimize export-from in System.register - fixes #1722

This commit is contained in:
Logan Smyth 2015-07-04 22:03:06 -07:00
parent 4a84cd785a
commit cdb8e3aefa
6 changed files with 101 additions and 1 deletions

View File

@ -78,6 +78,7 @@ export default class SystemFormatter extends AMDFormatter {
constructor(file) { constructor(file) {
super(file); super(file);
this._setters = null;
this.exportIdentifier = file.scope.generateUidIdentifier("export"); this.exportIdentifier = file.scope.generateUidIdentifier("export");
this.noInteropRequireExport = true; this.noInteropRequireExport = true;
this.noInteropRequireImport = true; this.noInteropRequireImport = true;
@ -178,11 +179,14 @@ export default class SystemFormatter extends AMDFormatter {
var block = t.blockStatement(program.body); var block = t.blockStatement(program.body);
var setterListNode = this._buildRunnerSetters(block, hoistDeclarators);
this._setters = setterListNode;
var runner = util.template("system", { var runner = util.template("system", {
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()), MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
EXPORT_IDENTIFIER: this.exportIdentifier, EXPORT_IDENTIFIER: this.exportIdentifier,
MODULE_NAME: moduleNameLiteral, MODULE_NAME: moduleNameLiteral,
SETTERS: this._buildRunnerSetters(block, hoistDeclarators), SETTERS: setterListNode,
EXECUTE: t.functionExpression(null, [], block) EXECUTE: t.functionExpression(null, [], block)
}, true); }, true);

View File

@ -84,4 +84,5 @@ export default {
_blockHoist: require("./internal/block-hoist"), _blockHoist: require("./internal/block-hoist"),
jscript: require("babel-plugin-jscript"), jscript: require("babel-plugin-jscript"),
flow: require("./other/flow"), flow: require("./other/flow"),
"optimisation.modules.system": require("./optimisation/modules.system"),
}; };

View File

@ -0,0 +1,50 @@
import * as t from "../../../types";
export var metadata = {
optional: true,
group: "builtin-trailing"
};
export var visitor = {
Program(node, parent, scope, file){
if (file.moduleFormatter._setters){
scope.traverse(file.moduleFormatter._setters, optimizeSettersVisitor, {
exportFunctionIdentifier: file.moduleFormatter.exportIdentifier
});
}
}
};
/**
* Setters are optimized to avoid slow export behavior in modules that rely on deep hierarchies
* of export-from declarations.
* More info in https://github.com/babel/babel/pull/1722 and
* https://github.com/ModuleLoader/es6-module-loader/issues/386.
*
* TODO: Ideally this would be optimized during construction of the setters, but the current
* architecture of the module formatters make that difficult.
*/
var optimizeSettersVisitor = {
FunctionExpression: {
enter: (node, parent, scope, state) => {
state.hasExports = false;
state.exportObjectIdentifier = scope.generateUidIdentifier("exportObj");
},
exit: (node, parent, scope, state) => {
if (!state.hasExports) return;
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(t.cloneDeep(state.exportObjectIdentifier), t.objectExpression([]))
]));
node.body.body.push(t.expressionStatement(t.callExpression(
t.cloneDeep(state.exportFunctionIdentifier), [t.cloneDeep(state.exportObjectIdentifier)])));
}
},
CallExpression: (node, parent, scope, state) => {
if (!t.isIdentifier(node.callee, {name: state.exportFunctionIdentifier.name})) return;
state.hasExports = true;
var memberNode = t.memberExpression(t.cloneDeep(state.exportObjectIdentifier), node.arguments[0], true);
return t.assignmentExpression("=", memberNode, node.arguments[1]);
}
};

View File

@ -0,0 +1,4 @@
{
"modules": "system",
"optional": ["optimisation.modules.system"]
}

View File

@ -0,0 +1,8 @@
export * from "foo";
export {foo} from "foo";
export {foo, bar} from "foo";
export {foo as bar} from "bar";
export {foo as default} from "bar";
export {foo as default, bar} from "bar";
export var foo, bar;

View File

@ -0,0 +1,33 @@
System.register(["foo", "bar"], function (_export) {
"use strict";
var foo, bar;
return {
setters: [function (_foo) {
var _exportObj = {};
for (var _key in _foo) {
_exportObj[_key] = _foo[_key];
}
_exportObj["foo"] = _foo.foo;
_exportObj["foo"] = _foo.foo;
_exportObj["bar"] = _foo.bar;
_export(_exportObj);
}, function (_bar) {
var _exportObj2 = {};
_exportObj2["bar"] = _bar.foo;
_exportObj2["default"] = _bar.foo;
_exportObj2["default"] = _bar.foo;
_exportObj2["bar"] = _bar.bar;
_export(_exportObj2);
}],
execute: function () {
_export("foo", foo);
_export("bar", bar);
}
};
});