mirror of https://github.com/webpack/webpack.git
Merge pull request #14291 from webpack/feature/eval-bailouzt
avoid bailout of unused eval
This commit is contained in:
commit
aa83e463c5
|
@ -28,7 +28,12 @@ class JavascriptMetaInfoPlugin {
|
||||||
parser.hooks.call.for("eval").tap("JavascriptMetaInfoPlugin", () => {
|
parser.hooks.call.for("eval").tap("JavascriptMetaInfoPlugin", () => {
|
||||||
parser.state.module.buildInfo.moduleConcatenationBailout = "eval()";
|
parser.state.module.buildInfo.moduleConcatenationBailout = "eval()";
|
||||||
parser.state.module.buildInfo.usingEval = true;
|
parser.state.module.buildInfo.usingEval = true;
|
||||||
InnerGraph.bailout(parser.state);
|
const currentSymbol = InnerGraph.getTopLevelSymbol(parser.state);
|
||||||
|
if (currentSymbol) {
|
||||||
|
InnerGraph.addUsage(parser.state, null, currentSymbol);
|
||||||
|
} else {
|
||||||
|
InnerGraph.bailout(parser.state);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
parser.hooks.finish.tap("JavascriptMetaInfoPlugin", () => {
|
parser.hooks.finish.tap("JavascriptMetaInfoPlugin", () => {
|
||||||
let topLevelDeclarations =
|
let topLevelDeclarations =
|
||||||
|
|
|
@ -394,6 +394,9 @@ module.exports = mergeExports(fn, {
|
||||||
"DEP_WEBPACK_AGGRESSIVE_SPLITTING_PLUGIN"
|
"DEP_WEBPACK_AGGRESSIVE_SPLITTING_PLUGIN"
|
||||||
)();
|
)();
|
||||||
},
|
},
|
||||||
|
get InnerGraph() {
|
||||||
|
return require("./optimize/InnerGraph");
|
||||||
|
},
|
||||||
get LimitChunkCountPlugin() {
|
get LimitChunkCountPlugin() {
|
||||||
return require("./optimize/LimitChunkCountPlugin");
|
return require("./optimize/LimitChunkCountPlugin");
|
||||||
},
|
},
|
||||||
|
@ -535,6 +538,9 @@ module.exports = mergeExports(fn, {
|
||||||
get comparators() {
|
get comparators() {
|
||||||
return require("./util/comparators");
|
return require("./util/comparators");
|
||||||
},
|
},
|
||||||
|
get runtime() {
|
||||||
|
return require("./util/runtime");
|
||||||
|
},
|
||||||
get serialization() {
|
get serialization() {
|
||||||
return require("./util/serialization");
|
return require("./util/serialization");
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,7 @@ const { UsageState } = require("../ExportsInfo");
|
||||||
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
||||||
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
||||||
|
|
||||||
/** @typedef {Map<TopLevelSymbol, Set<string | TopLevelSymbol> | true>} InnerGraph */
|
/** @typedef {Map<TopLevelSymbol | null, Set<string | TopLevelSymbol> | true>} InnerGraph */
|
||||||
/** @typedef {function(boolean | Set<string> | undefined): void} UsageCallback */
|
/** @typedef {function(boolean | Set<string> | undefined): void} UsageCallback */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +75,7 @@ exports.isEnabled = parserState => {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ParserState} state parser state
|
* @param {ParserState} state parser state
|
||||||
* @param {TopLevelSymbol} symbol the symbol
|
* @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols
|
||||||
* @param {string | TopLevelSymbol | true} usage usage data
|
* @param {string | TopLevelSymbol | true} usage usage data
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
|
@ -172,6 +172,26 @@ exports.inferDependencyUsage = state => {
|
||||||
}
|
}
|
||||||
if (isTerminal) {
|
if (isTerminal) {
|
||||||
nonTerminal.delete(key);
|
nonTerminal.delete(key);
|
||||||
|
|
||||||
|
// For the global key, merge with all other keys
|
||||||
|
if (key === null) {
|
||||||
|
const globalValue = innerGraph.get(null);
|
||||||
|
if (globalValue) {
|
||||||
|
for (const [key, value] of innerGraph) {
|
||||||
|
if (key !== null && value !== true) {
|
||||||
|
if (globalValue === true) {
|
||||||
|
innerGraph.set(key, true);
|
||||||
|
} else {
|
||||||
|
const newSet = new Set(value);
|
||||||
|
for (const item of globalValue) {
|
||||||
|
newSet.add(item);
|
||||||
|
}
|
||||||
|
innerGraph.set(key, newSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { a, b, c } from "./test";
|
||||||
|
|
||||||
|
export function x() {
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function y() {
|
||||||
|
b();
|
||||||
|
eval("x()");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function z() {
|
||||||
|
c();
|
||||||
|
y();
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
const createTestCases = require("../_helpers/createTestCases");
|
||||||
|
module.exports = createTestCases({
|
||||||
|
nothing: {
|
||||||
|
usedExports: [],
|
||||||
|
expect: {
|
||||||
|
"./test": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nonEval: {
|
||||||
|
usedExports: ["x"],
|
||||||
|
expect: {
|
||||||
|
"./test": ["a"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
directEval: {
|
||||||
|
usedExports: ["y"],
|
||||||
|
expect: {
|
||||||
|
"./test": ["a", "b", "c"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
indirectEval: {
|
||||||
|
usedExports: ["z"],
|
||||||
|
expect: {
|
||||||
|
"./test": ["a", "b", "c"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -9783,6 +9783,7 @@ declare class RuntimeChunkPlugin {
|
||||||
*/
|
*/
|
||||||
apply(compiler: Compiler): void;
|
apply(compiler: Compiler): void;
|
||||||
}
|
}
|
||||||
|
type RuntimeCondition = undefined | string | boolean | SortableSet<string>;
|
||||||
declare class RuntimeModule extends Module {
|
declare class RuntimeModule extends Module {
|
||||||
constructor(name: string, stage?: number);
|
constructor(name: string, stage?: number);
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -9829,7 +9830,8 @@ declare interface RuntimeRequirementsContext {
|
||||||
codeGenerationResults: CodeGenerationResults;
|
codeGenerationResults: CodeGenerationResults;
|
||||||
}
|
}
|
||||||
type RuntimeSpec = undefined | string | SortableSet<string>;
|
type RuntimeSpec = undefined | string | SortableSet<string>;
|
||||||
declare abstract class RuntimeSpecMap<T> {
|
declare class RuntimeSpecMap<T> {
|
||||||
|
constructor(clone?: RuntimeSpecMap<T>);
|
||||||
get(runtime: RuntimeSpec): T;
|
get(runtime: RuntimeSpec): T;
|
||||||
has(runtime: RuntimeSpec): boolean;
|
has(runtime: RuntimeSpec): boolean;
|
||||||
set(runtime?: any, value?: any): void;
|
set(runtime?: any, value?: any): void;
|
||||||
|
@ -9840,7 +9842,8 @@ declare abstract class RuntimeSpecMap<T> {
|
||||||
values(): IterableIterator<T>;
|
values(): IterableIterator<T>;
|
||||||
readonly size?: number;
|
readonly size?: number;
|
||||||
}
|
}
|
||||||
declare abstract class RuntimeSpecSet {
|
declare class RuntimeSpecSet {
|
||||||
|
constructor(iterable?: any);
|
||||||
add(runtime?: any): void;
|
add(runtime?: any): void;
|
||||||
has(runtime?: any): boolean;
|
has(runtime?: any): boolean;
|
||||||
[Symbol.iterator](): IterableIterator<RuntimeSpec>;
|
[Symbol.iterator](): IterableIterator<RuntimeSpec>;
|
||||||
|
@ -11299,6 +11302,10 @@ declare interface TimestampAndHash {
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
hash: string;
|
hash: string;
|
||||||
}
|
}
|
||||||
|
declare class TopLevelSymbol {
|
||||||
|
constructor(name: string);
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a Trusted Types policy to create urls for chunks.
|
* Use a Trusted Types policy to create urls for chunks.
|
||||||
|
@ -12155,6 +12162,52 @@ declare namespace exports {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export namespace optimize {
|
export namespace optimize {
|
||||||
|
export namespace InnerGraph {
|
||||||
|
export let bailout: (parserState: ParserState) => void;
|
||||||
|
export let enable: (parserState: ParserState) => void;
|
||||||
|
export let isEnabled: (parserState: ParserState) => boolean;
|
||||||
|
export let addUsage: (
|
||||||
|
state: ParserState,
|
||||||
|
symbol: null | TopLevelSymbol,
|
||||||
|
usage: string | true | TopLevelSymbol
|
||||||
|
) => void;
|
||||||
|
export let addVariableUsage: (
|
||||||
|
parser: JavascriptParser,
|
||||||
|
name: string,
|
||||||
|
usage: string | true | TopLevelSymbol
|
||||||
|
) => void;
|
||||||
|
export let inferDependencyUsage: (state: ParserState) => void;
|
||||||
|
export let onUsage: (
|
||||||
|
state: ParserState,
|
||||||
|
onUsageCallback: (arg0?: boolean | Set<string>) => void
|
||||||
|
) => void;
|
||||||
|
export let setTopLevelSymbol: (
|
||||||
|
state: ParserState,
|
||||||
|
symbol: TopLevelSymbol
|
||||||
|
) => void;
|
||||||
|
export let getTopLevelSymbol: (
|
||||||
|
state: ParserState
|
||||||
|
) => void | TopLevelSymbol;
|
||||||
|
export let tagTopLevelSymbol: (
|
||||||
|
parser: JavascriptParser,
|
||||||
|
name: string
|
||||||
|
) => TopLevelSymbol;
|
||||||
|
export let isDependencyUsedByExports: (
|
||||||
|
dependency: Dependency,
|
||||||
|
usedByExports: boolean | Set<string>,
|
||||||
|
moduleGraph: ModuleGraph,
|
||||||
|
runtime: RuntimeSpec
|
||||||
|
) => boolean;
|
||||||
|
export let getDependencyUsedByExportsCondition: (
|
||||||
|
dependency: Dependency,
|
||||||
|
usedByExports: boolean | Set<string>,
|
||||||
|
moduleGraph: ModuleGraph
|
||||||
|
) =>
|
||||||
|
| null
|
||||||
|
| false
|
||||||
|
| ((arg0: ModuleGraphConnection, arg1: RuntimeSpec) => ConnectionState);
|
||||||
|
export { TopLevelSymbol, topLevelSymbolTag };
|
||||||
|
}
|
||||||
export {
|
export {
|
||||||
AggressiveMergingPlugin,
|
AggressiveMergingPlugin,
|
||||||
AggressiveSplittingPlugin,
|
AggressiveSplittingPlugin,
|
||||||
|
@ -12280,6 +12333,59 @@ declare namespace exports {
|
||||||
b: DependencyLocation
|
b: DependencyLocation
|
||||||
) => 0 | 1 | -1;
|
) => 0 | 1 | -1;
|
||||||
}
|
}
|
||||||
|
export namespace runtime {
|
||||||
|
export let getEntryRuntime: (
|
||||||
|
compilation: Compilation,
|
||||||
|
name: string,
|
||||||
|
options?: EntryOptions
|
||||||
|
) => RuntimeSpec;
|
||||||
|
export let forEachRuntime: (
|
||||||
|
runtime: RuntimeSpec,
|
||||||
|
fn: (arg0: string) => void,
|
||||||
|
deterministicOrder?: boolean
|
||||||
|
) => void;
|
||||||
|
export let getRuntimeKey: (runtime: RuntimeSpec) => string;
|
||||||
|
export let keyToRuntime: (key: string) => RuntimeSpec;
|
||||||
|
export let runtimeToString: (runtime: RuntimeSpec) => string;
|
||||||
|
export let runtimeConditionToString: (
|
||||||
|
runtimeCondition: RuntimeCondition
|
||||||
|
) => string;
|
||||||
|
export let runtimeEqual: (a: RuntimeSpec, b: RuntimeSpec) => boolean;
|
||||||
|
export let compareRuntime: (a: RuntimeSpec, b: RuntimeSpec) => 0 | 1 | -1;
|
||||||
|
export let mergeRuntime: (a: RuntimeSpec, b: RuntimeSpec) => RuntimeSpec;
|
||||||
|
export let mergeRuntimeCondition: (
|
||||||
|
a: RuntimeCondition,
|
||||||
|
b: RuntimeCondition,
|
||||||
|
runtime: RuntimeSpec
|
||||||
|
) => RuntimeCondition;
|
||||||
|
export let mergeRuntimeConditionNonFalse: (
|
||||||
|
a: undefined | string | true | SortableSet<string>,
|
||||||
|
b: undefined | string | true | SortableSet<string>,
|
||||||
|
runtime: RuntimeSpec
|
||||||
|
) => undefined | string | true | SortableSet<string>;
|
||||||
|
export let mergeRuntimeOwned: (
|
||||||
|
a: RuntimeSpec,
|
||||||
|
b: RuntimeSpec
|
||||||
|
) => RuntimeSpec;
|
||||||
|
export let intersectRuntime: (
|
||||||
|
a: RuntimeSpec,
|
||||||
|
b: RuntimeSpec
|
||||||
|
) => RuntimeSpec;
|
||||||
|
export let subtractRuntime: (
|
||||||
|
a: RuntimeSpec,
|
||||||
|
b: RuntimeSpec
|
||||||
|
) => RuntimeSpec;
|
||||||
|
export let subtractRuntimeCondition: (
|
||||||
|
a: RuntimeCondition,
|
||||||
|
b: RuntimeCondition,
|
||||||
|
runtime: RuntimeSpec
|
||||||
|
) => RuntimeCondition;
|
||||||
|
export let filterRuntime: (
|
||||||
|
runtime: RuntimeSpec,
|
||||||
|
filter: (arg0: RuntimeSpec) => boolean
|
||||||
|
) => undefined | string | boolean | SortableSet<string>;
|
||||||
|
export { RuntimeSpecMap, RuntimeSpecSet };
|
||||||
|
}
|
||||||
export namespace serialization {
|
export namespace serialization {
|
||||||
export const register: (
|
export const register: (
|
||||||
Constructor: Constructor,
|
Constructor: Constructor,
|
||||||
|
@ -12425,5 +12531,6 @@ declare namespace exports {
|
||||||
LoaderContext
|
LoaderContext
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
declare const topLevelSymbolTag: unique symbol;
|
||||||
|
|
||||||
export = exports;
|
export = exports;
|
||||||
|
|
Loading…
Reference in New Issue