Skip to content

Commit 53a1d6c

Browse files
committed
replace harmonyModule flag with exportsType 3-state
exportsType falsy: It's non-harmony module exportsType "namespace": It's a harmony module, the exports is the namespace object exportsType "default": It's a harmony module, the exports is the default exports, named exports are properties of the default export
1 parent 2aac6ba commit 53a1d6c

20 files changed

Lines changed: 104 additions & 200 deletions

File tree

‎lib/ContextModule.js‎

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -225,44 +225,56 @@ class ContextModule extends Module {
225225
}
226226

227227
getFakeMap(dependencies) {
228-
if(!this.options.namespaceObject) return false;
228+
if(!this.options.namespaceObject) return 1;
229229
// if we filter first we get a new array
230230
// therefor we dont need to create a clone of dependencies explicitly
231231
// therefore the order of this is !important!
232232
let hasNonHarmony = false;
233-
let hasHarmony = false;
233+
let hasNamespace = false;
234+
let hasNamed = false;
234235
const fakeMap = dependencies
235236
.filter(dependency => dependency.module)
236237
.sort((a, b) => {
237238
return b.module.id - a.module.id;
238239
}).reduce((map, dep) => {
239-
const harmonyModule = dep.module.buildMeta && dep.module.buildMeta.harmonyModule;
240-
if(!harmonyModule) hasNonHarmony = true;
241-
if(harmonyModule) hasHarmony = true;
242-
map[dep.module.id] = harmonyModule ? 1 : 0;
240+
const exportsType = dep.module.buildMeta && dep.module.buildMeta.exportsType;
241+
if(!exportsType) hasNonHarmony = true;
242+
if(exportsType === "namespace") hasNamespace = true;
243+
if(exportsType === "named") hasNamed = true;
244+
map[dep.module.id] = {
245+
namespace: 1,
246+
named: 2
247+
}[exportsType] || 0;
243248
return map;
244249
}, Object.create(null));
245-
if(hasHarmony && !hasNonHarmony) return false;
246-
if(!hasHarmony && hasNonHarmony) return true;
250+
if(!hasNamespace && hasNonHarmony && !hasNamed) return 0;
251+
if(hasNamespace && !hasNonHarmony && !hasNamed) return 1;
252+
if(!hasNamespace && !hasNonHarmony && hasNamed) return 2;
253+
if(!hasNamespace && !hasNonHarmony && !hasNamed) return 1;
247254
return fakeMap;
248255
}
249256

250-
getModuleObjectSource(fakeMap, fakeMapDataExpression = "fakeMap[id]") {
257+
getReturnModuleObjectSource(fakeMap, fakeMapDataExpression = "fakeMap[id]") {
251258
const strict = this.options.namespaceObject === "strict";
252-
if(strict) {
253-
if(fakeMap === true) return "/* fake namespace object */ { \"default\": module }";
254-
if(fakeMap) return `${fakeMapDataExpression} ? module : /* fake namespace object */ { "default": module }`;
255-
} else {
256-
if(fakeMap === true) return "typeof module === \"object\" && module && module.__esModule ? module : /* fake namespace object */ { \"default\": module };";
257-
if(fakeMap) return `${fakeMapDataExpression} || typeof module === "object" && module && module.__esModule ? module : /* fake namespace object */ { "default": module };`;
258-
}
259-
return "module";
259+
const getReturn = type => {
260+
if(type === 1) return "module";
261+
if(type === 2) return "Object.assign({/* fake namespace object */}, module, { \"default\": module })";
262+
if(type === 0) {
263+
if(strict) {
264+
return "/* fake namespace object */ { \"default\": module }";
265+
} else {
266+
return "(typeof module === \"object\" && module && module.__esModule ? module : /* fake namespace object */ { \"default\": module })";
267+
}
268+
}
269+
};
270+
if(typeof fakeMap === "number") return `return ${getReturn(fakeMap)};`;
271+
return `return ${fakeMapDataExpression} === 1 ? ${getReturn(1)} : ${fakeMapDataExpression} ? ${getReturn(2)} : ${getReturn(0)};`;
260272
}
261273

262274
getSyncSource(dependencies, id) {
263275
const map = this.getUserRequestMap(dependencies);
264276
const fakeMap = this.getFakeMap(dependencies);
265-
const returnModuleObject = `return ${this.getModuleObjectSource(fakeMap)};`;
277+
const returnModuleObject = `${this.getReturnModuleObjectSource(fakeMap)};`;
266278

267279
return `var map = ${JSON.stringify(map, null, "\t")};
268280
${typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};` : ""}
@@ -292,7 +304,7 @@ webpackContext.id = ${JSON.stringify(id)};`;
292304
getWeakSyncSource(dependencies, id) {
293305
const map = this.getUserRequestMap(dependencies);
294306
const fakeMap = this.getFakeMap(dependencies);
295-
const returnModuleObject = `return ${this.getModuleObjectSource(fakeMap)};`;
307+
const returnModuleObject = `${this.getReturnModuleObjectSource(fakeMap)};`;
296308

297309
return `var map = ${JSON.stringify(map, null, "\t")};
298310
${typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};` : ""}
@@ -327,7 +339,7 @@ module.exports = webpackContext;`;
327339
getAsyncWeakSource(dependencies, id) {
328340
const map = this.getUserRequestMap(dependencies);
329341
const fakeMap = this.getFakeMap(dependencies);
330-
const returnModuleObject = `return ${this.getModuleObjectSource(fakeMap)};`;
342+
const returnModuleObject = `${this.getReturnModuleObjectSource(fakeMap)};`;
331343

332344
return `var map = ${JSON.stringify(map, null, "\t")};
333345
${typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};` : ""}
@@ -367,10 +379,10 @@ module.exports = webpackAsyncContext;`;
367379
getEagerSource(dependencies, id) {
368380
const map = this.getUserRequestMap(dependencies);
369381
const fakeMap = this.getFakeMap(dependencies);
370-
const thenFunction = fakeMap ?
382+
const thenFunction = fakeMap !== 1 ?
371383
`function(id) {
372384
var module = __webpack_require__(id);
373-
return ${this.getModuleObjectSource(fakeMap)};
385+
${this.getReturnModuleObjectSource(fakeMap)};
374386
}` :
375387
"__webpack_require__";
376388
return `var map = ${JSON.stringify(map, null, "\t")};
@@ -407,10 +419,10 @@ module.exports = webpackAsyncContext;`;
407419
});
408420
const map = this.getUserRequestMap(dependencies);
409421
const fakeMap = this.getFakeMap(dependencies);
410-
const thenFunction = fakeMap ?
422+
const thenFunction = fakeMap !== 1 ?
411423
`function(id) {
412424
var module = __webpack_require__(id);
413-
return ${this.getModuleObjectSource(fakeMap)};
425+
${this.getReturnModuleObjectSource(fakeMap)};
414426
}` :
415427
"__webpack_require__";
416428

@@ -469,7 +481,7 @@ module.exports = webpackAsyncContext;`;
469481
const requestPrefix = hasMultipleOrNoChunks ?
470482
`Promise.all(ids.slice(${chunksStartPosition}).map(__webpack_require__.e))` :
471483
`__webpack_require__.e(ids[${chunksStartPosition}])`;
472-
const returnModuleObject = `return ${this.getModuleObjectSource(fakeMap, "ids[1]")};`;
484+
const returnModuleObject = `${this.getReturnModuleObjectSource(fakeMap, "ids[1]")};`;
473485

474486
return `var map = ${JSON.stringify(map, null, "\t")};
475487
function webpackAsyncContext(req) {

‎lib/FlagDependencyExportsPlugin.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class FlagDependencyExportsPlugin {
105105
module = queue.dequeue();
106106

107107
if(module.buildMeta.providedExports !== true) {
108-
moduleWithExports = module.buildMeta && module.buildMeta.harmonyModule;
108+
moduleWithExports = module.buildMeta && module.buildMeta.exportsType;
109109
moduleProvidedExports = Array.isArray(module.buildMeta.providedExports) ? new Set(module.buildMeta.providedExports) : new Set();
110110
processDependenciesBlock(module);
111111
if(!moduleWithExports) {

‎lib/Module.js‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,14 @@ class Module extends DependenciesBlock {
248248
if(this.usedExports === true) return exportName;
249249
let idx = this.usedExports.indexOf(exportName);
250250
if(idx < 0) return false;
251-
if(this.isProvided(exportName))
252-
return Template.numberToIdentifer(idx);
251+
252+
// Mangle export name if possible
253+
if(this.isProvided(exportName)) {
254+
if(this.buildMeta.exportsType === "namespace")
255+
return Template.numberToIdentifer(idx);
256+
else if(this.buildMeta.exportsType === "named" && this.usedExports.indexOf("default") < 0)
257+
return Template.numberToIdentifer(idx);
258+
}
253259
return exportName;
254260
}
255261

‎lib/NodeStuffPlugin.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ class NodeStuffPlugin {
7777
});
7878
parser.hooks.expression.for("module.exports").tap("NodeStuffPlugin", () => {
7979
const module = parser.state.module;
80-
const isHarmony = module.buildMeta && module.buildMeta.harmonyModule;
80+
const isHarmony = module.buildMeta && module.buildMeta.exportsType;
8181
if(!isHarmony)
8282
return true;
8383
});
8484
parser.hooks.evaluateIdentifier.for("module.hot").tap("NodeStuffPlugin", ParserHelpers.evaluateToIdentifier("module.hot", false));
8585
parser.hooks.expression.for("module").tap("NodeStuffPlugin", () => {
8686
const module = parser.state.module;
87-
const isHarmony = module.buildMeta && module.buildMeta.harmonyModule;
87+
const isHarmony = module.buildMeta && module.buildMeta.exportsType;
8888
let moduleJsPath = path.join(__dirname, "..", "buildin", isHarmony ? "harmony-module.js" : "module.js");
8989
if(module.context) {
9090
moduleJsPath = path.relative(parser.state.module.context, moduleJsPath);

‎lib/RuntimeTemplate.js‎

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,11 @@ module.exports = class RuntimeTemplate {
9797
module,
9898
request
9999
});
100-
if(module.buildMeta && module.buildMeta.harmonyModule) {
100+
const exportsType = module.buildMeta && module.buildMeta.exportsType;
101+
if(exportsType === "namespace") {
101102
return rawModule;
103+
} else if(exportsType === "named") {
104+
return `Object.assign({/* fake namespace object */}, ${rawModule}, { "default": ${rawModule} })`;
102105
} else if(strict) {
103106
return `Object({ /* fake namespace object */ "default": ${rawModule} })`;
104107
} else {
@@ -139,12 +142,15 @@ module.exports = class RuntimeTemplate {
139142
module,
140143
request
141144
});
142-
if(module.buildMeta && module.buildMeta.harmonyModule) {
145+
const exportsType = module.buildMeta && module.buildMeta.exportsType;
146+
if(exportsType === "namespace") {
143147
if(header) {
144148
getModuleFunction = `function() { ${header}return ${rawModule}; }`;
145149
} else {
146150
getModuleFunction = `__webpack_require__.bind(null, ${comment}${idExpr})`;
147151
}
152+
} else if(exportsType === "named") {
153+
getModuleFunction = `function() { ${header}var module = ${rawModule}; return Object.assign({/* fake namespace object */}, module, { "default": module }); }`;
148154
} else if(strict) {
149155
getModuleFunction = `function() { ${header}return { /* fake namespace object */ "default": ${rawModule} }; }`;
150156
} else {
@@ -169,12 +175,19 @@ module.exports = class RuntimeTemplate {
169175
});
170176
const optDeclaration = update ? "" : "var ";
171177

172-
const isHarmonyModule = module.buildMeta && module.buildMeta.harmonyModule;
173-
const content = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${comment}${JSON.stringify(module.id)});\n`;
174-
if(isHarmonyModule || originModule.buildMeta.strictHarmonyModule) {
175-
return content;
178+
const exportsType = module.buildMeta && module.buildMeta.exportsType;
179+
let content = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${comment}${JSON.stringify(module.id)});\n`;
180+
181+
if(!exportsType && !originModule.buildMeta.strictHarmonyModule) {
182+
content += `/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/__webpack_require__.n(${importVar});\n`;
183+
}
184+
if(exportsType === "named") {
185+
if(Array.isArray(module.buildMeta.providedExports))
186+
content += `${optDeclaration}${importVar}_namespace = /*#__PURE__*/Object.assign({}, ${importVar}, {"default": ${importVar}});\n`;
187+
else
188+
content += `${optDeclaration}${importVar}_namespace = /*#__PURE__*/{ /* fake namespace object */ "default": ${importVar} };\n`;
176189
}
177-
return `${content}/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/__webpack_require__.n(${importVar});\n`;
190+
return content;
178191
}
179192

180193
exportFromImport({
@@ -186,9 +199,9 @@ module.exports = class RuntimeTemplate {
186199
callContext,
187200
importVar
188201
}) {
189-
const isHarmonyModule = module.buildMeta && module.buildMeta.harmonyModule;
202+
const exportsType = module.buildMeta && module.buildMeta.exportsType;
190203

191-
if(!isHarmonyModule) {
204+
if(!exportsType) {
192205
if(exportName === "default") {
193206
if(!originModule.buildMeta.strictHarmonyModule) {
194207
if(isCall)
@@ -205,14 +218,22 @@ module.exports = class RuntimeTemplate {
205218
return "/* non-default import from non-esm module */undefined";
206219
} else if(!exportName) {
207220
if(asiSafe) {
208-
return `{ /* fake namespace object */ "default": ${importVar} }`;
221+
return `/*#__PURE__*/{ /* fake namespace object */ "default": ${importVar} }`;
209222
} else {
210-
return `Object({ /* fake namespace object */ "default": ${importVar} })`;
223+
return `/*#__PURE__*/Object({ /* fake namespace object */ "default": ${importVar} })`;
211224
}
212225
}
213226
}
214227
}
215228

229+
if(exportsType === "named") {
230+
if(exportName === "default") {
231+
return importVar;
232+
} else if(!exportName) {
233+
return `${importVar}_namespace`;
234+
}
235+
}
236+
216237
if(exportName) {
217238
const used = module.isUsed(exportName);
218239
const comment = used !== exportName ? Template.toNormalComment(exportName) + " " : "";

‎lib/WebAssemblyParser.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class WebAssemblyParser extends Tapable {
2222
// TODO extract imports
2323

2424
// flag it as ESM
25-
state.module.buildMeta.harmonyModule = true;
25+
state.module.buildMeta.exportsType = "namespace";
2626

2727
// extract exports
2828
// TODO find more efficient way doing it

‎lib/dependencies/HarmonyDetectionParserPlugin.js‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module.exports = class HarmonyDetectionParserPlugin {
4343
};
4444
module.addDependency(initDep);
4545
parser.state.harmonyParserScope = parser.state.harmonyParserScope || {};
46-
module.buildMeta.harmonyModule = true;
46+
module.buildMeta.exportsType = "namespace";
4747
module.buildInfo.strict = true;
4848
module.buildInfo.exportsArgument = "__webpack_exports__";
4949
if(isStrictHarmony) {
@@ -55,13 +55,13 @@ module.exports = class HarmonyDetectionParserPlugin {
5555

5656
const skipInHarmony = () => {
5757
const module = parser.state.module;
58-
if(module && module.buildMeta && module.buildMeta.harmonyModule)
58+
if(module && module.buildMeta && module.buildMeta.exportsType)
5959
return true;
6060
};
6161

6262
const nullInHarmony = () => {
6363
const module = parser.state.module;
64-
if(module && module.buildMeta && module.buildMeta.harmonyModule)
64+
if(module && module.buildMeta && module.buildMeta.exportsType)
6565
return null;
6666
};
6767

‎lib/dependencies/HarmonyExportImportedSpecifierDependency.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
4040
};
4141
}
4242

43-
const isNotAHarmonyModule = importedModule.buildMeta && !importedModule.buildMeta.harmonyModule;
43+
const isNotAHarmonyModule = importedModule.buildMeta && !importedModule.buildMeta.exportsType;
4444
const strictHarmonyModule = this.originModule.buildMeta.strictHarmonyModule;
4545
if(name && id === "default" && isNotAHarmonyModule) {
4646
if(strictHarmonyModule) {
@@ -288,7 +288,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
288288
return;
289289
}
290290

291-
if(!importedModule.buildMeta || !importedModule.buildMeta.harmonyModule) {
291+
if(!importedModule.buildMeta || !importedModule.buildMeta.exportsType) {
292292
// It's not an harmony module
293293
if(this.originModule.buildMeta.strictHarmonyModule && this.id !== "default") {
294294
// In strict harmony modules we only support the default export

‎lib/dependencies/HarmonyImportDependency.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class HarmonyImportDependency extends ModuleDependency {
4747
updateHash(hash) {
4848
super.updateHash(hash);
4949
const importedModule = this.module;
50-
hash.update((importedModule && (!importedModule.buildMeta || importedModule.buildMeta.harmonyModule)) + "");
50+
hash.update((importedModule && (!importedModule.buildMeta || importedModule.buildMeta.exportsType)) + "");
5151
hash.update((importedModule && importedModule.id) + "");
5252
}
5353
}

‎lib/dependencies/HarmonyImportSpecifierDependency.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
5050
return;
5151
}
5252

53-
if(!importedModule.buildMeta || !importedModule.buildMeta.harmonyModule) {
53+
if(!importedModule.buildMeta || !importedModule.buildMeta.exportsType) {
5454
// It's not an harmony module
5555
if(this.originModule.buildMeta.strictHarmonyModule && this.id !== "default") {
5656
// In strict harmony modules we only support the default export
@@ -89,7 +89,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
8989
const importedModule = this.module;
9090
hash.update((importedModule && this.id) + "");
9191
hash.update((importedModule && this.id && importedModule.isUsed(this.id)) + "");
92-
hash.update((importedModule && (!importedModule.buildMeta || importedModule.buildMeta.harmonyModule)) + "");
92+
hash.update((importedModule && (!importedModule.buildMeta || importedModule.buildMeta.exportsType)) + "");
9393
hash.update((importedModule && (importedModule.used + JSON.stringify(importedModule.usedExports))) + "");
9494
}
9595
}

0 commit comments

Comments
 (0)