clean up dynamic imports, disable hoisting in system module formatter when **any** dynamic imports are included - fixes #1219

This commit is contained in:
Sebastian McKenzie 2015-04-11 17:22:48 -07:00
parent aba2d1c23c
commit 7905f48280
10 changed files with 57 additions and 41 deletions

View File

@ -36,10 +36,9 @@ function checkNode(stack, node, scope) {
export default class File { export default class File {
constructor(opts = {}) { constructor(opts = {}) {
this.dynamicImportedNoDefault = []; this.dynamicImportAbsoluteDefaults = [];
this.dynamicImportIds = {}; this.dynamicImportIds = {};
this.dynamicImported = []; this.dynamicImports = [];
this.dynamicImports = [];
this.usedHelpers = {}; this.usedHelpers = {};
this.dynamicData = {}; this.dynamicData = {};
@ -335,7 +334,7 @@ export default class File {
return source; return source;
} }
addImport(source: string, name?: string, noDefault?: boolean): Object { addImport(source: string, name?: string, absoluteDefault?: boolean): Object {
name ||= source; name ||= source;
var id = this.dynamicImportIds[name]; var id = this.dynamicImportIds[name];
@ -346,9 +345,7 @@ export default class File {
var specifiers = [t.importDefaultSpecifier(id)]; var specifiers = [t.importDefaultSpecifier(id)];
var declar = t.importDeclaration(specifiers, t.literal(source)); var declar = t.importDeclaration(specifiers, t.literal(source));
declar._blockHoist = 3; declar._blockHoist = 3;
if (absoluteDefault) this.dynamicImportAbsoluteDefaults.push(declar);
this.dynamicImported.push(declar);
if (noDefault) this.dynamicImportedNoDefault.push(declar);
if (this.transformers["es6.modules"].canTransform()) { if (this.transformers["es6.modules"].canTransform()) {
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports); this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);

View File

@ -80,9 +80,10 @@ export default class AMDFormatter extends DefaultFormatter {
this.defaultIds[key] = specifier.local; this.defaultIds[key] = specifier.local;
} }
if (includes(this.file.dynamicImportedNoDefault, node)) { if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
// Prevent unnecessary renaming of dynamic imports. // prevent unnecessary renaming of dynamic imports
this.ids[node.source.value] = ref; this.ids[node.source.value] = ref;
ref = t.memberExpression(ref, t.identifier("default"));
} else if (t.isImportNamespaceSpecifier(specifier)) { } else if (t.isImportNamespaceSpecifier(specifier)) {
// import * as bar from "foo"; // import * as bar from "foo";
} else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) { } else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {

View File

@ -45,20 +45,18 @@ export default class CommonJSFormatter extends DefaultFormatter {
// import foo from "foo"; // import foo from "foo";
if (t.isSpecifierDefault(specifier)) { if (t.isSpecifierDefault(specifier)) {
if (includes(this.file.dynamicImportedNoDefault, node)) { if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
this.internalRemap[variableName.name] = ref; this.internalRemap[variableName.name] = ref;
} else if (this.noInteropRequireImport) {
this.internalRemap[variableName.name] = t.memberExpression(ref, t.identifier("default"));
} else { } else {
if (this.noInteropRequireImport) { var uid = this.scope.generateUidBasedOnNode(node, "import");
this.internalRemap[variableName.name] = t.memberExpression(ref, t.identifier("default"));
} else if (!includes(this.file.dynamicImported, node)) {
var uid = this.scope.generateUidBasedOnNode(node, "import");
nodes.push(t.variableDeclaration("var", [ nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref])) t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]))
])); ]));
this.internalRemap[variableName.name] = t.memberExpression(uid, t.identifier("default")); this.internalRemap[variableName.name] = t.memberExpression(uid, t.identifier("default"));
}
} }
} else { } else {
if (t.isImportNamespaceSpecifier(specifier)) { if (t.isImportNamespaceSpecifier(specifier)) {
@ -106,7 +104,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
var call = t.callExpression(t.identifier("require"), [node.source]); var call = t.callExpression(t.identifier("require"), [node.source]);
var uid; var uid;
if (includes(this.file.dynamicImported, node) && !includes(this.file.dynamicImportedNoDefault, node)) { if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
call = t.memberExpression(call, t.identifier("default")); call = t.memberExpression(call, t.identifier("default"));
uid = node.specifiers[0].local; uid = node.specifiers[0].local;
} else { } else {

View File

@ -6,12 +6,8 @@ import each from "lodash/collection/each";
import map from "lodash/collection/map"; import map from "lodash/collection/map";
import * as t from "../../types"; import * as t from "../../types";
var canHoist = function (node, file) {
return node._blockHoist && !file.transformers.runtime.canTransform();
}
var hoistVariablesVisitor = { var hoistVariablesVisitor = {
enter(node, parent, scope, hoistDeclarators) { enter(node, parent, scope, state) {
if (t.isFunction(node)) { if (t.isFunction(node)) {
// nothing inside is accessible // nothing inside is accessible
return this.skip(); return this.skip();
@ -24,13 +20,13 @@ var hoistVariablesVisitor = {
} }
// ignore block hoisted nodes as these can be left in // ignore block hoisted nodes as these can be left in
if (canHoist(node, scope.file)) return; if (state.formatter.canHoist(node)) return;
var nodes = []; var nodes = [];
for (var i = 0; i < node.declarations.length; i++) { for (var i = 0; i < node.declarations.length; i++) {
var declar = node.declarations[i]; var declar = node.declarations[i];
hoistDeclarators.push(t.variableDeclarator(declar.id)); state.hoistDeclarators.push(t.variableDeclarator(declar.id));
if (declar.init) { if (declar.init) {
// no initializer so we can just hoist it as-is // no initializer so we can just hoist it as-is
var assign = t.expressionStatement(t.assignmentExpression("=", declar.id, declar.init)); var assign = t.expressionStatement(t.assignmentExpression("=", declar.id, declar.init));
@ -56,11 +52,11 @@ var hoistVariablesVisitor = {
}; };
var hoistFunctionsVisitor = { var hoistFunctionsVisitor = {
enter(node, parent, scope, handlerBody) { enter(node, parent, scope, state) {
if (t.isFunction(node)) this.skip(); if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || canHoist(node, scope.file)) { if (t.isFunctionDeclaration(node) || state.formatter.canHoist(node)) {
handlerBody.push(node); state.handlerBody.push(node);
this.remove(); this.remove();
} }
} }
@ -174,6 +170,10 @@ export default class SystemFormatter extends AMDFormatter {
})); }));
} }
canHoist(node) {
return node._blockHoist && !this.file.dynamicImports.length;
}
transform(program) { transform(program) {
DefaultFormatter.prototype.transform.apply(this, arguments); DefaultFormatter.prototype.transform.apply(this, arguments);
@ -197,7 +197,10 @@ export default class SystemFormatter extends AMDFormatter {
var returnStatement = handlerBody.pop(); var returnStatement = handlerBody.pop();
// hoist up all variable declarations // hoist up all variable declarations
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators); this.file.scope.traverse(block, hoistVariablesVisitor, {
formatter: this,
hoistDeclarators: hoistDeclarators
});
if (hoistDeclarators.length) { if (hoistDeclarators.length) {
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators); var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
@ -206,7 +209,10 @@ export default class SystemFormatter extends AMDFormatter {
} }
// hoist up function declarations for circular references // hoist up function declarations for circular references
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody); this.file.scope.traverse(block, hoistFunctionsVisitor, {
formatter: this,
handlerBody: handlerBody
});
handlerBody.push(returnStatement); handlerBody.push(returnStatement);

View File

@ -15,7 +15,7 @@ exports.Function = function (node, parent, scope, file) {
return remapAsyncToGenerator( return remapAsyncToGenerator(
node, node,
t.memberExpression(file.addImport("bluebird", null, true), t.identifier("coroutine")), t.memberExpression(file.addImport("bluebird"), t.identifier("coroutine")),
scope scope
); );
}; };

View File

@ -79,15 +79,15 @@ exports.Program = function (node, parent, scope, file) {
exports.pre = function (file) { exports.pre = function (file) {
file.set("helperGenerator", function (name) { file.set("helperGenerator", function (name) {
return file.addImport(`babel-runtime/helpers/${name}`, name); return file.addImport(`babel-runtime/helpers/${name}`, name, true);
}); });
file.setDynamic("coreIdentifier", function () { file.setDynamic("coreIdentifier", function () {
return file.addImport("babel-runtime/core-js", "core"); return file.addImport("babel-runtime/core-js", "core", true);
}); });
file.setDynamic("regeneratorIdentifier", function () { file.setDynamic("regeneratorIdentifier", function () {
return file.addImport("babel-runtime/regenerator", "regeneratorRuntime"); return file.addImport("babel-runtime/regenerator", "regeneratorRuntime", true);
}); });
}; };

View File

@ -2,6 +2,8 @@
var _bluebird2 = require("bluebird"); var _bluebird2 = require("bluebird");
var _bluebird3 = babelHelpers.interopRequireWildcard(_bluebird2);
var Foo = (function () { var Foo = (function () {
function Foo() { function Foo() {
babelHelpers.classCallCheck(this, Foo); babelHelpers.classCallCheck(this, Foo);
@ -9,7 +11,7 @@ var Foo = (function () {
babelHelpers.createClass(Foo, [{ babelHelpers.createClass(Foo, [{
key: "foo", key: "foo",
value: _bluebird2.coroutine(function* () { value: _bluebird3["default"].coroutine(function* () {
var wat = yield bar(); var wat = yield bar();
}) })
}]); }]);

View File

@ -2,6 +2,10 @@
var _bluebird2 = require("bluebird"); var _bluebird2 = require("bluebird");
var foo = _bluebird2.coroutine(function* () { var _bluebird3 = _interopRequireWildcard(_bluebird2);
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var foo = _bluebird3["default"].coroutine(function* () {
var wat = yield bar(); var wat = yield bar();
}); });

View File

@ -2,9 +2,13 @@
var _bluebird2 = require("bluebird"); var _bluebird2 = require("bluebird");
var _bluebird3 = _interopRequireWildcard(_bluebird2);
var _bar; var _bar;
var foo = _bar = _bluebird2.coroutine(function* () { var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var foo = _bar = _bluebird3["default"].coroutine(function* () {
console.log(_bar); console.log(_bar);
}); });

View File

@ -2,6 +2,10 @@
var _bluebird2 = require("bluebird"); var _bluebird2 = require("bluebird");
var foo = _bluebird2.coroutine(function* () { var _bluebird3 = _interopRequireWildcard(_bluebird2);
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var foo = _bluebird3["default"].coroutine(function* () {
var wat = yield bar(); var wat = yield bar();
}); });