Skip to content

Commit 8cb0ee7

Browse files
committed
mangle harmony export names
1 parent e52b7b2 commit 8cb0ee7

7 files changed

Lines changed: 70 additions & 17 deletions

lib/Module.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
var DependenciesBlock = require("./DependenciesBlock");
66
var ModuleReason = require("./ModuleReason");
7+
var Template = require("./Template");
8+
var HarmonyModulesHelpers = require("./dependencies/HarmonyModulesHelpers");
79

810
var debugId = 1000;
911

@@ -102,13 +104,17 @@ Module.prototype.rewriteChunkInReasons = function(oldChunk, newChunks) {
102104
};
103105

104106
Module.prototype.isUsed = function(exportName) {
105-
if(this.used === null) return true;
106-
if(!exportName) return this.used;
107+
if(this.used === null) return exportName;
108+
if(!exportName) return this.used ? true : false;
107109
if(!this.used) return false;
108110
if(!this.usedExports) return false;
109-
if(this.usedExports === true) return true;
110-
return this.usedExports.indexOf(exportName) >= 0;
111-
}
111+
if(this.usedExports === true) return exportName;
112+
var idx = this.usedExports.indexOf(exportName);
113+
if(idx < 0) return false;
114+
if(HarmonyModulesHelpers.isExportedByHarmony(this, exportName))
115+
return Template.numberToIdentifer(idx);
116+
return exportName;
117+
};
112118

113119
Module.prototype.toString = function() {
114120
return "Module[" + (this.id || this.debugId) + "]";

lib/Template.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ Template.toIdentifier = function(str) {
2020
return str.replace(/^[^a-zA-Z$_]/, "_").replace(/[^a-zA-Z0-9$_]/g, "_");
2121
};
2222

23+
var A_CODE = "a".charCodeAt(0);
24+
var Z_CODE = "z".charCodeAt(0);
25+
var AZ_COUNT = Z_CODE - A_CODE;
26+
var A2_CODE = "A".charCodeAt(0);
27+
var Z2_CODE = "Z".charCodeAt(0);
28+
var AZ2_COUNT = Z2_CODE - A2_CODE;
29+
Template.numberToIdentifer = function numberToIdentifer(n) {
30+
if(n < AZ_COUNT) return String.fromCharCode(A_CODE + n);
31+
if(n < AZ_COUNT + AZ2_COUNT) return String.fromCharCode(A2_CODE + n + AZ_COUNT);
32+
return "_" + (n - AZ_COUNT - AZ2_COUNT);
33+
};
34+
2335
Template.prototype = Object.create(Tapable.prototype);
2436
Template.prototype.constructor = Template;
2537

lib/dependencies/HarmonyExportExpressionDependency.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@ HarmonyExportExpressionDependency.prototype = Object.create(NullDependency.proto
1616
HarmonyExportExpressionDependency.prototype.constructor = HarmonyExportExpressionDependency;
1717
HarmonyExportExpressionDependency.prototype.type = "harmony export expression";
1818

19+
HarmonyExportExpressionDependency.prototype.describeHarmonyExport = function() {
20+
return {
21+
exportedName: "default",
22+
precedence: 1
23+
};
24+
};
25+
1926
HarmonyExportExpressionDependency.Template = function HarmonyExportDependencyTemplate() {};
2027

2128
HarmonyExportExpressionDependency.Template.prototype.apply = function(dep, source) {
2229
var used = dep.originModule.isUsed("default");
2330
var content;
2431
if(used)
25-
content = "/* harmony default export */ exports[" + JSON.stringify("default") + "] = ";
32+
content = "/* harmony default export */ exports[" + JSON.stringify(used) + "] = ";
2633
else
2734
content = "/* unused harmony default export */ var _unused_webpack_default_export = ";
2835
if(dep.range) {

lib/dependencies/HarmonyExportImportedSpecifierDependency.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,39 @@ HarmonyExportImportedSpecifierDependency.Template = function HarmonyExportImport
4343
HarmonyExportImportedSpecifierDependency.Template.prototype.apply = function(dep, source, outputOptions, requestShortener) {
4444
var name = dep.importedVar;
4545
var used = dep.originModule.isUsed(dep.name);
46+
var importedModule = dep.importDependency.module;
4647
var active = HarmonyModulesHelpers.isActive(dep.originModule, dep);
47-
var comment = "";
48-
if(outputOptions.pathinfo) comment = "/*! " + requestShortener.shorten(dep.request) + " */ ";
4948
var content;
5049
if(!used) {
5150
content = "/* unused harmony reexport " + (dep.name || "namespace") + " */";
5251
} else if(!active) {
5352
content = "/* inactive harmony reexport " + (dep.name || "namespace") + " */";
54-
} else if(dep.name === "default" && !(dep.importDependency.module.meta && dep.importDependency.module.meta.harmonyModule)) {
55-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(dep.name) + ", {configurable: false, enumerable: true, get: function() { return " + comment + name + "_default.a; }});";
53+
} else if(dep.name === "default" && !(importedModule && importedModule.meta && importedModule.meta.harmonyModule)) {
54+
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "_default.a; }});";
5655
} else if(dep.name && dep.id) {
57-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(dep.name) + ", {configurable: false, enumerable: true, get: function() { return " + comment + (name + "[" + JSON.stringify(dep.id) + "]") + "; }});";
56+
var idUsed = importedModule && importedModule.isUsed(dep.id);
57+
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + (name + "[" + JSON.stringify(idUsed) + "]") + "; }});";
5858
} else if(dep.name) {
59-
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(dep.name) + ", {configurable: false, enumerable: true, get: function() { return " + comment + name + "; }});";
60-
} else {
59+
content = "/* harmony reexport */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + name + "; }});";
60+
} else if(Array.isArray(dep.originModule.usedExports)) {
6161
var activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
62-
content = "/* harmony namespace reexport */ for(var __WEBPACK_IMPORT_KEY__ in " + comment + name + ") ";
62+
var items = dep.originModule.usedExports.map(function(id) {
63+
if(id === "default") return;
64+
if(activeExports.indexOf(id) >= 0) return;
65+
var exportUsed = dep.originModule.isUsed(id);
66+
var idUsed = importedModule && importedModule.isUsed(id);
67+
return [exportUsed, idUsed];
68+
}).filter(Boolean);
69+
if(items.length > 1) {
70+
content = "/* harmony namespace reexport */ " + JSON.stringify(items) + ".forEach(function(i) { " +
71+
"Object.defineProperty(exports, i[0], {configurable: false, enumerable: true, get: function() { return " + (name + "[i[1]]") + "; }});" +
72+
"});";
73+
} else if(items.length === 1) {
74+
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]) + "]") + "; }});";
75+
} else content = "/* unused harmony namespace reexport */";
76+
} else if(dep.originModule.usedExports) {
77+
var activeExports = HarmonyModulesHelpers.getActiveExports(dep.originModule);
78+
content = "/* harmony namespace reexport */ for(var __WEBPACK_IMPORT_KEY__ in " + name + ") ";
6379

6480
// Filter out exports which are defined by other exports
6581
// and filter out default export because it cannot be reexported with *

lib/dependencies/HarmonyExportSpecifierDependency.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ HarmonyExportSpecifierDependency.Template.prototype.apply = function(dep, source
3737
} else if(!active) {
3838
content = "/* inactive harmony export " + (dep.name || "namespace") + " */";
3939
} else if(dep.immutable) {
40-
content = "/* harmony export */ exports[" + JSON.stringify(dep.name) + "] = " + dep.id + ";";
40+
content = "/* harmony export */ exports[" + JSON.stringify(used) + "] = " + dep.id + ";";
4141
} else {
42-
content = "/* harmony export */ Object.defineProperty(exports, " + JSON.stringify(dep.name) + ", {configurable: false, enumerable: true, get: function() { return " + dep.id + "; }});";
42+
content = "/* harmony export */ Object.defineProperty(exports, " + JSON.stringify(used) + ", {configurable: false, enumerable: true, get: function() { return " + dep.id + "; }});";
4343
}
4444
source.insert(dep.position, content);
4545

lib/dependencies/HarmonyImportSpecifierDependency.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ HarmonyImportSpecifierDependency.Template.prototype.apply = function(dep, source
3333
if(dep.id === "default" && !(dep.importDependency.module.meta && dep.importDependency.module.meta.harmonyModule)) {
3434
content = "/* harmony import */ " + dep.importedVar + "_default.a";
3535
} else if(dep.id) {
36-
content = "/* harmony import */ " + dep.importedVar + "[" + JSON.stringify(dep.id) + "]";
36+
var used = dep.importDependency.module.isUsed(dep.id);
37+
content = "/* harmony import */ " + dep.importedVar + "[" + JSON.stringify(used) + "]";
3738
} else {
3839
content = "/* harmony namespace import */ " + dep.importedVar;
3940
}

lib/dependencies/HarmonyModulesHelpers.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,14 @@ HarmonyModulesHelpers.getActiveExports = function(module) {
6767
}, [])
6868
};
6969

70+
HarmonyModulesHelpers.isExportedByHarmony = function(module, exportedName) {
71+
return module.dependencies.some(function(dep) {
72+
if(!dep.describeHarmonyExport) return false;
73+
var d = dep.describeHarmonyExport();
74+
if(!d) return false;
75+
var name = d.exportedName;
76+
if(!name) return true; // namespace export
77+
return name === exportedName; // direct export
78+
}, [])
79+
};
80+

0 commit comments

Comments
 (0)