optimized harmony reexport

fixed #2050
This commit is contained in:
Tobias Koppers 2016-02-16 22:31:12 +01:00
parent 2b94afad33
commit a3d768e708
10 changed files with 59 additions and 23 deletions

View File

@ -53,34 +53,40 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
var active = HarmonyModulesHelpers.isActive(dep.originModule, dep);
var content;
var activeExports;
if(!used) {
content = "/* unused harmony reexport " + (dep.name || "namespace") + " */";
} else if(!active) {
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */";
} else if(dep.name === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule)) {
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "_default.a; }});";
} else if(dep.name && dep.id) {
function getReexportStatement(key, valueKey) {
return (importIsHarmony || !valueKey ? "" : "if(Object.prototype.hasOwnProperty.call(" + name + ", " + valueKey + ")) ") +
"Object.defineProperty(exports, " + key + ", "+
"{configurable: false, enumerable: true, get: function() { return " + name + (valueKey === null ? "_default.a" : valueKey && "[" + valueKey + "]") + "; }});"
}
if(!used) { // we want to rexport something, but the export isn't used
content = "/* unused harmony reexport " + (dep.name || "namespace") + " */\n";
} else if(!active) { // we want to reexport something but another exports overrides this one
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */\n";
} else if(dep.name && dep.id === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule)) { // we want to reexport the default export from a non-hamory module
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), null) + "\n";
} else if(dep.name && dep.id) { // we want to reexport a key as new key
var idUsed = importedModule && importedModule.isUsed(dep.id);
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + (name + "[" + JSON.stringify(idUsed) + "]") + "; }});";
} else if(dep.name) {
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "; }});";
} else if(Array.isArray(dep.originModule.usedExports)) {
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), JSON.stringify(idUsed)) + "\n";
} else if(dep.name) { // we want to reexport the module object as named export
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), "") + "\n";
} else if(Array.isArray(dep.originModule.usedExports)) { // we now which exports are used
activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
var importIsHarmony = importedModule && importedModule.meta.harmonyModule;
var importActiveExports = importedModule && HarmonyModulesHelpers.getActiveExports(importedModule);
var items = dep.originModule.usedExports.map(function(id) {
if(id === "default") return;
if(activeExports.indexOf(id) >= 0) return;
if(importIsHarmony && importActiveExports.indexOf(id) < 0) return;
var exportUsed = dep.originModule.isUsed(id);
var idUsed = importedModule && importedModule.isUsed(id);
return [exportUsed, idUsed];
}).filter(Boolean);
if(items.length > 1) {
content = "/* harmony namespace reexport */ " + JSON.stringify(items) + ".forEach(function(i) { " +
"Object.defineProperty(exports, i[0], {configurable: false, enumerable: true, get: function() { return " + (name + "[i[1]]") + "; }});" +
"});";
} else if(items.length === 1) {
content = "/* harmony namespace reexport */ Object.defineProperty(exports, " + JSON.stringify(items[0][0]) + ", {configurable: false, enumerable: true, get: function() { return " + (name + "[" + JSON.stringify(items[0][1]) + "]") + "; }});";
} else content = "/* unused harmony namespace reexport */";
} else if(dep.originModule.usedExports) {
if(items.length > 0) {
content = "/* harmony namespace reexport */ " + items.map(function(item) {
return getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
}).join(" ") + "\n";
} else content = "/* unused harmony namespace reexport */\n";
} else if(dep.originModule.usedExports) { // not sure which exports are used
activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
content = "/* harmony namespace reexport */ for(var __WEBPACK_IMPORT_KEY__ in " + name + ") ";
@ -90,8 +96,8 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
content += "if(" + JSON.stringify(activeExports.concat("default")) + ".indexOf(__WEBPACK_IMPORT_KEY__) < 0) ";
else
content += "if(__WEBPACK_IMPORT_KEY__ !== 'default') ";
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));";
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));\n";
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));\n";
}
source.insert(dep.position, content);
};

View File

@ -8,7 +8,7 @@ import { one, two } from "exportKinds";
import { test1, test2 } from "exportKinds";
import { a as rea, b as reb, c as rec, o as reo, two as retwo } from "reexport";
import { a as rea, b as reb, c as rec, o as reo, two as retwo, def as Thing3 } from "reexport";
import threeIsOdd, { even } from "circularEven";
@ -90,4 +90,5 @@ it("should be able to import commonjs", function() {
Thing2.should.have.type("function");
new Thing2().value.should.be.eql("thing");
Other2.should.be.eql("other");
Thing3().should.be.eql("thing");
});

View File

@ -1,2 +1,3 @@
export * from "abc";
export { one as o, two } from "exportKinds";
export { one as o, two } from "exportKinds";
export { default as def } from "commonjs";

View File

@ -0,0 +1,2 @@
var xa = "a";
export { xa };

View File

@ -0,0 +1,2 @@
var xb = "b";
export { xb };

View File

@ -0,0 +1,2 @@
var xc = "c";
export { xc };

View File

@ -0,0 +1,2 @@
var xd = "d";
exports.xd = xd;

View File

@ -0,0 +1,8 @@
it("should support multiple reexports", function() {
require("./x").should.be.eql({
xa: "a",
xb: "b",
xc: "c",
xd: "d"
});
});

View File

@ -0,0 +1,4 @@
export * from "./a";
export * from "./b";
export * from "./c";
export * from "./d";

View File

@ -0,0 +1,8 @@
import { xa, xb, xc, xd } from "./module";
module.exports = {
xa: xa,
xb: xb,
xc: xc,
xd: xd
}