fix: should count in module scope variables

This commit is contained in:
fi3ework 2024-04-24 23:51:33 +08:00
parent c586c7b1e0
commit 1234b1f27b
7 changed files with 51 additions and 40 deletions

View File

@ -822,7 +822,7 @@ class JavascriptModulesPlugin {
const lastInlinedModule = last(inlinedModules);
const startupSource = new ConcatSource();
startupSource.add(`var ${RuntimeGlobals.exports} = {};\n`);
const renamedInlinedModules = this.renamedRootModule(
const renamedInlinedModule = this.renameInlineModule(
allModules,
renderContext,
inlinedModules,
@ -832,7 +832,7 @@ class JavascriptModulesPlugin {
for (const m of inlinedModules) {
const renderedModule =
renamedInlinedModules.get(m) ||
renamedInlinedModule.get(m) ||
this.renderModule(m, chunkRenderContext, hooks, false);
if (renderedModule) {
@ -1400,7 +1400,7 @@ class JavascriptModulesPlugin {
* @param {CompilationHooks} hooks hooks
* @returns {Map<Module, Source>} renamed inlined modules
*/
renamedRootModule(
renameInlineModule(
allModules,
renderContext,
inlinedModules,
@ -1409,14 +1409,12 @@ class JavascriptModulesPlugin {
) {
const { runtimeTemplate } = renderContext;
/** @type {Map<Module, { source: Source, ast: any, variables: Set<Variable> }>} */
/** @type {Map<Module, { source: Source, ast: any, variables: Set<Variable>, usedInNonInlined: Set<Variable>}>} */
const inlinedModulesToInfo = new Map();
/** @type {Set<string>} */
const nonInlinedModuleThroughIdentifiers = new Set();
/** @type {Map<Module, Source>} */
const renamedInlinedModules = new Map();
/** @type {Set<{ m: Module, variable: Variable}>} */
const usedIdentifiers = new Set();
for (const m of allModules) {
const isInlinedModule = inlinedModules && inlinedModules.has(m);
@ -1443,11 +1441,12 @@ class JavascriptModulesPlugin {
const globalScope = scopeManager.acquire(ast);
if (inlinedModules && inlinedModules.has(m)) {
const moduleScope = globalScope.childScopes[0];
const variables = new Set();
for (const variable of moduleScope.variables) {
variables.add(variable);
}
inlinedModulesToInfo.set(m, { source: moduleSource, ast, variables });
inlinedModulesToInfo.set(m, {
source: moduleSource,
ast,
variables: new Set(moduleScope.variables),
usedInNonInlined: new Set()
});
} else {
for (const ref of globalScope.through) {
nonInlinedModuleThroughIdentifiers.add(ref.identifier.name);
@ -1455,43 +1454,53 @@ class JavascriptModulesPlugin {
}
}
for (const [module, { variables }] of inlinedModulesToInfo) {
for (const [, { variables, usedInNonInlined }] of inlinedModulesToInfo) {
for (const variable of variables) {
if (nonInlinedModuleThroughIdentifiers.has(variable.name)) {
usedIdentifiers.add({ m: module, variable });
usedInNonInlined.add(variable);
}
}
}
const usedName = new Set();
for (const { variable, m } of usedIdentifiers) {
const references = getAllReferences(variable);
const { ast, source: _source } = inlinedModulesToInfo.get(m);
for (const [m, moduleInfo] of inlinedModulesToInfo) {
const { ast, source: _source, usedInNonInlined } = moduleInfo;
const source = new ReplaceSource(_source);
const allIdentifiers = new Set(
references.map(r => r.identifier).concat(variable.identifiers)
if (usedInNonInlined.size === 0) {
renamedInlinedModules.set(m, source);
continue;
}
const usedNames = new Set(
Array.from(inlinedModulesToInfo.get(m).variables).map(v => v.name)
);
const newName = this.findNewName(
variable.name,
usedName,
m.readableIdentifier(runtimeTemplate.requestShortener)
);
for (const variable of usedInNonInlined) {
const references = getAllReferences(variable);
const allIdentifiers = new Set(
references.map(r => r.identifier).concat(variable.identifiers)
);
for (const identifier of allIdentifiers) {
const r = identifier.range;
const path = getPathInAst(ast, identifier);
if (path && path.length > 1) {
const maybeProperty =
path[1].type === "AssignmentPattern" && path[1].left === path[0]
? path[2]
: path[1];
if (maybeProperty.type === "Property" && maybeProperty.shorthand) {
source.insert(r[1], `: ${newName}`);
continue;
const newName = this.findNewName(
variable.name,
usedNames,
m.readableIdentifier(runtimeTemplate.requestShortener)
);
usedNames.add(newName);
for (const identifier of allIdentifiers) {
const r = identifier.range;
const path = getPathInAst(ast, identifier);
if (path && path.length > 1) {
const maybeProperty =
path[1].type === "AssignmentPattern" && path[1].left === path[0]
? path[2]
: path[1];
if (maybeProperty.type === "Property" && maybeProperty.shorthand) {
source.insert(r[1], `: ${newName}`);
continue;
}
}
source.replace(r[0], r[1] - 1, newName);
}
source.replace(r[0], r[1] - 1, newName);
}
renamedInlinedModules.set(m, source);
@ -1524,10 +1533,10 @@ class JavascriptModulesPlugin {
}
let i = 0;
let nameWithNumber = Template.toIdentifier(`${oldName}_${i}`);
let nameWithNumber = Template.toIdentifier(`${name}_${i}`);
while (usedName.has(nameWithNumber)) {
i++;
nameWithNumber = Template.toIdentifier(`${oldName}_${i}`);
nameWithNumber = Template.toIdentifier(`${name}_${i}`);
}
return nameWithNumber;
}

View File

@ -2,7 +2,8 @@ import { value as v1 } from "./module1";
const v2 = require("./module2")
const module3Inc = require("./module3")
var value = 42;
const index_value = 10;
let value = 42;
function inc() {
value++;
@ -15,4 +16,5 @@ it("single inlined module should not be wrapped in IIFE", () => {
expect(module3Inc).toBe(undefined);
inc();
expect(value).toBe(43);
expect(index_value).toBe(10);
});

2
types.d.ts vendored
View File

@ -5529,7 +5529,7 @@ declare class JavascriptModulesPlugin {
renderContext: RenderBootstrapContext,
hooks: CompilationHooksJavascriptModulesPlugin
): string;
renamedRootModule(
renameInlineModule(
allModules: Module[],
renderContext: MainRenderContext,
inlinedModules: Set<Module>,