put reexports into the correct init section when possible

fixes #7857
This commit is contained in:
Tobias Koppers 2018-08-08 14:12:54 +02:00
parent 979b6b2ea5
commit 227952c914
5 changed files with 128 additions and 87 deletions

View File

@ -469,14 +469,10 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (dependency);
if (this.isUsed(dep, templateContext)) {
const importFragments = super.getInitFragments(dep, templateContext);
const exportFragment = new InitFragment(
this.getContent(
dep,
templateContext.module,
templateContext.moduleGraph
),
InitFragment.STAGE_HARMONY_IMPORTS,
dep.sourceOrder
const exportFragment = this._getExportFragment(
dep,
templateContext.module,
templateContext.moduleGraph
);
return importFragments
? importFragments.concat(exportFragment)
@ -533,122 +529,152 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
* @param {HarmonyExportImportedSpecifierDependency} dep dependency
* @param {Module} module the current module
* @param {ModuleGraph} moduleGraph the module graph
* @returns {string} the generated code
* @returns {InitFragment} the generated init fragment
*/
getContent(dep, module, moduleGraph) {
_getExportFragment(dep, module, moduleGraph) {
const mode = dep.getMode(moduleGraph, false);
const importedModule = moduleGraph.getModule(dep);
const importVar = dep.getImportVar(moduleGraph);
switch (mode.type) {
case "missing":
return `throw new Error(${JSON.stringify(
`Cannot find module '${mode.userRequest}'`
)});\n`;
return new InitFragment(
"/* empty/unused harmony star reexport */\n",
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "unused":
return `${Template.toNormalComment(
`unused harmony reexport ${mode.name}`
)}\n`;
return new InitFragment(
`${Template.toNormalComment(
`unused harmony reexport ${mode.name}`
)}\n`,
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "reexport-non-harmony-default":
return (
return new InitFragment(
"/* harmony reexport (default from non-harmony) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
null
)
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
null
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "reexport-named-default":
return (
return new InitFragment(
"/* harmony reexport (default from named exports) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
)
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "reexport-fake-namespace-object":
return (
return new InitFragment(
"/* harmony reexport (fake namespace object from non-harmony) */ " +
this.getReexportFakeNamespaceObjectStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar
)
this.getReexportFakeNamespaceObjectStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "rexport-non-harmony-undefined":
return (
return new InitFragment(
"/* harmony reexport (non default export from non-harmony) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
"undefined",
""
)
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
"undefined",
""
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "reexport-non-harmony-default-strict":
return (
return new InitFragment(
"/* harmony reexport (default from non-harmony) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
)
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "reexport-namespace-object":
return (
return new InitFragment(
"/* harmony reexport (module object) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
)
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, mode.name),
importVar,
""
),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "empty-star":
return "/* empty/unused harmony star reexport */";
return new InitFragment(
"/* empty/unused harmony star reexport */",
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "safe-reexport":
return Array.from(mode.map.entries())
.map(item => {
return (
"/* harmony reexport (safe) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, item[0]),
importVar,
importedModule.getUsedName(moduleGraph, item[1])
)
);
})
.join("");
return new InitFragment(
Array.from(mode.map.entries())
.map(item => {
return (
"/* harmony reexport (safe) */ " +
this.getReexportStatement(
module,
module.getUsedName(moduleGraph, item[0]),
importVar,
importedModule.getUsedName(moduleGraph, item[1])
)
);
})
.join(""),
InitFragment.STAGE_HARMONY_EXPORTS,
1
);
case "checked-reexport":
return Array.from(mode.map.entries())
.map(item => {
return (
"/* harmony reexport (checked) */ " +
this.getConditionalReexportStatement(
module,
item[0],
importVar,
item[1]
) +
"\n"
);
})
.join("");
return new InitFragment(
Array.from(mode.map.entries())
.map(item => {
return (
"/* harmony reexport (checked) */ " +
this.getConditionalReexportStatement(
module,
item[0],
importVar,
item[1]
) +
"\n"
);
})
.join(""),
InitFragment.STAGE_HARMONY_IMPORTS,
dep.sourceOrder
);
case "dynamic-reexport": {
const activeExports = new Set([
@ -671,9 +697,11 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
content += "if(__WEBPACK_IMPORT_KEY__ !== 'default') ";
}
const exportsName = module.exportsArgument;
return (
return new InitFragment(
content +
`(function(key) { __webpack_require__.d(${exportsName}, key, function() { return ${importVar}[key]; }) }(__WEBPACK_IMPORT_KEY__));\n`
`(function(key) { __webpack_require__.d(${exportsName}, key, function() { return ${importVar}[key]; }) }(__WEBPACK_IMPORT_KEY__));\n`,
InitFragment.STAGE_HARMONY_IMPORTS,
dep.sourceOrder
);
}

View File

@ -0,0 +1,3 @@
import { B } from "./cycle";
export const A = B;

View File

@ -0,0 +1,3 @@
import { A } from "./cycle";
export const B = A;

View File

@ -0,0 +1,2 @@
export { A } from "./a";
export { B } from "./b";

View File

@ -0,0 +1,5 @@
it("should fail with a ReferenceError", () => {
expect(() => {
require("./cycle");
}).toThrow();
});