Skip to content

Commit a3d768e

Browse files
committed
optimized harmony reexport
fixed webpack#2050
1 parent 2b94afa commit a3d768e

File tree

10 files changed

+59
-23
lines changed

10 files changed

+59
-23
lines changed

lib/dependencies/HarmonyExportImportedSpecifierDependency.js

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,34 +53,40 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
5353
var active = HarmonyModulesHelpers.isActive(dep.originModule, dep);
5454
var content;
5555
var activeExports;
56-
if(!used) {
57-
content = "/* unused harmony reexport " + (dep.name || "namespace") + " */";
58-
} else if(!active) {
59-
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */";
60-
} else if(dep.name === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule)) {
61-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "_default.a; }});";
62-
} else if(dep.name && dep.id) {
56+
function getReexportStatement(key, valueKey) {
57+
return (importIsHarmony || !valueKey ? "" : "if(Object.prototype.hasOwnProperty.call(" + name + ", " + valueKey + ")) ") +
58+
"Object.defineProperty(exports, " + key + ", "+
59+
"{configurable: false, enumerable: true, get: function() { return " + name + (valueKey === null ? "_default.a" : valueKey && "[" + valueKey + "]") + "; }});"
60+
}
61+
if(!used) { // we want to rexport something, but the export isn't used
62+
content = "/* unused harmony reexport " + (dep.name || "namespace") + " */\n";
63+
} else if(!active) { // we want to reexport something but another exports overrides this one
64+
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */\n";
65+
} 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
66+
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), null) + "\n";
67+
} else if(dep.name && dep.id) { // we want to reexport a key as new key
6368
var idUsed = importedModule && importedModule.isUsed(dep.id);
64-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + (name + "[" + JSON.stringify(idUsed) + "]") + "; }});";
65-
} else if(dep.name) {
66-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "; }});";
67-
} else if(Array.isArray(dep.originModule.usedExports)) {
69+
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), JSON.stringify(idUsed)) + "\n";
70+
} else if(dep.name) { // we want to reexport the module object as named export
71+
content = "/* harmony reexport */ " + getReexportStatement(JSON.stringify(used), "") + "\n";
72+
} else if(Array.isArray(dep.originModule.usedExports)) { // we now which exports are used
6873
activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
74+
var importIsHarmony = importedModule && importedModule.meta.harmonyModule;
75+
var importActiveExports = importedModule && HarmonyModulesHelpers.getActiveExports(importedModule);
6976
var items = dep.originModule.usedExports.map(function(id) {
7077
if(id === "default") return;
7178
if(activeExports.indexOf(id) >= 0) return;
79+
if(importIsHarmony && importActiveExports.indexOf(id) < 0) return;
7280
var exportUsed = dep.originModule.isUsed(id);
7381
var idUsed = importedModule && importedModule.isUsed(id);
7482
return [exportUsed, idUsed];
7583
}).filter(Boolean);
76-
if(items.length > 1) {
77-
content = "/* harmony namespace reexport */ " + JSON.stringify(items) + ".forEach(function(i) { " +
78-
"Object.defineProperty(exports, i[0], {configurable: false, enumerable: true, get: function() { return " + (name + "[i[1]]") + "; }});" +
79-
"});";
80-
} else if(items.length === 1) {
81-
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]) + "]") + "; }});";
82-
} else content = "/* unused harmony namespace reexport */";
83-
} else if(dep.originModule.usedExports) {
84+
if(items.length > 0) {
85+
content = "/* harmony namespace reexport */ " + items.map(function(item) {
86+
return getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
87+
}).join(" ") + "\n";
88+
} else content = "/* unused harmony namespace reexport */\n";
89+
} else if(dep.originModule.usedExports) { // not sure which exports are used
8490
activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
8591
content = "/* harmony namespace reexport */ for(var __WEBPACK_IMPORT_KEY__ in " + name + ") ";
8692

@@ -90,8 +96,8 @@ HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep
9096
content += "if(" + JSON.stringify(activeExports.concat("default")) + ".indexOf(__WEBPACK_IMPORT_KEY__) < 0) ";
9197
else
9298
content += "if(__WEBPACK_IMPORT_KEY__ !== 'default') ";
93-
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));";
99+
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));\n";
100+
content += "(function(key) { Object.defineProperty(exports, key, {configurable: false, enumerable: true, get: function() { return " + name + "[key]; }}) }(__WEBPACK_IMPORT_KEY__));\n";
94101
}
95102
source.insert(dep.position, content);
96-
97103
};

test/cases/parsing/harmony/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { one, two } from "exportKinds";
88

99
import { test1, test2 } from "exportKinds";
1010

11-
import { a as rea, b as reb, c as rec, o as reo, two as retwo } from "reexport";
11+
import { a as rea, b as reb, c as rec, o as reo, two as retwo, def as Thing3 } from "reexport";
1212

1313
import threeIsOdd, { even } from "circularEven";
1414

@@ -90,4 +90,5 @@ it("should be able to import commonjs", function() {
9090
Thing2.should.have.type("function");
9191
new Thing2().value.should.be.eql("thing");
9292
Other2.should.be.eql("other");
93+
Thing3().should.be.eql("thing");
9394
});

test/cases/parsing/harmony/node_modules/reexport.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/cases/parsing/issue-2050/a.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var xa = "a";
2+
export { xa };

test/cases/parsing/issue-2050/b.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var xb = "b";
2+
export { xb };

test/cases/parsing/issue-2050/c.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var xc = "c";
2+
export { xc };

test/cases/parsing/issue-2050/d.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var xd = "d";
2+
exports.xd = xd;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
it("should support multiple reexports", function() {
2+
require("./x").should.be.eql({
3+
xa: "a",
4+
xb: "b",
5+
xc: "c",
6+
xd: "d"
7+
});
8+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from "./a";
2+
export * from "./b";
3+
export * from "./c";
4+
export * from "./d";

test/cases/parsing/issue-2050/x.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { xa, xb, xc, xd } from "./module";
2+
3+
module.exports = {
4+
xa: xa,
5+
xb: xb,
6+
xc: xc,
7+
xd: xd
8+
}

0 commit comments

Comments
 (0)