Framework updates
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1
node_modules/webpack/lib/CleanPlugin.js
generated
vendored
1
node_modules/webpack/lib/CleanPlugin.js
generated
vendored
@@ -369,6 +369,7 @@ class CleanPlugin {
|
||||
/** @param {CleanOptions} options options */
|
||||
constructor(options = {}) {
|
||||
validate(options);
|
||||
/** @type {CleanOptions & { dry: boolean }} */
|
||||
this.options = { dry: false, ...options };
|
||||
}
|
||||
|
||||
|
||||
18
node_modules/webpack/lib/Compilation.js
generated
vendored
18
node_modules/webpack/lib/Compilation.js
generated
vendored
@@ -4019,7 +4019,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
||||
* @param {string | ChunkGroupOptions} groupOptions options for the chunk group
|
||||
* @param {Module=} module the module the references the chunk group
|
||||
* @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module)
|
||||
* @param {string=} request the request from which the the chunk group is referenced
|
||||
* @param {string=} request the request from which the chunk group is referenced
|
||||
* @returns {ChunkGroup} the new or existing chunk group
|
||||
*/
|
||||
addChunkInGroup(groupOptions, module, loc, request) {
|
||||
@@ -4067,7 +4067,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
||||
* @param {EntryOptions} options options for the entrypoint
|
||||
* @param {Module} module the module the references the chunk group
|
||||
* @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module)
|
||||
* @param {string} request the request from which the the chunk group is referenced
|
||||
* @param {string} request the request from which the chunk group is referenced
|
||||
* @returns {Entrypoint} the new or existing entrypoint
|
||||
*/
|
||||
addAsyncEntrypoint(options, module, loc, request) {
|
||||
@@ -4531,12 +4531,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
||||
(e) => e.chunks[e.chunks.length - 1]
|
||||
)
|
||||
)) {
|
||||
const otherInfo =
|
||||
/** @type {RuntimeChunkInfo} */
|
||||
(runtimeChunksMap.get(other));
|
||||
otherInfo.referencedBy.push(info);
|
||||
info.remaining++;
|
||||
remaining++;
|
||||
const otherInfo = runtimeChunksMap.get(other);
|
||||
// other may be a non-runtime chunk (e.g. worker chunk)
|
||||
// when you have a worker chunk in your app.js (new Worker(...)) and as a separate entry point
|
||||
if (otherInfo) {
|
||||
otherInfo.referencedBy.push(info);
|
||||
info.remaining++;
|
||||
remaining++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @type {Chunk[]} */
|
||||
|
||||
22
node_modules/webpack/lib/ContextModule.js
generated
vendored
22
node_modules/webpack/lib/ContextModule.js
generated
vendored
@@ -119,6 +119,7 @@ const makeSerializable = require("./util/makeSerializable");
|
||||
|
||||
/** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
|
||||
/** @typedef {Record<string, ModuleId>} UserRequestMap */
|
||||
/** @typedef {Record<ModuleId, ModuleId[]>} UserRequestsMap */
|
||||
|
||||
class ContextModule extends Module {
|
||||
/**
|
||||
@@ -711,7 +712,7 @@ class ContextModule extends Module {
|
||||
/**
|
||||
* @param {Dependency[]} dependencies all dependencies
|
||||
* @param {ChunkGraph} chunkGraph chunk graph
|
||||
* @returns {Map<string, ModuleId[] | undefined>} map with user requests
|
||||
* @returns {UserRequestsMap} map with user requests
|
||||
*/
|
||||
getModuleDeferredAsyncDepsMap(dependencies, chunkGraph) {
|
||||
const moduleGraph = chunkGraph.moduleGraph;
|
||||
@@ -726,6 +727,7 @@ class ContextModule extends Module {
|
||||
)
|
||||
.filter(Boolean)
|
||||
.sort(comparator);
|
||||
/** @type {UserRequestsMap} */
|
||||
const map = Object.create(null);
|
||||
for (const module of sortedModules) {
|
||||
if (!(/** @type {BuildMeta} */ (module.buildMeta).async)) {
|
||||
@@ -740,7 +742,7 @@ class ContextModule extends Module {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {false | Map<string, ModuleId[] | undefined>} asyncDepsMap fake map
|
||||
* @param {false | UserRequestsMap} asyncDepsMap fake map
|
||||
* @returns {string} async deps map init statement
|
||||
*/
|
||||
getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap) {
|
||||
@@ -1168,12 +1170,16 @@ function webpackAsyncContext(req) {
|
||||
])});
|
||||
}`
|
||||
: `function webpackAsyncContext(req) {
|
||||
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
|
||||
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
|
||||
'var e = new Error("Cannot find module \'" + req + "\'");',
|
||||
"e.code = 'MODULE_NOT_FOUND';",
|
||||
"throw e;"
|
||||
])});
|
||||
try {
|
||||
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
|
||||
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
|
||||
'var e = new Error("Cannot find module \'" + req + "\'");',
|
||||
"e.code = 'MODULE_NOT_FOUND';",
|
||||
"throw e;"
|
||||
])});
|
||||
}
|
||||
} catch(err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
|
||||
var ids = map[req], id = ids[0];
|
||||
|
||||
2
node_modules/webpack/lib/Dependency.js
generated
vendored
2
node_modules/webpack/lib/Dependency.js
generated
vendored
@@ -227,7 +227,7 @@ class Dependency {
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
throw new Error(
|
||||
"Dependency.getReference was removed in favor of Dependency.getReferencedExports, ModuleGraph.getModule and ModuleGraph.getConnection().active"
|
||||
"Dependency.getReference was removed in favor of Dependency.getReferencedExports, ModuleGraph.getModule, ModuleGraph.getConnection(), and ModuleGraphConnection.getActiveState(runtime)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
1
node_modules/webpack/lib/EnvironmentNotSupportAsyncWarning.js
generated
vendored
1
node_modules/webpack/lib/EnvironmentNotSupportAsyncWarning.js
generated
vendored
@@ -26,6 +26,7 @@ As a result, the code may not run as expected or may cause runtime errors.`;
|
||||
|
||||
/** @type {string} */
|
||||
this.name = "EnvironmentNotSupportAsyncWarning";
|
||||
/** @type {Module} */
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
|
||||
3
node_modules/webpack/lib/EvalDevToolModulePlugin.js
generated
vendored
3
node_modules/webpack/lib/EvalDevToolModulePlugin.js
generated
vendored
@@ -43,8 +43,11 @@ class EvalDevToolModulePlugin {
|
||||
* @param {EvalDevToolModulePluginOptions=} options options
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
/** @type {DevtoolNamespace} */
|
||||
this.namespace = options.namespace || "";
|
||||
/** @type {string} */
|
||||
this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]";
|
||||
/** @type {DevtoolModuleFilenameTemplate} */
|
||||
this.moduleFilenameTemplate =
|
||||
options.moduleFilenameTemplate ||
|
||||
"webpack://[namespace]/[resourcePath]?[loaders]";
|
||||
|
||||
9
node_modules/webpack/lib/EvalSourceMapDevToolPlugin.js
generated
vendored
9
node_modules/webpack/lib/EvalSourceMapDevToolPlugin.js
generated
vendored
@@ -17,10 +17,13 @@ const { makePathsAbsolute } = require("./util/identifier");
|
||||
|
||||
/** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../declarations/WebpackOptions").DevtoolNamespace} DevtoolNamespace */
|
||||
/** @typedef {import("../declarations/WebpackOptions").DevtoolModuleFilenameTemplate} DevtoolModuleFilenameTemplate */
|
||||
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
|
||||
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").Rules} Rules */
|
||||
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
|
||||
/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
|
||||
|
||||
/** @type {WeakMap<Source, Source>} */
|
||||
const cache = new WeakMap();
|
||||
@@ -51,14 +54,18 @@ class EvalSourceMapDevToolPlugin {
|
||||
} else {
|
||||
options = inputOptions;
|
||||
}
|
||||
/** @type {string} */
|
||||
this.sourceMapComment =
|
||||
options.append && typeof options.append !== "function"
|
||||
? options.append
|
||||
: "//# sourceURL=[module]\n//# sourceMappingURL=[url]";
|
||||
/** @type {DevtoolModuleFilenameTemplate} */
|
||||
this.moduleFilenameTemplate =
|
||||
options.moduleFilenameTemplate ||
|
||||
"webpack://[namespace]/[resource-path]?[hash]";
|
||||
/** @type {DevtoolNamespace} */
|
||||
this.namespace = options.namespace || "";
|
||||
/** @type {SourceMapDevToolPluginOptions} */
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
||||
30
node_modules/webpack/lib/ExportsInfo.js
generated
vendored
30
node_modules/webpack/lib/ExportsInfo.js
generated
vendored
@@ -933,36 +933,6 @@ class ExportInfo {
|
||||
this._maxTarget = undefined;
|
||||
}
|
||||
|
||||
// TODO webpack 5 remove
|
||||
/**
|
||||
* @private
|
||||
* @param {EXPECTED_ANY} v v
|
||||
*/
|
||||
set used(v) {
|
||||
throw new Error("REMOVED");
|
||||
}
|
||||
|
||||
// TODO webpack 5 remove
|
||||
/** @private */
|
||||
get used() {
|
||||
throw new Error("REMOVED");
|
||||
}
|
||||
|
||||
// TODO webpack 5 remove
|
||||
/**
|
||||
* @private
|
||||
* @param {EXPECTED_ANY} v v
|
||||
*/
|
||||
set usedName(v) {
|
||||
throw new Error("REMOVED");
|
||||
}
|
||||
|
||||
// TODO webpack 5 remove
|
||||
/** @private */
|
||||
get usedName() {
|
||||
throw new Error("REMOVED");
|
||||
}
|
||||
|
||||
get canMangle() {
|
||||
switch (this.canMangleProvide) {
|
||||
case undefined:
|
||||
|
||||
4
node_modules/webpack/lib/ExternalModule.js
generated
vendored
4
node_modules/webpack/lib/ExternalModule.js
generated
vendored
@@ -995,7 +995,7 @@ class ExternalModule extends Module {
|
||||
);
|
||||
/** @type {CodeGenerationResultData} */
|
||||
const data = new Map();
|
||||
data.set("url", { javascript: request });
|
||||
data.set("url", { javascript: /** @type {string} */ (request) });
|
||||
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
|
||||
}
|
||||
case "css-url": {
|
||||
@@ -1003,7 +1003,7 @@ class ExternalModule extends Module {
|
||||
const sources = new Map();
|
||||
/** @type {CodeGenerationResultData} */
|
||||
const data = new Map();
|
||||
data.set("url", { "css-url": request });
|
||||
data.set("url", { "css-url": /** @type {string} */ (request) });
|
||||
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
|
||||
}
|
||||
case "css-import": {
|
||||
|
||||
50
node_modules/webpack/lib/Module.js
generated
vendored
50
node_modules/webpack/lib/Module.js
generated
vendored
@@ -80,6 +80,8 @@ const makeSerializable = require("./util/makeSerializable");
|
||||
/** @typedef {KnownSourceType | string} SourceType */
|
||||
/** @typedef {ReadonlySet<SourceType>} SourceTypes */
|
||||
|
||||
/** @typedef {ReadonlySet<typeof JAVASCRIPT_TYPE | string>} BasicSourceTypes */
|
||||
|
||||
// TODO webpack 6: compilation will be required in CodeGenerationContext
|
||||
/**
|
||||
* @typedef {object} CodeGenerationContext
|
||||
@@ -104,11 +106,36 @@ const makeSerializable = require("./util/makeSerializable");
|
||||
/** @typedef {Set<string>} RuntimeRequirements */
|
||||
/** @typedef {ReadonlySet<string>} ReadOnlyRuntimeRequirements */
|
||||
|
||||
/** @typedef {Map<"topLevelDeclarations", Set<string>> & Map<"chunkInitFragments", InitFragment<EXPECTED_ANY>[]>} KnownCodeGenerationResultDataForJavascriptModules */
|
||||
/** @typedef {Map<"url", { ["css-url"]: string }>} KnownCodeGenerationResultDataForCssModules */
|
||||
/** @typedef {Map<"filename", string> & Map<"assetInfo", AssetInfo> & Map<"fullContentHash", string> & Map<"url", { javascript: string }>} KnownCodeGenerationResultDataForAssetModules */
|
||||
/** @typedef {Map<"share-init", [{ shareScope: string, initStage: number, init: string }]>} KnownCodeGenerationResultForSharing */
|
||||
/** @typedef {KnownCodeGenerationResultDataForJavascriptModules & KnownCodeGenerationResultDataForCssModules & KnownCodeGenerationResultDataForAssetModules & KnownCodeGenerationResultForSharing & Map<string, EXPECTED_ANY>} CodeGenerationResultData */
|
||||
/**
|
||||
* @typedef {object} AllCodeGenerationSchemas
|
||||
* @property {Set<string>} topLevelDeclarations top level declarations for javascript modules
|
||||
* @property {InitFragment<EXPECTED_ANY>[]} chunkInitFragments chunk init fragments for javascript modules
|
||||
* @property {{ javascript?: string, ["css-url"]?: string }} url url for css and javascript modules
|
||||
* @property {string} filename a filename for asset modules
|
||||
* @property {AssetInfo} assetInfo an asset info for asset modules
|
||||
* @property {string} fullContentHash a full content hash for asset modules
|
||||
* @property {[{ shareScope: string, initStage: number, init: string }]} share-init share-init for modules federation
|
||||
*/
|
||||
|
||||
/* eslint-disable jsdoc/type-formatting */
|
||||
/**
|
||||
* @template {string} K
|
||||
* @typedef {K extends keyof AllCodeGenerationSchemas ? AllCodeGenerationSchemas[K] : EXPECTED_ANY} CodeGenValue
|
||||
*/
|
||||
/* eslint-enable jsdoc/type-formatting */
|
||||
|
||||
/* eslint-disable jsdoc/require-template */
|
||||
/**
|
||||
* @typedef {object} CodeGenMapOverloads
|
||||
* @property {<K extends string>(key: K) => CodeGenValue<K> | undefined} get
|
||||
* @property {<K extends string>(key: K, value: CodeGenValue<K>) => CodeGenerationResultData} set
|
||||
* @property {<K extends string>(key: K) => boolean} has
|
||||
* @property {<K extends string>(key: K) => boolean} delete
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Omit<Map<string, EXPECTED_ANY>, "get" | "set" | "has" | "delete"> & CodeGenMapOverloads} CodeGenerationResultData
|
||||
*/
|
||||
|
||||
/** @typedef {Map<SourceType, Source>} Sources */
|
||||
|
||||
@@ -941,6 +968,19 @@ class Module extends DependenciesBlock {
|
||||
return JAVASCRIPT_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic source types are high-level categories like javascript, css, webassembly, etc.
|
||||
* We only have built-in knowledge about the javascript basic type here; other basic types may be
|
||||
* added or changed over time by generators and do not need to be handled or detected here.
|
||||
*
|
||||
* Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
|
||||
* from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
|
||||
* @returns {BasicSourceTypes} types available (do not mutate)
|
||||
*/
|
||||
getSourceBasicTypes() {
|
||||
return this.getSourceTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @deprecated Use codeGeneration() instead
|
||||
|
||||
9
node_modules/webpack/lib/ModuleGraphConnection.js
generated
vendored
9
node_modules/webpack/lib/ModuleGraphConnection.js
generated
vendored
@@ -184,15 +184,6 @@ class ModuleGraphConnection {
|
||||
this.conditional = false;
|
||||
this._active = value;
|
||||
}
|
||||
|
||||
// TODO webpack 5 remove
|
||||
get active() {
|
||||
throw new Error("Use getActiveState instead");
|
||||
}
|
||||
|
||||
set active(value) {
|
||||
throw new Error("Use setActive instead");
|
||||
}
|
||||
}
|
||||
|
||||
/** @typedef {typeof TRANSITIVE_ONLY} TRANSITIVE_ONLY */
|
||||
|
||||
10
node_modules/webpack/lib/MultiStats.js
generated
vendored
10
node_modules/webpack/lib/MultiStats.js
generated
vendored
@@ -8,6 +8,7 @@
|
||||
const identifierUtils = require("./util/identifier");
|
||||
|
||||
/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
|
||||
/** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
|
||||
/** @typedef {import("./Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
|
||||
/** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
|
||||
/** @typedef {import("./Stats")} Stats */
|
||||
@@ -25,8 +26,7 @@ const indent = (str, prefix) => {
|
||||
return prefix + rem;
|
||||
};
|
||||
|
||||
/** @typedef {undefined | string | boolean | StatsOptions} ChildrenStatsOptions */
|
||||
/** @typedef {Omit<StatsOptions, "children"> & { children?: ChildrenStatsOptions | ChildrenStatsOptions[] }} MultiStatsOptions */
|
||||
/** @typedef {StatsOptions} MultiStatsOptions */
|
||||
/** @typedef {{ version: boolean, hash: boolean, errorsCount: boolean, warningsCount: boolean, errors: boolean, warnings: boolean, children: NormalizedStatsOptions[] }} ChildOptions */
|
||||
|
||||
class MultiStats {
|
||||
@@ -56,7 +56,7 @@ class MultiStats {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {undefined | string | boolean | MultiStatsOptions} options stats options
|
||||
* @param {undefined | StatsValue} options stats options
|
||||
* @param {CreateStatsOptionsContext} context context
|
||||
* @returns {ChildOptions} context context
|
||||
*/
|
||||
@@ -109,7 +109,7 @@ class MultiStats {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(string | boolean | MultiStatsOptions)=} options stats options
|
||||
* @param {StatsValue=} options stats options
|
||||
* @returns {StatsCompilation} json output
|
||||
*/
|
||||
toJson(options) {
|
||||
@@ -184,7 +184,7 @@ class MultiStats {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(string | boolean | MultiStatsOptions)=} options stats options
|
||||
* @param {StatsValue=} options stats options
|
||||
* @returns {string} string output
|
||||
*/
|
||||
toString(options) {
|
||||
|
||||
19
node_modules/webpack/lib/RuntimeModule.js
generated
vendored
19
node_modules/webpack/lib/RuntimeModule.js
generated
vendored
@@ -8,7 +8,10 @@
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const OriginalSource = require("webpack-sources").OriginalSource;
|
||||
const Module = require("./Module");
|
||||
const { RUNTIME_TYPES } = require("./ModuleSourceTypeConstants");
|
||||
const {
|
||||
JAVASCRIPT_TYPES,
|
||||
RUNTIME_TYPES
|
||||
} = require("./ModuleSourceTypeConstants");
|
||||
const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
|
||||
|
||||
/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
|
||||
@@ -29,6 +32,7 @@ const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
|
||||
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
|
||||
/** @typedef {import("./util/Hash")} Hash */
|
||||
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
|
||||
/** @typedef {import("./Module").BasicSourceTypes} BasicSourceTypes */
|
||||
|
||||
class RuntimeModule extends Module {
|
||||
/**
|
||||
@@ -138,6 +142,19 @@ class RuntimeModule extends Module {
|
||||
return RUNTIME_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic source types are high-level categories like javascript, css, webassembly, etc.
|
||||
* We only have built-in knowledge about the javascript basic type here; other basic types may be
|
||||
* added or changed over time by generators and do not need to be handled or detected here.
|
||||
*
|
||||
* Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
|
||||
* from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
|
||||
* @returns {BasicSourceTypes} types available (do not mutate)
|
||||
*/
|
||||
getSourceBasicTypes() {
|
||||
return JAVASCRIPT_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CodeGenerationContext} context context for code generation
|
||||
* @returns {CodeGenerationResult} result
|
||||
|
||||
1
node_modules/webpack/lib/SourceMapDevToolModuleOptionsPlugin.js
generated
vendored
1
node_modules/webpack/lib/SourceMapDevToolModuleOptionsPlugin.js
generated
vendored
@@ -17,6 +17,7 @@ class SourceMapDevToolModuleOptionsPlugin {
|
||||
* @param {SourceMapDevToolPluginOptions=} options options
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
/** @type {SourceMapDevToolPluginOptions} */
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
||||
12
node_modules/webpack/lib/SourceMapDevToolPlugin.js
generated
vendored
12
node_modules/webpack/lib/SourceMapDevToolPlugin.js
generated
vendored
@@ -19,6 +19,9 @@ const { makePathsAbsolute } = require("./util/identifier");
|
||||
|
||||
/** @typedef {import("webpack-sources").MapOptions} MapOptions */
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../declarations/WebpackOptions").DevtoolNamespace} DevtoolNamespace */
|
||||
/** @typedef {import("../declarations/WebpackOptions").DevtoolModuleFilenameTemplate} DevtoolModuleFilenameTemplate */
|
||||
/** @typedef {import("../declarations/WebpackOptions").DevtoolFallbackModuleFilenameTemplate} DevtoolFallbackModuleFilenameTemplate */
|
||||
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
|
||||
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").Rules} Rules */
|
||||
/** @typedef {import("./CacheFacade").ItemCacheFacade} ItemCacheFacade */
|
||||
@@ -140,19 +143,24 @@ class SourceMapDevToolPlugin {
|
||||
constructor(options = {}) {
|
||||
validate(options);
|
||||
|
||||
this.sourceMapFilename = /** @type {string | false} */ (options.filename);
|
||||
/** @type {false | TemplatePath}} */
|
||||
/** @type {undefined | null | false | string} */
|
||||
this.sourceMapFilename = options.filename;
|
||||
/** @type {false | TemplatePath} */
|
||||
this.sourceMappingURLComment =
|
||||
options.append === false
|
||||
? false
|
||||
: // eslint-disable-next-line no-useless-concat
|
||||
options.append || "\n//# source" + "MappingURL=[url]";
|
||||
/** @type {DevtoolModuleFilenameTemplate} */
|
||||
this.moduleFilenameTemplate =
|
||||
options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]";
|
||||
/** @type {DevtoolFallbackModuleFilenameTemplate} */
|
||||
this.fallbackModuleFilenameTemplate =
|
||||
options.fallbackModuleFilenameTemplate ||
|
||||
"webpack://[namespace]/[resourcePath]?[hash]";
|
||||
/** @type {DevtoolNamespace} */
|
||||
this.namespace = options.namespace || "";
|
||||
/** @type {SourceMapDevToolPluginOptions} */
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
||||
5
node_modules/webpack/lib/Stats.js
generated
vendored
5
node_modules/webpack/lib/Stats.js
generated
vendored
@@ -6,6 +6,7 @@
|
||||
"use strict";
|
||||
|
||||
/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
|
||||
/** @typedef {import("../declarations/WebpackOptions").StatsValue} StatsValue */
|
||||
/** @typedef {import("./Compilation")} Compilation */
|
||||
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
|
||||
|
||||
@@ -50,7 +51,7 @@ class Stats {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(string | boolean | StatsOptions)=} options stats options
|
||||
* @param {StatsValue=} options stats options
|
||||
* @returns {StatsCompilation} json output
|
||||
*/
|
||||
toJson(options) {
|
||||
@@ -66,7 +67,7 @@ class Stats {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(string | boolean | StatsOptions)=} options stats options
|
||||
* @param {StatsValue=} options stats options
|
||||
* @returns {string} string output
|
||||
*/
|
||||
toString(options) {
|
||||
|
||||
16
node_modules/webpack/lib/WebpackOptionsApply.js
generated
vendored
16
node_modules/webpack/lib/WebpackOptionsApply.js
generated
vendored
@@ -60,6 +60,7 @@ const URLPlugin = require("./dependencies/URLPlugin");
|
||||
const WorkerPlugin = require("./dependencies/WorkerPlugin");
|
||||
|
||||
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
||||
const JavascriptParser = require("./javascript/JavascriptParser");
|
||||
|
||||
const JsonModulesPlugin = require("./json/JsonModulesPlugin");
|
||||
|
||||
@@ -371,7 +372,9 @@ class WebpackOptionsApply extends OptionsApply {
|
||||
|
||||
new JavascriptModulesPlugin().apply(compiler);
|
||||
new JsonModulesPlugin().apply(compiler);
|
||||
new AssetModulesPlugin().apply(compiler);
|
||||
new AssetModulesPlugin({
|
||||
sideEffectFree: options.experiments.futureDefaults
|
||||
}).apply(compiler);
|
||||
|
||||
if (!options.experiments.outputModule) {
|
||||
if (options.output.module) {
|
||||
@@ -483,11 +486,18 @@ class WebpackOptionsApply extends OptionsApply {
|
||||
new HttpUriPlugin(httpOptions).apply(compiler);
|
||||
}
|
||||
|
||||
if (options.experiments.deferImport) {
|
||||
const JavascriptParser = require("./javascript/JavascriptParser");
|
||||
if (
|
||||
options.experiments.deferImport &&
|
||||
!(
|
||||
/** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
|
||||
(JavascriptParser).__importPhasesExtended
|
||||
)
|
||||
) {
|
||||
const importPhases = require("acorn-import-phases");
|
||||
|
||||
JavascriptParser.extend(importPhases({ source: false }));
|
||||
/** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
|
||||
(JavascriptParser).__importPhasesExtended = true;
|
||||
}
|
||||
|
||||
new EntryOptionPlugin().apply(compiler);
|
||||
|
||||
17
node_modules/webpack/lib/asset/AssetModulesPlugin.js
generated
vendored
17
node_modules/webpack/lib/asset/AssetModulesPlugin.js
generated
vendored
@@ -86,7 +86,19 @@ const getNormalModule = memoize(() => require("../NormalModule"));
|
||||
const type = ASSET_MODULE_TYPE;
|
||||
const PLUGIN_NAME = "AssetModulesPlugin";
|
||||
|
||||
/**
|
||||
* @typedef {object} AssetModulesPluginOptions
|
||||
* @property {boolean=} sideEffectFree
|
||||
*/
|
||||
|
||||
class AssetModulesPlugin {
|
||||
/**
|
||||
* @param {AssetModulesPluginOptions} options options
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
@@ -112,7 +124,10 @@ class AssetModulesPlugin {
|
||||
/** @type {NormalModuleCreateData} */
|
||||
(createData)
|
||||
);
|
||||
module.factoryMeta = { sideEffectFree: true };
|
||||
if (this.options.sideEffectFree) {
|
||||
module.factoryMeta = { sideEffectFree: true };
|
||||
}
|
||||
|
||||
return module;
|
||||
});
|
||||
}
|
||||
|
||||
6
node_modules/webpack/lib/asset/RawDataUrlModule.js
generated
vendored
6
node_modules/webpack/lib/asset/RawDataUrlModule.js
generated
vendored
@@ -42,9 +42,13 @@ class RawDataUrlModule extends Module {
|
||||
*/
|
||||
constructor(url, identifier, readableIdentifier) {
|
||||
super(ASSET_MODULE_TYPE_RAW_DATA_URL, null);
|
||||
/** @type {string} */
|
||||
this.url = url;
|
||||
/** @type {Buffer | undefined} */
|
||||
this.urlBuffer = url ? Buffer.from(url) : undefined;
|
||||
this.identifierStr = identifier || this.url;
|
||||
/** @type {string} */
|
||||
this.identifierStr = identifier;
|
||||
/** @type {string} */
|
||||
this.readableIdentifierStr = readableIdentifier || this.identifierStr;
|
||||
}
|
||||
|
||||
|
||||
19
node_modules/webpack/lib/container/RemoteModule.js
generated
vendored
19
node_modules/webpack/lib/container/RemoteModule.js
generated
vendored
@@ -7,7 +7,10 @@
|
||||
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const Module = require("../Module");
|
||||
const { REMOTE_AND_SHARE_INIT_TYPES } = require("../ModuleSourceTypeConstants");
|
||||
const {
|
||||
JAVASCRIPT_TYPES,
|
||||
REMOTE_AND_SHARE_INIT_TYPES
|
||||
} = require("../ModuleSourceTypeConstants");
|
||||
const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
@@ -34,6 +37,7 @@ const RemoteToExternalDependency = require("./RemoteToExternalDependency");
|
||||
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
|
||||
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
/** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
|
||||
|
||||
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
|
||||
|
||||
@@ -137,6 +141,19 @@ class RemoteModule extends Module {
|
||||
return REMOTE_AND_SHARE_INIT_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic source types are high-level categories like javascript, css, webassembly, etc.
|
||||
* We only have built-in knowledge about the javascript basic type here; other basic types may be
|
||||
* added or changed over time by generators and do not need to be handled or detected here.
|
||||
*
|
||||
* Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
|
||||
* from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
|
||||
* @returns {BasicSourceTypes} types available (do not mutate)
|
||||
*/
|
||||
getSourceBasicTypes() {
|
||||
return JAVASCRIPT_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph the module graph
|
||||
* @param {boolean | undefined} strict the importing module is strict
|
||||
|
||||
19
node_modules/webpack/lib/css/CssGenerator.js
generated
vendored
19
node_modules/webpack/lib/css/CssGenerator.js
generated
vendored
@@ -19,7 +19,7 @@ const {
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const Template = require("../Template");
|
||||
const CssImportDependency = require("../dependencies/CssImportDependency");
|
||||
const EntryDependency = require("../dependencies/EntryDependency");
|
||||
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
|
||||
const { getUndoPath } = require("../util/identifier");
|
||||
const memoize = require("../util/memoize");
|
||||
|
||||
@@ -470,22 +470,27 @@ class CssGenerator extends Generator {
|
||||
getTypes(module) {
|
||||
const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType;
|
||||
const sourceTypes = new Set();
|
||||
|
||||
const connections = this._moduleGraph.getIncomingConnections(module);
|
||||
|
||||
let isEntryModule = false;
|
||||
for (const connection of connections) {
|
||||
if (connection.dependency instanceof EntryDependency) {
|
||||
isEntryModule = true;
|
||||
}
|
||||
if (
|
||||
exportType === "link" &&
|
||||
connection.dependency instanceof CssImportDependency
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// when no hmr required, css module js output contains no sideEffects at all
|
||||
// js sideeffect connection doesn't require js type output
|
||||
if (connection.dependency instanceof HarmonyImportSideEffectDependency) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!connection.originModule) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connection.originModule.type.split("/")[0] !== CSS_TYPE) {
|
||||
sourceTypes.add(JAVASCRIPT_TYPE);
|
||||
} else {
|
||||
@@ -503,7 +508,7 @@ class CssGenerator extends Generator {
|
||||
}
|
||||
}
|
||||
if (this._generatesJsOnly(module)) {
|
||||
if (sourceTypes.has(JAVASCRIPT_TYPE) || isEntryModule) {
|
||||
if (sourceTypes.has(JAVASCRIPT_TYPE)) {
|
||||
return JAVASCRIPT_TYPES;
|
||||
}
|
||||
return new Set();
|
||||
@@ -578,3 +583,5 @@ class CssGenerator extends Generator {
|
||||
}
|
||||
|
||||
module.exports = CssGenerator;
|
||||
|
||||
module.exports = CssGenerator;
|
||||
|
||||
7
node_modules/webpack/lib/css/CssModulesPlugin.js
generated
vendored
7
node_modules/webpack/lib/css/CssModulesPlugin.js
generated
vendored
@@ -386,6 +386,13 @@ class CssModulesPlugin {
|
||||
compilation
|
||||
).renderModuleContent.tap(PLUGIN_NAME, (source, module) => {
|
||||
if (module instanceof CssModule && module.hot) {
|
||||
const exportType = /** @type {BuildMeta} */ (module.buildMeta)
|
||||
.exportType;
|
||||
// When exportType !== "link", modules behave like JavaScript modules
|
||||
if (exportType && exportType !== "link") {
|
||||
return source;
|
||||
}
|
||||
// For exportType === "link", we can optimize with self-acceptance
|
||||
const cssData = /** @type {BuildInfo} */ (module.buildInfo).cssData;
|
||||
if (!cssData) {
|
||||
return source;
|
||||
|
||||
4
node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js
generated
vendored
4
node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js
generated
vendored
@@ -65,6 +65,10 @@ class CommonJsExportRequireDependency extends ModuleDependency {
|
||||
return "cjs export require";
|
||||
}
|
||||
|
||||
get category() {
|
||||
return "commonjs";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
|
||||
*/
|
||||
|
||||
822
node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js
generated
vendored
822
node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js
generated
vendored
@@ -5,13 +5,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { fileURLToPath } = require("url");
|
||||
const CommentCompilationWarning = require("../CommentCompilationWarning");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
|
||||
const WebpackError = require("../WebpackError");
|
||||
const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
|
||||
const { VariableInfo } = require("../javascript/JavascriptParser");
|
||||
const {
|
||||
evaluateToIdentifier,
|
||||
evaluateToString,
|
||||
@@ -36,6 +32,7 @@ const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency
|
||||
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
|
||||
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
||||
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
||||
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
|
||||
/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
|
||||
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
||||
/** @typedef {import("../javascript/JavascriptParser").Members} Members */
|
||||
@@ -48,11 +45,300 @@ const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency
|
||||
* @property {string} context
|
||||
*/
|
||||
|
||||
const createRequireSpecifierTag = Symbol("createRequire");
|
||||
const createdRequireIdentifierTag = Symbol("createRequire()");
|
||||
|
||||
const PLUGIN_NAME = "CommonJsImportsParserPlugin";
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser parser
|
||||
* @returns {(expr: Expression) => boolean} handler
|
||||
*/
|
||||
const createRequireCacheDependency = (parser) =>
|
||||
toConstantDependency(parser, RuntimeGlobals.moduleCache, [
|
||||
RuntimeGlobals.moduleCache,
|
||||
RuntimeGlobals.moduleId,
|
||||
RuntimeGlobals.moduleLoaded
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser parser
|
||||
* @param {JavascriptParserOptions} options options
|
||||
* @param {() => undefined | string} getContext context accessor
|
||||
* @returns {(expr: Expression) => boolean} handler
|
||||
*/
|
||||
const createRequireAsExpressionHandler =
|
||||
(parser, options, getContext) => (expr) => {
|
||||
const dep = new CommonJsRequireContextDependency(
|
||||
{
|
||||
request: /** @type {string} */ (options.unknownContextRequest),
|
||||
recursive: /** @type {boolean} */ (options.unknownContextRecursive),
|
||||
regExp: /** @type {RegExp} */ (options.unknownContextRegExp),
|
||||
mode: "sync"
|
||||
},
|
||||
/** @type {Range} */ (expr.range),
|
||||
undefined,
|
||||
parser.scope.inShorthand,
|
||||
getContext()
|
||||
);
|
||||
dep.critical =
|
||||
options.unknownContextCritical &&
|
||||
"require function is used in a way in which dependencies cannot be statically extracted";
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser parser
|
||||
* @param {JavascriptParserOptions} options options
|
||||
* @param {() => undefined | string} getContext context accessor
|
||||
* @returns {(callNew: boolean) => (expr: CallExpression | NewExpression) => (boolean | void)} handler factory
|
||||
*/
|
||||
const createRequireCallHandler = (parser, options, getContext) => {
|
||||
/**
|
||||
* @param {CallExpression | NewExpression} expr expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processRequireItem = (expr, param) => {
|
||||
if (param.isString()) {
|
||||
const dep = new CommonJsRequireDependency(
|
||||
/** @type {string} */ (param.string),
|
||||
/** @type {Range} */ (param.range),
|
||||
getContext()
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {CallExpression | NewExpression} expr expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processRequireContext = (expr, param) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
CommonJsRequireContextDependency,
|
||||
/** @type {Range} */ (expr.range),
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
category: "commonjs"
|
||||
},
|
||||
parser,
|
||||
undefined,
|
||||
getContext()
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
return (callNew) => (expr) => {
|
||||
if (options.commonjsMagicComments) {
|
||||
const { options: requireOptions, errors: commentErrors } =
|
||||
parser.parseCommentOptions(/** @type {Range} */ (expr.range));
|
||||
|
||||
if (commentErrors) {
|
||||
for (const e of commentErrors) {
|
||||
const { comment } = e;
|
||||
parser.state.module.addWarning(
|
||||
new CommentCompilationWarning(
|
||||
`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
|
||||
/** @type {DependencyLocation} */ (comment.loc)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (requireOptions && requireOptions.webpackIgnore !== undefined) {
|
||||
if (typeof requireOptions.webpackIgnore !== "boolean") {
|
||||
parser.state.module.addWarning(
|
||||
new UnsupportedFeatureWarning(
|
||||
`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
|
||||
/** @type {DependencyLocation} */ (expr.loc)
|
||||
)
|
||||
);
|
||||
} else if (requireOptions.webpackIgnore) {
|
||||
// Do not instrument `require()` if `webpackIgnore` is `true`
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.arguments.length !== 1) return;
|
||||
/** @type {null | LocalModule} */
|
||||
let localModule;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
let isExpression = false;
|
||||
for (const p of /** @type {BasicEvaluatedExpression[]} */ (
|
||||
param.options
|
||||
)) {
|
||||
const result = processRequireItem(expr, p);
|
||||
if (result === undefined) {
|
||||
isExpression = true;
|
||||
}
|
||||
}
|
||||
if (!isExpression) {
|
||||
const dep = new RequireHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
param.isString() &&
|
||||
(localModule = getLocalModule(
|
||||
parser.state,
|
||||
/** @type {string} */ (param.string)
|
||||
))
|
||||
) {
|
||||
localModule.flagUsed();
|
||||
const dep = new LocalModuleDependency(
|
||||
localModule,
|
||||
/** @type {Range} */ (expr.range),
|
||||
callNew
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
} else {
|
||||
const result = processRequireItem(expr, param);
|
||||
if (result === undefined) {
|
||||
processRequireContext(expr, param);
|
||||
} else {
|
||||
const dep = new RequireHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser parser
|
||||
* @param {JavascriptParserOptions} options options
|
||||
* @param {() => undefined | string} getContext context accessor
|
||||
* @returns {(expr: CallExpression, weak: boolean) => (boolean | void)} resolver
|
||||
*/
|
||||
const createProcessResolveHandler = (parser, options, getContext) => {
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @param {boolean} weak weak
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processResolveItem = (expr, param, weak) => {
|
||||
if (param.isString()) {
|
||||
const dep = new RequireResolveDependency(
|
||||
/** @type {string} */ (param.string),
|
||||
/** @type {Range} */ (param.range),
|
||||
getContext()
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
dep.weak = weak;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @param {boolean} weak weak
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processResolveContext = (expr, param, weak) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
RequireResolveContextDependency,
|
||||
/** @type {Range} */ (param.range),
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
category: "commonjs",
|
||||
mode: weak ? "weak" : "sync"
|
||||
},
|
||||
parser,
|
||||
getContext()
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
return (expr, weak) => {
|
||||
if (!weak && options.commonjsMagicComments) {
|
||||
const { options: requireOptions, errors: commentErrors } =
|
||||
parser.parseCommentOptions(/** @type {Range} */ (expr.range));
|
||||
|
||||
if (commentErrors) {
|
||||
for (const e of commentErrors) {
|
||||
const { comment } = e;
|
||||
parser.state.module.addWarning(
|
||||
new CommentCompilationWarning(
|
||||
`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
|
||||
/** @type {DependencyLocation} */ (comment.loc)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (requireOptions && requireOptions.webpackIgnore !== undefined) {
|
||||
if (typeof requireOptions.webpackIgnore !== "boolean") {
|
||||
parser.state.module.addWarning(
|
||||
new UnsupportedFeatureWarning(
|
||||
`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
|
||||
/** @type {DependencyLocation} */ (expr.loc)
|
||||
)
|
||||
);
|
||||
} else if (requireOptions.webpackIgnore) {
|
||||
// Do not instrument `require()` if `webpackIgnore` is `true`
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
for (const option of /** @type {BasicEvaluatedExpression[]} */ (
|
||||
param.options
|
||||
)) {
|
||||
const result = processResolveItem(expr, option, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, option, weak);
|
||||
}
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
const result = processResolveItem(expr, param, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, param, weak);
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
class CommonJsImportsParserPlugin {
|
||||
/**
|
||||
* @param {JavascriptParserOptions} options parser options
|
||||
@@ -98,20 +384,6 @@ class CommonJsImportsParserPlugin {
|
||||
evaluateToIdentifier(expression, "require", getMembers, true)
|
||||
);
|
||||
};
|
||||
/**
|
||||
* @param {string | symbol} tag tag
|
||||
*/
|
||||
const tapRequireExpressionTag = (tag) => {
|
||||
parser.hooks.typeof
|
||||
.for(tag)
|
||||
.tap(
|
||||
PLUGIN_NAME,
|
||||
toConstantDependency(parser, JSON.stringify("function"))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for(tag)
|
||||
.tap(PLUGIN_NAME, evaluateToString("function"));
|
||||
};
|
||||
tapRequireExpression("require", () => []);
|
||||
tapRequireExpression("require.resolve", () => ["resolve"]);
|
||||
tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
|
||||
@@ -176,15 +448,7 @@ class CommonJsImportsParserPlugin {
|
||||
// #endregion
|
||||
|
||||
// #region Inspection
|
||||
const requireCache = toConstantDependency(
|
||||
parser,
|
||||
RuntimeGlobals.moduleCache,
|
||||
[
|
||||
RuntimeGlobals.moduleCache,
|
||||
RuntimeGlobals.moduleId,
|
||||
RuntimeGlobals.moduleLoaded
|
||||
]
|
||||
);
|
||||
const requireCache = createRequireCacheDependency(parser);
|
||||
|
||||
parser.hooks.expression.for("require.cache").tap(PLUGIN_NAME, requireCache);
|
||||
// #endregion
|
||||
@@ -194,163 +458,26 @@ class CommonJsImportsParserPlugin {
|
||||
* @param {Expression} expr expression
|
||||
* @returns {boolean} true when handled
|
||||
*/
|
||||
const requireAsExpressionHandler = (expr) => {
|
||||
const dep = new CommonJsRequireContextDependency(
|
||||
{
|
||||
request: /** @type {string} */ (options.unknownContextRequest),
|
||||
recursive: /** @type {boolean} */ (options.unknownContextRecursive),
|
||||
regExp: /** @type {RegExp} */ (options.unknownContextRegExp),
|
||||
mode: "sync"
|
||||
},
|
||||
/** @type {Range} */ (expr.range),
|
||||
undefined,
|
||||
parser.scope.inShorthand,
|
||||
getContext()
|
||||
);
|
||||
dep.critical =
|
||||
options.unknownContextCritical &&
|
||||
"require function is used in a way in which dependencies cannot be statically extracted";
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
const requireAsExpressionHandler = createRequireAsExpressionHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("require")
|
||||
.tap(PLUGIN_NAME, requireAsExpressionHandler);
|
||||
// #endregion
|
||||
|
||||
// #region Require
|
||||
/**
|
||||
* @param {CallExpression | NewExpression} expr expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processRequireItem = (expr, param) => {
|
||||
if (param.isString()) {
|
||||
const dep = new CommonJsRequireDependency(
|
||||
/** @type {string} */ (param.string),
|
||||
/** @type {Range} */ (param.range),
|
||||
getContext()
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {CallExpression | NewExpression} expr expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processRequireContext = (expr, param) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
CommonJsRequireContextDependency,
|
||||
/** @type {Range} */ (expr.range),
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
category: "commonjs"
|
||||
},
|
||||
parser,
|
||||
undefined,
|
||||
getContext()
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* @param {boolean} callNew true, when require is called with new
|
||||
* @returns {(expr: CallExpression | NewExpression) => (boolean | void)} handler
|
||||
*/
|
||||
const createRequireHandler = (callNew) => (expr) => {
|
||||
if (options.commonjsMagicComments) {
|
||||
const { options: requireOptions, errors: commentErrors } =
|
||||
parser.parseCommentOptions(/** @type {Range} */ (expr.range));
|
||||
|
||||
if (commentErrors) {
|
||||
for (const e of commentErrors) {
|
||||
const { comment } = e;
|
||||
parser.state.module.addWarning(
|
||||
new CommentCompilationWarning(
|
||||
`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
|
||||
/** @type {DependencyLocation} */ (comment.loc)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (requireOptions && requireOptions.webpackIgnore !== undefined) {
|
||||
if (typeof requireOptions.webpackIgnore !== "boolean") {
|
||||
parser.state.module.addWarning(
|
||||
new UnsupportedFeatureWarning(
|
||||
`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
|
||||
/** @type {DependencyLocation} */ (expr.loc)
|
||||
)
|
||||
);
|
||||
} else if (requireOptions.webpackIgnore) {
|
||||
// Do not instrument `require()` if `webpackIgnore` is `true`
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.arguments.length !== 1) return;
|
||||
/** @type {null | LocalModule} */
|
||||
let localModule;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
let isExpression = false;
|
||||
for (const p of /** @type {BasicEvaluatedExpression[]} */ (
|
||||
param.options
|
||||
)) {
|
||||
const result = processRequireItem(expr, p);
|
||||
if (result === undefined) {
|
||||
isExpression = true;
|
||||
}
|
||||
}
|
||||
if (!isExpression) {
|
||||
const dep = new RequireHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
param.isString() &&
|
||||
(localModule = getLocalModule(
|
||||
parser.state,
|
||||
/** @type {string} */ (param.string)
|
||||
))
|
||||
) {
|
||||
localModule.flagUsed();
|
||||
const dep = new LocalModuleDependency(
|
||||
localModule,
|
||||
/** @type {Range} */ (expr.range),
|
||||
callNew
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
} else {
|
||||
const result = processRequireItem(expr, param);
|
||||
if (result === undefined) {
|
||||
processRequireContext(expr, param);
|
||||
} else {
|
||||
const dep = new RequireHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const createRequireHandler = createRequireCallHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
parser.hooks.call
|
||||
.for("require")
|
||||
.tap(PLUGIN_NAME, createRequireHandler(false));
|
||||
@@ -460,112 +587,11 @@ class CommonJsImportsParserPlugin {
|
||||
* @param {boolean} weak weak
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processResolve = (expr, weak) => {
|
||||
if (!weak && options.commonjsMagicComments) {
|
||||
const { options: requireOptions, errors: commentErrors } =
|
||||
parser.parseCommentOptions(/** @type {Range} */ (expr.range));
|
||||
|
||||
if (commentErrors) {
|
||||
for (const e of commentErrors) {
|
||||
const { comment } = e;
|
||||
parser.state.module.addWarning(
|
||||
new CommentCompilationWarning(
|
||||
`Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
|
||||
/** @type {DependencyLocation} */ (comment.loc)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (requireOptions && requireOptions.webpackIgnore !== undefined) {
|
||||
if (typeof requireOptions.webpackIgnore !== "boolean") {
|
||||
parser.state.module.addWarning(
|
||||
new UnsupportedFeatureWarning(
|
||||
`\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
|
||||
/** @type {DependencyLocation} */ (expr.loc)
|
||||
)
|
||||
);
|
||||
} else if (requireOptions.webpackIgnore) {
|
||||
// Do not instrument `require()` if `webpackIgnore` is `true`
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
for (const option of /** @type {BasicEvaluatedExpression[]} */ (
|
||||
param.options
|
||||
)) {
|
||||
const result = processResolveItem(expr, option, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, option, weak);
|
||||
}
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
const result = processResolveItem(expr, param, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, param, weak);
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(
|
||||
/** @type {Range} */ (expr.callee.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @param {boolean} weak weak
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processResolveItem = (expr, param, weak) => {
|
||||
if (param.isString()) {
|
||||
const dep = new RequireResolveDependency(
|
||||
/** @type {string} */ (param.string),
|
||||
/** @type {Range} */ (param.range),
|
||||
getContext()
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
dep.weak = weak;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @param {BasicEvaluatedExpression} param param
|
||||
* @param {boolean} weak weak
|
||||
* @returns {boolean | void} true when handled
|
||||
*/
|
||||
const processResolveContext = (expr, param, weak) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
RequireResolveContextDependency,
|
||||
/** @type {Range} */ (param.range),
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
category: "commonjs",
|
||||
mode: weak ? "weak" : "sync"
|
||||
},
|
||||
parser,
|
||||
getContext()
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
dep.optional = Boolean(parser.scope.inTry);
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
const processResolve = createProcessResolveHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
|
||||
parser.hooks.call
|
||||
.for("require.resolve")
|
||||
@@ -574,232 +600,12 @@ class CommonJsImportsParserPlugin {
|
||||
.for("require.resolveWeak")
|
||||
.tap(PLUGIN_NAME, (expr) => processResolve(expr, true));
|
||||
// #endregion
|
||||
|
||||
// #region Create require
|
||||
|
||||
if (!options.createRequire) return;
|
||||
|
||||
/** @type {ImportSource[]} */
|
||||
let moduleName = [];
|
||||
/** @type {string | undefined} */
|
||||
let specifierName;
|
||||
|
||||
if (options.createRequire === true) {
|
||||
moduleName = ["module", "node:module"];
|
||||
specifierName = "createRequire";
|
||||
} else {
|
||||
/** @type {undefined | string} */
|
||||
let moduleName;
|
||||
const match = /^(.*) from (.*)$/.exec(options.createRequire);
|
||||
if (match) {
|
||||
[, specifierName, moduleName] = match;
|
||||
}
|
||||
if (!specifierName || !moduleName) {
|
||||
const err = new WebpackError(
|
||||
`Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
|
||||
options.createRequire
|
||||
)}`
|
||||
);
|
||||
err.details =
|
||||
'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
tapRequireExpressionTag(createdRequireIdentifierTag);
|
||||
tapRequireExpressionTag(createRequireSpecifierTag);
|
||||
parser.hooks.evaluateCallExpression
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr) => {
|
||||
const context = parseCreateRequireArguments(expr);
|
||||
if (context === undefined) return;
|
||||
const ident = parser.evaluatedVariable({
|
||||
tag: createdRequireIdentifierTag,
|
||||
data: { context },
|
||||
next: undefined
|
||||
});
|
||||
|
||||
return new BasicEvaluatedExpression()
|
||||
.setIdentifier(ident, ident, () => [])
|
||||
.setSideEffects(false)
|
||||
.setRange(/** @type {Range} */ (expr.range));
|
||||
});
|
||||
parser.hooks.unhandledExpressionMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) =>
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
`createRequire().${members.join(".")} is not supported by webpack.`
|
||||
)(expr)
|
||||
);
|
||||
parser.hooks.canRename
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, () => true);
|
||||
parser.hooks.canRename
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, () => true);
|
||||
parser.hooks.rename
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, defineUndefined);
|
||||
parser.hooks.expression
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, requireAsExpressionHandler);
|
||||
parser.hooks.call
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, createRequireHandler(false));
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @returns {string | void} context
|
||||
*/
|
||||
const parseCreateRequireArguments = (expr) => {
|
||||
const args = expr.arguments;
|
||||
if (args.length !== 1) {
|
||||
const err = new WebpackError(
|
||||
"module.createRequire supports only one argument."
|
||||
);
|
||||
err.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addWarning(err);
|
||||
return;
|
||||
}
|
||||
const arg = args[0];
|
||||
const evaluated = parser.evaluateExpression(arg);
|
||||
if (!evaluated.isString()) {
|
||||
const err = new WebpackError(
|
||||
"module.createRequire failed parsing argument."
|
||||
);
|
||||
err.loc = /** @type {DependencyLocation} */ (arg.loc);
|
||||
parser.state.module.addWarning(err);
|
||||
return;
|
||||
}
|
||||
const ctx = /** @type {string} */ (evaluated.string).startsWith("file://")
|
||||
? fileURLToPath(/** @type {string} */ (evaluated.string))
|
||||
: /** @type {string} */ (evaluated.string);
|
||||
// argument always should be a filename
|
||||
return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
|
||||
};
|
||||
|
||||
parser.hooks.import.tap(
|
||||
{
|
||||
name: PLUGIN_NAME,
|
||||
stage: -10
|
||||
},
|
||||
(statement, source) => {
|
||||
if (
|
||||
!moduleName.includes(source) ||
|
||||
statement.specifiers.length !== 1 ||
|
||||
statement.specifiers[0].type !== "ImportSpecifier" ||
|
||||
statement.specifiers[0].imported.type !== "Identifier" ||
|
||||
statement.specifiers[0].imported.name !== specifierName
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// clear for 'import { createRequire as x } from "module"'
|
||||
// if any other specifier was used import module
|
||||
const clearDep = new ConstDependency(
|
||||
parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
|
||||
? ";"
|
||||
: "",
|
||||
/** @type {Range} */ (statement.range)
|
||||
);
|
||||
clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
|
||||
parser.state.module.addPresentationalDependency(clearDep);
|
||||
parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
parser.hooks.importSpecifier.tap(
|
||||
{
|
||||
name: PLUGIN_NAME,
|
||||
stage: -10
|
||||
},
|
||||
(statement, source, id, name) => {
|
||||
if (!moduleName.includes(source) || id !== specifierName) return;
|
||||
parser.tagVariable(name, createRequireSpecifierTag);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
|
||||
if (
|
||||
declarator.id.type !== "Identifier" ||
|
||||
!declarator.init ||
|
||||
declarator.init.type !== "CallExpression" ||
|
||||
declarator.init.callee.type !== "Identifier"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const variableInfo = parser.getVariableInfo(declarator.init.callee.name);
|
||||
if (
|
||||
variableInfo instanceof VariableInfo &&
|
||||
variableInfo.tagInfo &&
|
||||
variableInfo.tagInfo.tag === createRequireSpecifierTag
|
||||
) {
|
||||
const context = parseCreateRequireArguments(declarator.init);
|
||||
if (context === undefined) return;
|
||||
parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
|
||||
name: declarator.id.name,
|
||||
context
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
parser.hooks.memberChainOfCallMemberChain
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, calleeMembers, callExpr, members) => {
|
||||
if (
|
||||
calleeMembers.length !== 0 ||
|
||||
members.length !== 1 ||
|
||||
members[0] !== "cache"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// createRequire().cache
|
||||
const context = parseCreateRequireArguments(callExpr);
|
||||
if (context === undefined) return;
|
||||
return requireCache(expr);
|
||||
});
|
||||
parser.hooks.callMemberChainOfCallMemberChain
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, calleeMembers, innerCallExpression, members) => {
|
||||
if (
|
||||
calleeMembers.length !== 0 ||
|
||||
members.length !== 1 ||
|
||||
members[0] !== "resolve"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// createRequire().resolve()
|
||||
return processResolve(expr, false);
|
||||
});
|
||||
parser.hooks.expressionMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) => {
|
||||
// require.cache
|
||||
if (members.length === 1 && members[0] === "cache") {
|
||||
return requireCache(expr);
|
||||
}
|
||||
});
|
||||
parser.hooks.callMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) => {
|
||||
// require.resolve()
|
||||
if (members.length === 1 && members[0] === "resolve") {
|
||||
return processResolve(expr, false);
|
||||
}
|
||||
});
|
||||
parser.hooks.call
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr) => {
|
||||
const clearDep = new ConstDependency(
|
||||
"/* createRequire() */ undefined",
|
||||
/** @type {Range} */ (expr.range)
|
||||
);
|
||||
clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(clearDep);
|
||||
return true;
|
||||
});
|
||||
// #endregion
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CommonJsImportsParserPlugin;
|
||||
module.exports.createProcessResolveHandler = createProcessResolveHandler;
|
||||
module.exports.createRequireAsExpressionHandler =
|
||||
createRequireAsExpressionHandler;
|
||||
module.exports.createRequireCacheDependency = createRequireCacheDependency;
|
||||
module.exports.createRequireHandler = createRequireCallHandler;
|
||||
|
||||
356
node_modules/webpack/lib/dependencies/CreateRequireParserPlugin.js
generated
vendored
Executable file
356
node_modules/webpack/lib/dependencies/CreateRequireParserPlugin.js
generated
vendored
Executable file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { fileURLToPath } = require("url");
|
||||
const WebpackError = require("../WebpackError");
|
||||
const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
|
||||
const { VariableInfo } = require("../javascript/JavascriptParser");
|
||||
const {
|
||||
evaluateToString,
|
||||
expressionIsUnsupported,
|
||||
toConstantDependency
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
|
||||
const ConstDependency = require("./ConstDependency");
|
||||
|
||||
/** @typedef {import("estree").CallExpression} CallExpression */
|
||||
/** @typedef {import("estree").Expression} Expression */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
|
||||
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
||||
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
||||
/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */
|
||||
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
||||
|
||||
/**
|
||||
* @typedef {object} CommonJsImportSettings
|
||||
* @property {string=} name
|
||||
* @property {string} context
|
||||
*/
|
||||
|
||||
const createRequireSpecifierTag = Symbol("createRequire");
|
||||
const createdRequireIdentifierTag = Symbol("createRequire()");
|
||||
|
||||
const PLUGIN_NAME = "CreateRequireParserPlugin";
|
||||
|
||||
const {
|
||||
createProcessResolveHandler,
|
||||
createRequireAsExpressionHandler,
|
||||
createRequireCacheDependency,
|
||||
createRequireHandler
|
||||
} = CommonJsImportsParserPlugin;
|
||||
|
||||
class CreateRequireParserPlugin {
|
||||
/**
|
||||
* @param {JavascriptParserOptions} options parser options
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser the parser
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
if (!options.createRequire) return;
|
||||
|
||||
const getContext = () => {
|
||||
if (parser.currentTagData) {
|
||||
const { context } =
|
||||
/** @type {CommonJsImportSettings} */
|
||||
(parser.currentTagData);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string | symbol} tag tag
|
||||
*/
|
||||
const tapRequireExpressionTag = (tag) => {
|
||||
parser.hooks.typeof
|
||||
.for(tag)
|
||||
.tap(
|
||||
PLUGIN_NAME,
|
||||
toConstantDependency(parser, JSON.stringify("function"))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for(tag)
|
||||
.tap(PLUGIN_NAME, evaluateToString("function"));
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Expression} expr expression
|
||||
* @returns {boolean} true when set undefined
|
||||
*/
|
||||
const defineUndefined = (expr) => {
|
||||
const dep = new ConstDependency(
|
||||
"undefined",
|
||||
/** @type {Range} */ (expr.range)
|
||||
);
|
||||
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return false;
|
||||
};
|
||||
|
||||
const requireCache = createRequireCacheDependency(parser);
|
||||
const requireAsExpressionHandler = createRequireAsExpressionHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
const createRequireCallHandler = createRequireHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
const processResolve = createProcessResolveHandler(
|
||||
parser,
|
||||
options,
|
||||
getContext
|
||||
);
|
||||
|
||||
/** @type {ImportSource[]} */
|
||||
let moduleNames = [];
|
||||
/** @type {string | undefined} */
|
||||
let specifierName;
|
||||
|
||||
if (options.createRequire === true) {
|
||||
moduleNames = ["module", "node:module"];
|
||||
specifierName = "createRequire";
|
||||
} else if (typeof options.createRequire === "string") {
|
||||
/** @type {undefined | string} */
|
||||
let parsedModuleName;
|
||||
const match = /^(.*) from (.*)$/.exec(options.createRequire);
|
||||
if (match) {
|
||||
[, specifierName, parsedModuleName] = match;
|
||||
}
|
||||
if (!specifierName || !parsedModuleName) {
|
||||
const err = new WebpackError(
|
||||
`Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
|
||||
options.createRequire
|
||||
)}`
|
||||
);
|
||||
err.details =
|
||||
'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
|
||||
throw err;
|
||||
}
|
||||
moduleNames = [parsedModuleName];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CallExpression} expr call expression
|
||||
* @returns {string | void} context
|
||||
*/
|
||||
const parseCreateRequireArguments = (expr) => {
|
||||
const args = expr.arguments;
|
||||
if (args.length !== 1) {
|
||||
const err = new WebpackError(
|
||||
"module.createRequire supports only one argument."
|
||||
);
|
||||
err.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addWarning(err);
|
||||
return;
|
||||
}
|
||||
const arg = args[0];
|
||||
const evaluated = parser.evaluateExpression(arg);
|
||||
if (!evaluated.isString()) {
|
||||
const err = new WebpackError(
|
||||
"module.createRequire failed parsing argument."
|
||||
);
|
||||
err.loc = /** @type {DependencyLocation} */ (arg.loc);
|
||||
parser.state.module.addWarning(err);
|
||||
return;
|
||||
}
|
||||
const ctx = /** @type {string} */ (evaluated.string).startsWith("file://")
|
||||
? fileURLToPath(/** @type {string} */ (evaluated.string))
|
||||
: /** @type {string} */ (evaluated.string);
|
||||
// argument always should be a filename
|
||||
return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
|
||||
};
|
||||
|
||||
tapRequireExpressionTag(createdRequireIdentifierTag);
|
||||
tapRequireExpressionTag(createRequireSpecifierTag);
|
||||
|
||||
parser.hooks.evaluateCallExpression
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr) => {
|
||||
const context = parseCreateRequireArguments(expr);
|
||||
if (context === undefined) return;
|
||||
const ident = parser.evaluatedVariable({
|
||||
tag: createdRequireIdentifierTag,
|
||||
data: { context },
|
||||
next: undefined
|
||||
});
|
||||
|
||||
return new BasicEvaluatedExpression()
|
||||
.setIdentifier(ident, ident, () => [])
|
||||
.setSideEffects(false)
|
||||
.setRange(/** @type {Range} */ (expr.range));
|
||||
});
|
||||
|
||||
parser.hooks.unhandledExpressionMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) =>
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
`createRequire().${members.join(".")} is not supported by webpack.`
|
||||
)(expr)
|
||||
);
|
||||
parser.hooks.canRename
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, () => true);
|
||||
parser.hooks.canRename
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, () => true);
|
||||
parser.hooks.rename
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, defineUndefined);
|
||||
parser.hooks.expression
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, requireAsExpressionHandler);
|
||||
parser.hooks.call
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, createRequireCallHandler(false));
|
||||
|
||||
parser.hooks.import.tap(
|
||||
{
|
||||
name: PLUGIN_NAME,
|
||||
stage: -10
|
||||
},
|
||||
(statement, source) => {
|
||||
if (
|
||||
!moduleNames.includes(source) ||
|
||||
statement.specifiers.length !== 1 ||
|
||||
statement.specifiers[0].type !== "ImportSpecifier" ||
|
||||
statement.specifiers[0].imported.type !== "Identifier" ||
|
||||
statement.specifiers[0].imported.name !== specifierName
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// clear for 'import { createRequire as x } from "module"'
|
||||
// if any other specifier was used import module
|
||||
const clearDep = new ConstDependency(
|
||||
parser.isAsiPosition(/** @type {Range} */ (statement.range)[0])
|
||||
? ";"
|
||||
: "",
|
||||
/** @type {Range} */ (statement.range)
|
||||
);
|
||||
clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
|
||||
parser.state.module.addPresentationalDependency(clearDep);
|
||||
parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
parser.hooks.importSpecifier.tap(
|
||||
{
|
||||
name: PLUGIN_NAME,
|
||||
stage: -10
|
||||
},
|
||||
(statement, source, id, name) => {
|
||||
if (!moduleNames.includes(source) || id !== specifierName) return;
|
||||
parser.tagVariable(name, createRequireSpecifierTag);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
|
||||
if (
|
||||
declarator.id.type !== "Identifier" ||
|
||||
!declarator.init ||
|
||||
declarator.init.type !== "CallExpression" ||
|
||||
declarator.init.callee.type !== "Identifier"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const variableInfo = parser.getVariableInfo(declarator.init.callee.name);
|
||||
if (
|
||||
variableInfo instanceof VariableInfo &&
|
||||
variableInfo.tagInfo &&
|
||||
variableInfo.tagInfo.tag === createRequireSpecifierTag
|
||||
) {
|
||||
const context = parseCreateRequireArguments(declarator.init);
|
||||
if (context === undefined) return;
|
||||
parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
|
||||
name: declarator.id.name,
|
||||
context
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
parser.hooks.memberChainOfCallMemberChain
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, calleeMembers, callExpr, members) => {
|
||||
if (
|
||||
calleeMembers.length !== 0 ||
|
||||
members.length !== 1 ||
|
||||
members[0] !== "cache"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// createRequire().cache
|
||||
const context = parseCreateRequireArguments(callExpr);
|
||||
if (context === undefined) return;
|
||||
return requireCache(expr);
|
||||
});
|
||||
parser.hooks.callMemberChainOfCallMemberChain
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, calleeMembers, innerCallExpression, members) => {
|
||||
if (
|
||||
calleeMembers.length !== 0 ||
|
||||
members.length !== 1 ||
|
||||
members[0] !== "resolve"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// createRequire().resolve()
|
||||
return processResolve(expr, false);
|
||||
});
|
||||
parser.hooks.expressionMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) => {
|
||||
// require.cache
|
||||
if (members.length === 1 && members[0] === "cache") {
|
||||
return requireCache(expr);
|
||||
}
|
||||
});
|
||||
parser.hooks.callMemberChain
|
||||
.for(createdRequireIdentifierTag)
|
||||
.tap(PLUGIN_NAME, (expr, members) => {
|
||||
// require.resolve()
|
||||
if (members.length === 1 && members[0] === "resolve") {
|
||||
return processResolve(expr, false);
|
||||
}
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr) => {
|
||||
const clearDep = new ConstDependency(
|
||||
"/* createRequire */ undefined",
|
||||
/** @type {Range} */ (expr.range)
|
||||
);
|
||||
clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(clearDep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.call
|
||||
.for(createRequireSpecifierTag)
|
||||
.tap(PLUGIN_NAME, (expr) => {
|
||||
const clearDep = new ConstDependency(
|
||||
"/* createRequire() */ undefined",
|
||||
/** @type {Range} */ (expr.range)
|
||||
);
|
||||
clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
||||
parser.state.module.addPresentationalDependency(clearDep);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CreateRequireParserPlugin;
|
||||
12
node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js
generated
vendored
12
node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js
generated
vendored
@@ -39,14 +39,10 @@ module.exports = class HarmonyExportDependencyParserPlugin {
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
this.exportPresenceMode =
|
||||
options.reexportExportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
|
||||
: options.exportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.exportsPresence)
|
||||
: options.strictExportPresence
|
||||
? ExportPresenceModes.ERROR
|
||||
: ExportPresenceModes.AUTO;
|
||||
this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
|
||||
options.reexportExportsPresence,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
30
node_modules/webpack/lib/dependencies/HarmonyImportDependency.js
generated
vendored
30
node_modules/webpack/lib/dependencies/HarmonyImportDependency.js
generated
vendored
@@ -53,9 +53,38 @@ const ExportPresenceModes = {
|
||||
default:
|
||||
throw new Error(`Invalid export presence value ${str}`);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Resolve export presence mode from parser options with a specific key and shared fallbacks.
|
||||
* @param {string | false | undefined} specificValue the type-specific option value (e.g. importExportsPresence or reexportExportsPresence)
|
||||
* @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options parser options
|
||||
* @returns {ExportPresenceMode} resolved mode
|
||||
*/
|
||||
resolveFromOptions(specificValue, options) {
|
||||
if (specificValue !== undefined) {
|
||||
return ExportPresenceModes.fromUserOption(specificValue);
|
||||
}
|
||||
if (options.exportsPresence !== undefined) {
|
||||
return ExportPresenceModes.fromUserOption(options.exportsPresence);
|
||||
}
|
||||
return options.strictExportPresence
|
||||
? ExportPresenceModes.ERROR
|
||||
: ExportPresenceModes.AUTO;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the non-optional leading part of a member chain.
|
||||
* @param {string[]} members members
|
||||
* @param {boolean[]} membersOptionals optionality for each member
|
||||
* @returns {string[]} the non-optional prefix
|
||||
*/
|
||||
const getNonOptionalPart = (members, membersOptionals) => {
|
||||
let i = 0;
|
||||
while (i < members.length && membersOptionals[i] === false) i++;
|
||||
return i !== members.length ? members.slice(0, i) : members;
|
||||
};
|
||||
|
||||
/** @typedef {string[]} Ids */
|
||||
|
||||
class HarmonyImportDependency extends ModuleDependency {
|
||||
@@ -427,3 +456,4 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
|
||||
};
|
||||
|
||||
module.exports.ExportPresenceModes = ExportPresenceModes;
|
||||
module.exports.getNonOptionalPart = getNonOptionalPart;
|
||||
|
||||
352
node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js
generated
vendored
352
node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js
generated
vendored
@@ -18,12 +18,16 @@ const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
||||
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
||||
const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
|
||||
const HarmonyExports = require("./HarmonyExports");
|
||||
const { ExportPresenceModes } = require("./HarmonyImportDependency");
|
||||
const {
|
||||
ExportPresenceModes,
|
||||
getNonOptionalPart
|
||||
} = require("./HarmonyImportDependency");
|
||||
const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
|
||||
const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
|
||||
const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
|
||||
|
||||
/** @typedef {import("estree").Expression} Expression */
|
||||
/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
|
||||
/** @typedef {import("estree").Identifier} Identifier */
|
||||
/** @typedef {import("estree").MemberExpression} MemberExpression */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
|
||||
@@ -63,17 +67,44 @@ const harmonySpecifierGuardTag = Symbol("harmony import guard");
|
||||
|
||||
const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
|
||||
|
||||
/** @type {(members: Members) => string} */
|
||||
const getMembersKey = (members) => members.join(".");
|
||||
|
||||
/**
|
||||
* Strip the root binding name if needed
|
||||
* @param {HarmonySettings} settings settings
|
||||
* @param {Ids} ids ids
|
||||
* @returns {Ids} ids for presence check
|
||||
* @param {JavascriptParser} parser the parser
|
||||
* @param {PrivateIdentifier | Expression} left left expression
|
||||
* @param {Expression} right right expression
|
||||
* @returns {{ leftPart: string, members: Members, settings: HarmonySettings } | undefined} info
|
||||
*/
|
||||
const getIdsForPresence = (settings, ids) =>
|
||||
settings.ids.length ? ids.slice(1) : ids;
|
||||
const getInOperatorHarmonyImportInfo = (parser, left, right) => {
|
||||
const leftPartEvaluated = parser.evaluateExpression(left);
|
||||
if (leftPartEvaluated.couldHaveSideEffects()) return;
|
||||
/** @type {string | undefined} */
|
||||
const leftPart = leftPartEvaluated.asString();
|
||||
if (!leftPart) return;
|
||||
|
||||
const rightPart = parser.evaluateExpression(right);
|
||||
if (!rightPart.isIdentifier()) return;
|
||||
|
||||
const rootInfo = rightPart.rootInfo;
|
||||
const root =
|
||||
typeof rootInfo === "string"
|
||||
? rootInfo
|
||||
: rootInfo instanceof VariableInfo
|
||||
? rootInfo.name
|
||||
: undefined;
|
||||
if (!root) return;
|
||||
|
||||
const settings = /** @type {HarmonySettings | undefined} */ (
|
||||
parser.getTagData(root, harmonySpecifierTag)
|
||||
);
|
||||
if (!settings) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
leftPart,
|
||||
members: /** @type {(() => Members)} */ (rightPart.getMembers)(),
|
||||
settings
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
/**
|
||||
@@ -82,23 +113,23 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
/** @type {ExportPresenceMode} */
|
||||
this.exportPresenceMode =
|
||||
options.importExportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.importExportsPresence)
|
||||
: options.exportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.exportsPresence)
|
||||
: options.strictExportPresence
|
||||
? ExportPresenceModes.ERROR
|
||||
: ExportPresenceModes.AUTO;
|
||||
this.exportPresenceMode = ExportPresenceModes.resolveFromOptions(
|
||||
options.importExportsPresence,
|
||||
options
|
||||
);
|
||||
this.strictThisContextOnImports = options.strictThisContextOnImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser the parser
|
||||
* @param {HarmonySettings} settings settings
|
||||
* @param {Ids} ids ids
|
||||
* @returns {ExportPresenceMode} exportPresenceMode
|
||||
*/
|
||||
getExportPresenceMode(parser, ids) {
|
||||
getExportPresenceMode(parser, settings, ids) {
|
||||
// Guards only apply to namespace imports
|
||||
if (settings.ids.length) return this.exportPresenceMode;
|
||||
|
||||
const harmonySettings = /** @type {HarmonySettings=} */ (
|
||||
parser.currentTagData
|
||||
);
|
||||
@@ -107,9 +138,12 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
const data = /** @type {HarmonySpecifierGuards=} */ (
|
||||
parser.getTagData(harmonySettings.name, harmonySpecifierGuardTag)
|
||||
);
|
||||
return data && data.guards && data.guards.has(getMembersKey(ids))
|
||||
? ExportPresenceModes.NONE
|
||||
: this.exportPresenceMode;
|
||||
|
||||
if (data && data.guards && data.guards.has(ids[0])) {
|
||||
return ExportPresenceModes.NONE;
|
||||
}
|
||||
|
||||
return this.exportPresenceMode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,17 +153,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
apply(parser) {
|
||||
const getImportPhase = createGetImportPhase(this.options.deferImport);
|
||||
|
||||
/**
|
||||
* @param {Members} members members
|
||||
* @param {MembersOptionals} membersOptionals members Optionals
|
||||
* @returns {Ids} a non optional part
|
||||
*/
|
||||
function getNonOptionalPart(members, membersOptionals) {
|
||||
let i = 0;
|
||||
while (i < members.length && membersOptionals[i] === false) i++;
|
||||
return i !== members.length ? members.slice(0, i) : members;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MemberExpression} node member expression
|
||||
* @param {number} count count
|
||||
@@ -207,31 +230,14 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
);
|
||||
parser.hooks.binaryExpression.tap(PLUGIN_NAME, (expression) => {
|
||||
if (expression.operator !== "in") return;
|
||||
const info = getInOperatorHarmonyImportInfo(
|
||||
parser,
|
||||
expression.left,
|
||||
expression.right
|
||||
);
|
||||
if (!info) return;
|
||||
|
||||
const leftPartEvaluated = parser.evaluateExpression(expression.left);
|
||||
if (leftPartEvaluated.couldHaveSideEffects()) return;
|
||||
/** @type {string | undefined} */
|
||||
const leftPart = leftPartEvaluated.asString();
|
||||
if (!leftPart) return;
|
||||
|
||||
const rightPart = parser.evaluateExpression(expression.right);
|
||||
if (!rightPart.isIdentifier()) return;
|
||||
|
||||
const rootInfo = rightPart.rootInfo;
|
||||
if (
|
||||
typeof rootInfo === "string" ||
|
||||
!rootInfo ||
|
||||
!rootInfo.tagInfo ||
|
||||
rootInfo.tagInfo.tag !== harmonySpecifierTag
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const settings =
|
||||
/** @type {HarmonySettings} */
|
||||
(rootInfo.tagInfo.data);
|
||||
const members =
|
||||
/** @type {(() => Members)} */
|
||||
(rightPart.getMembers)();
|
||||
const { leftPart, members, settings } = info;
|
||||
const dep = new HarmonyEvaluatedImportSpecifierDependency(
|
||||
settings.source,
|
||||
settings.sourceOrder,
|
||||
@@ -276,10 +282,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
settings.name,
|
||||
/** @type {Range} */
|
||||
(expr.range),
|
||||
this.getExportPresenceMode(
|
||||
parser,
|
||||
getIdsForPresence(settings, settings.ids)
|
||||
),
|
||||
this.exportPresenceMode,
|
||||
settings.phase,
|
||||
settings.attributes,
|
||||
[]
|
||||
@@ -329,10 +332,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
settings.name,
|
||||
/** @type {Range} */
|
||||
(expr.range),
|
||||
this.getExportPresenceMode(
|
||||
parser,
|
||||
getIdsForPresence(settings, ids)
|
||||
),
|
||||
this.getExportPresenceMode(parser, settings, ids),
|
||||
settings.phase,
|
||||
settings.attributes,
|
||||
ranges
|
||||
@@ -382,10 +382,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
ids,
|
||||
settings.name,
|
||||
/** @type {Range} */ (expr.range),
|
||||
this.getExportPresenceMode(
|
||||
parser,
|
||||
getIdsForPresence(settings, ids)
|
||||
),
|
||||
this.getExportPresenceMode(parser, settings, ids),
|
||||
settings.phase,
|
||||
settings.attributes,
|
||||
ranges
|
||||
@@ -453,160 +450,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {Expression} expression expression
|
||||
* @returns {{ root: string, members: Members } | undefined} info
|
||||
*/
|
||||
const getHarmonyImportInfo = (expression) => {
|
||||
const nameInfo = parser.getNameForExpression(expression);
|
||||
if (!nameInfo) return;
|
||||
|
||||
const rootInfo = nameInfo.rootInfo;
|
||||
const root =
|
||||
typeof rootInfo === "string"
|
||||
? rootInfo
|
||||
: rootInfo instanceof VariableInfo
|
||||
? rootInfo.name
|
||||
: undefined;
|
||||
if (!root) return;
|
||||
if (!parser.getTagData(root, harmonySpecifierTag)) return;
|
||||
return { root, members: nameInfo.getMembers() };
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Guards} guards guards
|
||||
* @param {string} root root name
|
||||
* @param {Members} members members
|
||||
*/
|
||||
const addToGuards = (guards, root, members) => {
|
||||
const membersKey = getMembersKey(members);
|
||||
const guardedMembers = guards.get(root);
|
||||
if (guardedMembers) {
|
||||
guardedMembers.add(membersKey);
|
||||
return;
|
||||
}
|
||||
|
||||
guards.set(
|
||||
root,
|
||||
// Adding `foo.bar` implies guarding `foo` as well
|
||||
membersKey === "" ? new Set([""]) : new Set([membersKey, ""])
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Expression} expression expression
|
||||
* @param {Guards} guards guards
|
||||
* @param {boolean} needTruthy need to be truthy
|
||||
*/
|
||||
const collect = (expression, guards, needTruthy) => {
|
||||
// !foo
|
||||
if (
|
||||
expression.type === "UnaryExpression" &&
|
||||
expression.operator === "!"
|
||||
) {
|
||||
collect(expression.argument, guards, !needTruthy);
|
||||
return;
|
||||
} else if (expression.type === "LogicalExpression" && needTruthy) {
|
||||
// foo && bar
|
||||
if (expression.operator === "&&") {
|
||||
collect(expression.left, guards, true);
|
||||
collect(expression.right, guards, true);
|
||||
}
|
||||
// falsy || foo
|
||||
else if (expression.operator === "||") {
|
||||
const leftEvaluation = parser.evaluateExpression(expression.left);
|
||||
const leftBool = leftEvaluation.asBool();
|
||||
if (leftBool === false) {
|
||||
collect(expression.right, guards, true);
|
||||
}
|
||||
}
|
||||
// nullish ?? foo
|
||||
else if (expression.operator === "??") {
|
||||
const leftEvaluation = parser.evaluateExpression(expression.left);
|
||||
const leftNullish = leftEvaluation.asNullish();
|
||||
if (leftNullish === true) {
|
||||
collect(expression.right, guards, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!needTruthy) return;
|
||||
|
||||
/**
|
||||
* @param {Expression} targetExpression expression
|
||||
* @returns {boolean} is added
|
||||
*/
|
||||
const addGuardForExpression = (targetExpression) => {
|
||||
const info = getHarmonyImportInfo(targetExpression);
|
||||
if (!info) return false;
|
||||
addToGuards(guards, info.root, info.members);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Expression} left left expression
|
||||
* @param {Expression} right right expression
|
||||
* @param {(evaluation: ReturnType<JavascriptParser["evaluateExpression"]>) => boolean} matcher matcher
|
||||
* @returns {boolean} is added
|
||||
*/
|
||||
const addGuardForNullishCompare = (left, right, matcher) => {
|
||||
const leftEval = parser.evaluateExpression(left);
|
||||
if (leftEval && matcher(leftEval)) {
|
||||
return addGuardForExpression(right);
|
||||
}
|
||||
const rightEval = parser.evaluateExpression(right);
|
||||
if (rightEval && matcher(rightEval)) {
|
||||
return addGuardForExpression(/** @type {Expression} */ (left));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (expression.type === "BinaryExpression") {
|
||||
// "bar" in foo
|
||||
if (expression.operator === "in") {
|
||||
const leftEvaluation = parser.evaluateExpression(expression.left);
|
||||
if (leftEvaluation.couldHaveSideEffects()) return;
|
||||
const propertyName = leftEvaluation.asString();
|
||||
if (!propertyName) return;
|
||||
parser.evaluateExpression(expression.right);
|
||||
const info = getHarmonyImportInfo(expression.right);
|
||||
if (!info) return;
|
||||
|
||||
if (info.members.length) {
|
||||
for (const member of info.members) {
|
||||
addToGuards(guards, info.root, [member]);
|
||||
}
|
||||
}
|
||||
addToGuards(guards, info.root, [...info.members, propertyName]);
|
||||
return;
|
||||
}
|
||||
// foo !== undefined
|
||||
else if (
|
||||
expression.operator === "!==" &&
|
||||
addGuardForNullishCompare(
|
||||
/** @type {Expression} */ (expression.left),
|
||||
expression.right,
|
||||
(evaluation) => evaluation.isUndefined()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// foo != undefined
|
||||
// foo != null
|
||||
else if (
|
||||
expression.operator === "!=" &&
|
||||
addGuardForNullishCompare(
|
||||
/** @type {Expression} */ (expression.left),
|
||||
expression.right,
|
||||
(evaluation) => Boolean(evaluation.asNullish())
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
addGuardForExpression(expression);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Guards} guards guards
|
||||
* @param {() => void} walk walk callback
|
||||
@@ -657,7 +500,68 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
if (parser.scope.isAsmJs) return;
|
||||
/** @type {Guards} */
|
||||
const guards = new Map();
|
||||
collect(expression, guards, true);
|
||||
|
||||
/**
|
||||
* @param {Expression} expression expression
|
||||
* @param {boolean} needTruthy need to be truthy
|
||||
*/
|
||||
const collect = (expression, needTruthy) => {
|
||||
if (
|
||||
expression.type === "UnaryExpression" &&
|
||||
expression.operator === "!"
|
||||
) {
|
||||
collect(expression.argument, !needTruthy);
|
||||
return;
|
||||
} else if (expression.type === "LogicalExpression" && needTruthy) {
|
||||
if (expression.operator === "&&") {
|
||||
collect(expression.left, true);
|
||||
collect(expression.right, true);
|
||||
} else if (expression.operator === "||") {
|
||||
const leftEvaluation = parser.evaluateExpression(expression.left);
|
||||
const leftBool = leftEvaluation.asBool();
|
||||
if (leftBool === false) {
|
||||
collect(expression.right, true);
|
||||
}
|
||||
} else if (expression.operator === "??") {
|
||||
const leftEvaluation = parser.evaluateExpression(expression.left);
|
||||
const leftNullish = leftEvaluation.asNullish();
|
||||
if (leftNullish === true) {
|
||||
collect(expression.right, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!needTruthy) return;
|
||||
|
||||
// Direct `"x" in ns` guards
|
||||
if (
|
||||
expression.type === "BinaryExpression" &&
|
||||
expression.operator === "in"
|
||||
) {
|
||||
if (expression.right.type !== "Identifier") {
|
||||
return;
|
||||
}
|
||||
const info = getInOperatorHarmonyImportInfo(
|
||||
parser,
|
||||
expression.left,
|
||||
expression.right
|
||||
);
|
||||
if (!info) return;
|
||||
|
||||
const { settings, leftPart, members } = info;
|
||||
// Only direct namespace guards
|
||||
if (members.length > 0) return;
|
||||
const guarded = guards.get(settings.name);
|
||||
if (guarded) {
|
||||
guarded.add(leftPart);
|
||||
return;
|
||||
}
|
||||
|
||||
guards.set(settings.name, new Set([leftPart]));
|
||||
}
|
||||
};
|
||||
|
||||
collect(expression, true);
|
||||
|
||||
if (guards.size === 0) return;
|
||||
return (walk) => {
|
||||
|
||||
16
node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js
generated
vendored
16
node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js
generated
vendored
@@ -5,6 +5,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const HarmonyImportDependency = require("./HarmonyImportDependency");
|
||||
|
||||
@@ -72,11 +73,16 @@ HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDepend
|
||||
*/
|
||||
apply(dependency, source, templateContext) {
|
||||
const { moduleGraph, concatenationScope } = templateContext;
|
||||
if (concatenationScope) {
|
||||
const module = /** @type {Module} */ (moduleGraph.getModule(dependency));
|
||||
if (concatenationScope.isModuleInScope(module)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const module = /** @type {Module} */ (moduleGraph.getModule(dependency));
|
||||
|
||||
if (module && !module.getSourceBasicTypes().has(JAVASCRIPT_TYPE)) {
|
||||
// no need to render import
|
||||
return;
|
||||
}
|
||||
|
||||
if (concatenationScope && concatenationScope.isModuleInScope(module)) {
|
||||
return;
|
||||
}
|
||||
super.apply(dependency, source, templateContext);
|
||||
}
|
||||
|
||||
4
node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js
generated
vendored
4
node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js
generated
vendored
@@ -9,6 +9,7 @@ const {
|
||||
JAVASCRIPT_MODULE_TYPE_AUTO,
|
||||
JAVASCRIPT_MODULE_TYPE_ESM
|
||||
} = require("../ModuleTypeConstants");
|
||||
const CreateRequireParserPlugin = require("./CreateRequireParserPlugin");
|
||||
const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
||||
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
||||
const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
|
||||
@@ -138,6 +139,9 @@ class HarmonyModulesPlugin {
|
||||
new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser);
|
||||
new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser);
|
||||
new HarmonyTopLevelThisParserPlugin().apply(parser);
|
||||
if (parserOptions.createRequire) {
|
||||
new CreateRequireParserPlugin(parserOptions).apply(parser);
|
||||
}
|
||||
};
|
||||
|
||||
normalModuleFactory.hooks.parser
|
||||
|
||||
12
node_modules/webpack/lib/dependencies/ImportParserPlugin.js
generated
vendored
12
node_modules/webpack/lib/dependencies/ImportParserPlugin.js
generated
vendored
@@ -14,6 +14,7 @@ const {
|
||||
} = require("../javascript/JavascriptParser");
|
||||
const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
|
||||
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
||||
const { getNonOptionalPart } = require("./HarmonyImportDependency");
|
||||
const ImportContextDependency = require("./ImportContextDependency");
|
||||
const ImportDependency = require("./ImportDependency");
|
||||
const ImportEagerDependency = require("./ImportEagerDependency");
|
||||
@@ -178,17 +179,6 @@ class ImportParserPlugin {
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(parser) {
|
||||
/**
|
||||
* @param {Members} members members
|
||||
* @param {MembersOptionals} membersOptionals members Optionals
|
||||
* @returns {string[]} a non optional part
|
||||
*/
|
||||
function getNonOptionalPart(members, membersOptionals) {
|
||||
let i = 0;
|
||||
while (i < members.length && membersOptionals[i] === false) i++;
|
||||
return i !== members.length ? members.slice(0, i) : members;
|
||||
}
|
||||
|
||||
parser.hooks.collectDestructuringAssignmentProperties.tap(
|
||||
PLUGIN_NAME,
|
||||
(expr) => {
|
||||
|
||||
4
node_modules/webpack/lib/dependencies/ImportPhase.js
generated
vendored
4
node_modules/webpack/lib/dependencies/ImportPhase.js
generated
vendored
@@ -27,12 +27,16 @@ const ImportPhase = Object.freeze({
|
||||
|
||||
/**
|
||||
* @typedef {object} ImportPhaseUtils
|
||||
* @property {(phase: ImportPhaseType) => boolean} isEvaluation true if phase is evaluation
|
||||
* @property {(phase: ImportPhaseType) => boolean} isDefer true if phase is defer
|
||||
* @property {(phase: ImportPhaseType) => boolean} isSource true if phase is source
|
||||
*/
|
||||
|
||||
/** @type {ImportPhaseUtils} */
|
||||
const ImportPhaseUtils = {
|
||||
isEvaluation(phase) {
|
||||
return phase === ImportPhase.Evaluation;
|
||||
},
|
||||
isDefer(phase) {
|
||||
return phase === ImportPhase.Defer;
|
||||
},
|
||||
|
||||
97
node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js
generated
vendored
97
node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js
generated
vendored
@@ -56,6 +56,7 @@ const JavascriptParser = require("./JavascriptParser");
|
||||
/** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
|
||||
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
|
||||
/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
|
||||
/** @typedef {import("../Compilation").ExecuteModuleObject} ExecuteModuleObject */
|
||||
@@ -75,37 +76,75 @@ const JavascriptParser = require("./JavascriptParser");
|
||||
/** @typedef {import("../util/concatenate").ScopeSet} ScopeSet */
|
||||
/** @typedef {import("../util/concatenate").UsedNamesInScopeInfo} UsedNamesInScopeInfo */
|
||||
|
||||
/** @type {WeakMap<ChunkGraph, WeakMap<Chunk, boolean>>} */
|
||||
const chunkHasJsCache = new WeakMap();
|
||||
|
||||
/**
|
||||
* @param {Chunk} chunk a chunk
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {boolean} true, when a JS file is needed for this chunk
|
||||
*/
|
||||
const chunkHasJs = (chunk, chunkGraph) => {
|
||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) return true;
|
||||
const _chunkHasJs = (chunk, chunkGraph) => {
|
||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
|
||||
if (chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean(
|
||||
chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Chunk} chunk a chunk
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {boolean} true, when a JS file is needed for this chunk
|
||||
*/
|
||||
const chunkHasJs = (chunk, chunkGraph) => {
|
||||
let innerCache = chunkHasJsCache.get(chunkGraph);
|
||||
if (innerCache === undefined) {
|
||||
innerCache = new WeakMap();
|
||||
chunkHasJsCache.set(chunkGraph, innerCache);
|
||||
}
|
||||
|
||||
const cachedResult = innerCache.get(chunk);
|
||||
if (cachedResult !== undefined) {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
const result = _chunkHasJs(chunk, chunkGraph);
|
||||
innerCache.set(chunk, result);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Chunk} chunk a chunk
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {boolean} true, when a JS file is needed for this chunk
|
||||
*/
|
||||
const chunkHasRuntimeOrJs = (chunk, chunkGraph) => {
|
||||
if (chunkHasJs(chunk, chunkGraph)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
WEBPACK_MODULE_TYPE_RUNTIME
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
for (const chunkGroup of chunk.groupsIterable) {
|
||||
for (const c of chunkGroup.chunks) {
|
||||
if (chunkHasJs(c, chunkGraph)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return Boolean(
|
||||
chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
|
||||
);
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1312,17 +1351,22 @@ class JavascriptModulesPlugin {
|
||||
const runtimeRequirements =
|
||||
chunkGraph.getTreeRuntimeRequirements(chunk);
|
||||
buf2.push("// Load entry module and return exports");
|
||||
let i = chunkGraph.getNumberOfEntryModules(chunk);
|
||||
|
||||
/** @type {EntryModuleWithChunkGroup[]} */
|
||||
const jsEntries = [];
|
||||
for (const [
|
||||
entryModule,
|
||||
entrypoint
|
||||
] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
|
||||
if (
|
||||
!chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
|
||||
chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
|
||||
) {
|
||||
i--;
|
||||
jsEntries.push([entryModule, entrypoint]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let i = jsEntries.length;
|
||||
for (const [entryModule, entrypoint] of jsEntries) {
|
||||
const chunks =
|
||||
/** @type {Entrypoint} */
|
||||
(entrypoint).chunks.filter((c) => c !== chunk);
|
||||
@@ -1546,20 +1590,42 @@ class JavascriptModulesPlugin {
|
||||
runtimeTemplate: { outputOptions }
|
||||
} = renderContext;
|
||||
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
||||
|
||||
/**
|
||||
* @param {string} condition guard expression
|
||||
* @returns {string[]} source
|
||||
*/
|
||||
const renderMissingModuleError = (condition) =>
|
||||
outputOptions.pathinfo
|
||||
? [
|
||||
`if (${condition}) {`,
|
||||
Template.indent([
|
||||
"delete __webpack_module_cache__[moduleId];",
|
||||
'var e = new Error("Cannot find module \'" + moduleId + "\'");',
|
||||
"e.code = 'MODULE_NOT_FOUND';",
|
||||
"throw e;"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
: [];
|
||||
|
||||
const moduleExecution = runtimeRequirements.has(
|
||||
RuntimeGlobals.interceptModuleExecution
|
||||
)
|
||||
? Template.asString([
|
||||
`var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`,
|
||||
`${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
|
||||
...renderMissingModuleError("!execOptions.factory"),
|
||||
"module = execOptions.module;",
|
||||
"execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
|
||||
])
|
||||
: runtimeRequirements.has(RuntimeGlobals.thisAsExports)
|
||||
? Template.asString([
|
||||
...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
|
||||
`__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});`
|
||||
])
|
||||
: Template.asString([
|
||||
...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
|
||||
`__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});`
|
||||
]);
|
||||
const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
|
||||
@@ -1580,19 +1646,6 @@ class JavascriptModulesPlugin {
|
||||
])
|
||||
: Template.indent("return cachedModule.exports;"),
|
||||
"}",
|
||||
// Add helpful error message in development mode when module is not found
|
||||
...(outputOptions.pathinfo
|
||||
? [
|
||||
"// Check if module exists (development only)",
|
||||
"if (__webpack_modules__[moduleId] === undefined) {",
|
||||
Template.indent([
|
||||
'var e = new Error("Cannot find module \'" + moduleId + "\'");',
|
||||
"e.code = 'MODULE_NOT_FOUND';",
|
||||
"throw e;"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
: []),
|
||||
"// Create a new module (and put it into the cache)",
|
||||
"var module = __webpack_module_cache__[moduleId] = {",
|
||||
Template.indent([
|
||||
|
||||
4
node_modules/webpack/lib/javascript/JavascriptParser.js
generated
vendored
4
node_modules/webpack/lib/javascript/JavascriptParser.js
generated
vendored
@@ -318,13 +318,13 @@ class VariableInfo {
|
||||
/** @typedef {Literal | string | null | undefined} ImportSource */
|
||||
|
||||
/**
|
||||
* @typedef {Omit<ParseOptions, "sourceType"> & { sourceType: "module" | "script" | "auto" }} InternalParseOptions
|
||||
* @typedef {Omit<ParseOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto" }} InternalParseOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} ParseOptions
|
||||
* @property {"module" | "script"} sourceType
|
||||
* @property {EcmaVersion=} ecmaVersion
|
||||
* @property {EcmaVersion} ecmaVersion
|
||||
* @property {boolean=} locations
|
||||
* @property {boolean=} comments
|
||||
* @property {boolean=} ranges
|
||||
|
||||
3
node_modules/webpack/lib/optimize/ConcatenatedModule.js
generated
vendored
3
node_modules/webpack/lib/optimize/ConcatenatedModule.js
generated
vendored
@@ -1004,6 +1004,9 @@ class ConcatenatedModule extends Module {
|
||||
if (!(connection.dependency instanceof HarmonyImportDependency)) {
|
||||
return false;
|
||||
}
|
||||
if (!connection.module.getSourceBasicTypes().has(JAVASCRIPT_TYPE)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
connection &&
|
||||
connection.resolvedOriginModule === module &&
|
||||
|
||||
5
node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js
generated
vendored
5
node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js
generated
vendored
@@ -466,7 +466,10 @@ class ModuleConcatenationPlugin {
|
||||
chunk,
|
||||
m
|
||||
);
|
||||
if (sourceTypes.size === 1) {
|
||||
if (
|
||||
sourceTypes.size === 1 &&
|
||||
sourceTypes.has(JAVASCRIPT_TYPE)
|
||||
) {
|
||||
chunkGraph.disconnectChunkAndModule(chunk, m);
|
||||
} else {
|
||||
const newSourceTypes = new Set(sourceTypes);
|
||||
|
||||
1
node_modules/webpack/lib/performance/AssetsOverSizeLimitWarning.js
generated
vendored
1
node_modules/webpack/lib/performance/AssetsOverSizeLimitWarning.js
generated
vendored
@@ -28,6 +28,7 @@ Assets: ${assetLists}`);
|
||||
|
||||
/** @type {string} */
|
||||
this.name = "AssetsOverSizeLimitWarning";
|
||||
/** @type {AssetDetails[]} */
|
||||
this.assets = assetsOverSizeLimit;
|
||||
}
|
||||
}
|
||||
|
||||
1
node_modules/webpack/lib/performance/EntrypointsOverSizeLimitWarning.js
generated
vendored
1
node_modules/webpack/lib/performance/EntrypointsOverSizeLimitWarning.js
generated
vendored
@@ -31,6 +31,7 @@ Entrypoints:${entrypointList}\n`);
|
||||
|
||||
/** @type {string} */
|
||||
this.name = "EntrypointsOverSizeLimitWarning";
|
||||
/** @type {EntrypointDetails[]} */
|
||||
this.entrypoints = entrypoints;
|
||||
}
|
||||
}
|
||||
|
||||
1
node_modules/webpack/lib/performance/SizeLimitsPlugin.js
generated
vendored
1
node_modules/webpack/lib/performance/SizeLimitsPlugin.js
generated
vendored
@@ -46,6 +46,7 @@ module.exports = class SizeLimitsPlugin {
|
||||
* @param {PerformanceOptions} options the plugin options
|
||||
*/
|
||||
constructor(options) {
|
||||
/** @type {PerformanceOptions["hints"]} */
|
||||
this.hints = options.hints;
|
||||
/** @type {number | undefined} */
|
||||
this.maxAssetSize = options.maxAssetSize;
|
||||
|
||||
20
node_modules/webpack/lib/runtime/ToBinaryRuntimeModule.js
generated
vendored
20
node_modules/webpack/lib/runtime/ToBinaryRuntimeModule.js
generated
vendored
@@ -29,30 +29,38 @@ class ToBinaryRuntimeModule extends RuntimeModule {
|
||||
const isNodePlatform = compilation.compiler.platform.node;
|
||||
const isWebPlatform = compilation.compiler.platform.web;
|
||||
const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
|
||||
const toImmutableBytes = runtimeTemplate.basicFunction("value", [
|
||||
runtimeTemplate.destructureObject(["buffer"], "value"),
|
||||
`${runtimeTemplate.renderConst()} throwErr = ${runtimeTemplate.basicFunction("", ["throw new TypeError('ArrayBuffer is immutable');"])};`,
|
||||
"Object.defineProperties(buffer, { immutable: { value: true }, resize: { value: throwErr }, transfer: { value: throwErr }, transferToFixedLength: { value: throwErr } });",
|
||||
"Object.freeze(buffer);",
|
||||
"return value;"
|
||||
]);
|
||||
|
||||
return Template.asString([
|
||||
"// define to binary helper",
|
||||
`${runtimeTemplate.renderConst()} toImmutableBytes = ${toImmutableBytes}`,
|
||||
`${fn} = ${isNeutralPlatform ? "typeof Buffer !== 'undefined' ? " : ""}${
|
||||
isNodePlatform || isNeutralPlatform
|
||||
? `${runtimeTemplate.returningFunction("new Uint8Array(Buffer.from(base64, 'base64'))", "base64")}`
|
||||
? `${runtimeTemplate.returningFunction("toImmutableBytes(new Uint8Array(Buffer.from(base64, 'base64')))", "base64")}`
|
||||
: ""
|
||||
} ${isNeutralPlatform ? ": " : ""}${
|
||||
isWebPlatform || isNeutralPlatform
|
||||
? `(${runtimeTemplate.basicFunction("", [
|
||||
"var table = new Uint8Array(128);",
|
||||
`${runtimeTemplate.renderConst()} table = new Uint8Array(128);`,
|
||||
"for (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i;",
|
||||
`return ${runtimeTemplate.basicFunction("base64", [
|
||||
"var n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == '=') - (base64[n - 2] == '=')) * 3 / 4 | 0);",
|
||||
`${runtimeTemplate.renderConst()} n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == '=') - (base64[n - 2] == '=')) * 3 / 4 | 0);`,
|
||||
"for (var i = 0, j = 0; i < n;) {",
|
||||
Template.indent([
|
||||
"var c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)];",
|
||||
"var c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)];",
|
||||
`${runtimeTemplate.renderConst()} c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)];`,
|
||||
`${runtimeTemplate.renderConst()} c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)];`,
|
||||
"bytes[j++] = (c0 << 2) | (c1 >> 4);",
|
||||
"bytes[j++] = (c1 << 4) | (c2 >> 2);",
|
||||
"bytes[j++] = (c2 << 6) | c3;"
|
||||
]),
|
||||
"}",
|
||||
"return bytes"
|
||||
"return toImmutableBytes(bytes)"
|
||||
])}`
|
||||
])})();`
|
||||
: ""
|
||||
|
||||
19
node_modules/webpack/lib/sharing/ConsumeSharedModule.js
generated
vendored
19
node_modules/webpack/lib/sharing/ConsumeSharedModule.js
generated
vendored
@@ -8,7 +8,10 @@
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
||||
const Module = require("../Module");
|
||||
const { CONSUME_SHARED_TYPES } = require("../ModuleSourceTypeConstants");
|
||||
const {
|
||||
CONSUME_SHARED_TYPES,
|
||||
JAVASCRIPT_TYPES
|
||||
} = require("../ModuleSourceTypeConstants");
|
||||
const {
|
||||
WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
|
||||
} = require("../ModuleTypeConstants");
|
||||
@@ -41,6 +44,7 @@ const fallbackModuleCache = new WeakMap();
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
/** @typedef {import("../util/semver").SemVerRange} SemVerRange */
|
||||
/** @typedef {import("../Module").BasicSourceTypes} BasicSourceTypes */
|
||||
|
||||
/**
|
||||
* @typedef {object} ConsumeOptions
|
||||
@@ -159,6 +163,19 @@ class ConsumeSharedModule extends Module {
|
||||
return CONSUME_SHARED_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic source types are high-level categories like javascript, css, webassembly, etc.
|
||||
* We only have built-in knowledge about the javascript basic type here; other basic types may be
|
||||
* added or changed over time by generators and do not need to be handled or detected here.
|
||||
*
|
||||
* Some modules, e.g. RemoteModule, may return non-basic source types like "remote" and "share-init"
|
||||
* from getSourceTypes(), but their generated output is still JavaScript, i.e. their basic type is JS.
|
||||
* @returns {BasicSourceTypes} types available (do not mutate)
|
||||
*/
|
||||
getSourceBasicTypes() {
|
||||
return JAVASCRIPT_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph the module graph
|
||||
* @returns {Module | null} fallback module
|
||||
|
||||
23
node_modules/webpack/lib/util/AppendOnlyStackedSet.js
generated
vendored
23
node_modules/webpack/lib/util/AppendOnlyStackedSet.js
generated
vendored
@@ -43,7 +43,9 @@ class AppendOnlyStackedSet {
|
||||
|
||||
clear() {
|
||||
this._sets = [];
|
||||
if (this._current) this._current.clear();
|
||||
if (this._current) {
|
||||
this._current = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,6 +54,25 @@ class AppendOnlyStackedSet {
|
||||
createChild() {
|
||||
return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Iterator<T>} iterable iterator
|
||||
*/
|
||||
[Symbol.iterator]() {
|
||||
const iterators = this._sets.map((map) => map[Symbol.iterator]());
|
||||
let current = iterators.pop();
|
||||
return {
|
||||
next() {
|
||||
if (!current) return { done: true, value: undefined };
|
||||
let result = current.next();
|
||||
while (result.done && iterators.length > 0) {
|
||||
current = /** @type {SetIterator<T>} */ (iterators.pop());
|
||||
result = current.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AppendOnlyStackedSet;
|
||||
|
||||
188
node_modules/webpack/lib/util/findGraphRoots.js
generated
vendored
188
node_modules/webpack/lib/util/findGraphRoots.js
generated
vendored
@@ -8,19 +8,13 @@
|
||||
const NO_MARKER = 0;
|
||||
const IN_PROGRESS_MARKER = 1;
|
||||
const DONE_MARKER = 2;
|
||||
const DONE_MAYBE_ROOT_CYCLE_MARKER = 3;
|
||||
const DONE_AND_ROOT_MARKER = 4;
|
||||
const CANDIDATE_MARKER = 3;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Set<Node<T>>} Nodes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Set<Cycle<T>>} Cycles
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
@@ -32,20 +26,24 @@ class Node {
|
||||
this.item = item;
|
||||
/** @type {Nodes<T>} */
|
||||
this.dependencies = new Set();
|
||||
this.marker = NO_MARKER;
|
||||
/** @type {Cycle<T> | undefined} */
|
||||
this.cycle = undefined;
|
||||
/** @type {SCC<T>} */
|
||||
this.scc = new SCC();
|
||||
// Each node starts as a single-node SCC
|
||||
this.scc.nodes.add(this);
|
||||
/** @type {number} */
|
||||
this.incoming = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SCC (strongly connected component)
|
||||
* @template T
|
||||
*/
|
||||
class Cycle {
|
||||
class SCC {
|
||||
constructor() {
|
||||
/** @type {Nodes<T>} */
|
||||
this.nodes = new Set();
|
||||
this.marker = NO_MARKER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +68,10 @@ module.exports = (items, getDependencies) => {
|
||||
itemToNode.set(item, node);
|
||||
}
|
||||
|
||||
// early exit when there is only a single item
|
||||
// Early exit when there is only one node
|
||||
if (itemToNode.size <= 1) return items;
|
||||
|
||||
// grab all the dependencies
|
||||
// Build graph edges
|
||||
for (const node of itemToNode.values()) {
|
||||
for (const dep of getDependencies(node.item)) {
|
||||
const depNode = itemToNode.get(dep);
|
||||
@@ -83,27 +81,16 @@ module.exports = (items, getDependencies) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Set of current root modules
|
||||
// items will be removed if a new reference to it has been found
|
||||
/** @type {Nodes<T>} */
|
||||
const roots = new Set();
|
||||
// All candidate root SCCs, they will be removed once an incoming edge is found
|
||||
/** @type {Set<SCC<T>>} */
|
||||
const rootSCCs = new Set();
|
||||
|
||||
// Set of current cycles without references to it
|
||||
// cycles will be removed if a new reference to it has been found
|
||||
// that is not part of the cycle
|
||||
/** @type {Cycles<T>} */
|
||||
const rootCycles = new Set();
|
||||
|
||||
// For all non-marked nodes
|
||||
for (const selectedNode of itemToNode.values()) {
|
||||
if (selectedNode.marker === NO_MARKER) {
|
||||
// deep-walk all referenced modules
|
||||
// in a non-recursive way
|
||||
// DFS walk only once per unseen SCC
|
||||
if (selectedNode.scc.marker === NO_MARKER) {
|
||||
selectedNode.scc.marker = IN_PROGRESS_MARKER;
|
||||
|
||||
// start by entering the selected node
|
||||
selectedNode.marker = IN_PROGRESS_MARKER;
|
||||
|
||||
// keep a stack to avoid recursive walk
|
||||
// Keep a stack to avoid recursive walk
|
||||
/** @type {StackEntry<T>[]} */
|
||||
const stack = [
|
||||
{
|
||||
@@ -112,130 +99,113 @@ module.exports = (items, getDependencies) => {
|
||||
}
|
||||
];
|
||||
|
||||
// process the top item until stack is empty
|
||||
while (stack.length > 0) {
|
||||
const topOfStack = stack[stack.length - 1];
|
||||
|
||||
// Are there still edges unprocessed in the current node?
|
||||
// Process one unvisited outgoing edge if available
|
||||
if (topOfStack.openEdges.length > 0) {
|
||||
// Process one dependency
|
||||
const dependency =
|
||||
/** @type {Node<T>} */
|
||||
(topOfStack.openEdges.pop());
|
||||
switch (dependency.marker) {
|
||||
const depSCC = dependency.scc;
|
||||
switch (depSCC.marker) {
|
||||
case NO_MARKER:
|
||||
// dependency has not be visited yet
|
||||
// mark it as in-progress and recurse
|
||||
// First time we see this SCC: enter it
|
||||
stack.push({
|
||||
node: dependency,
|
||||
openEdges: [...dependency.dependencies]
|
||||
});
|
||||
dependency.marker = IN_PROGRESS_MARKER;
|
||||
depSCC.marker = IN_PROGRESS_MARKER;
|
||||
break;
|
||||
case IN_PROGRESS_MARKER: {
|
||||
// It's a in-progress cycle
|
||||
let cycle = dependency.cycle;
|
||||
if (!cycle) {
|
||||
cycle = new Cycle();
|
||||
cycle.nodes.add(dependency);
|
||||
dependency.cycle = cycle;
|
||||
}
|
||||
// set cycle property for each node in the cycle
|
||||
// if nodes are already part of a cycle
|
||||
// we merge the cycles to a shared cycle
|
||||
// Back-edge to an SCC that is still on the stack
|
||||
// Example:
|
||||
// A -> B -> C -> D
|
||||
// ^ |
|
||||
// |_________|
|
||||
// If we are at `D` and traverse `D` -> `B`, then `B/C/D` must be in one SCC
|
||||
/** @type {Set<SCC<T>>} */
|
||||
const sccsToMerge = new Set();
|
||||
for (
|
||||
let i = stack.length - 1;
|
||||
stack[i].node !== dependency;
|
||||
stack[i].node.scc !== depSCC;
|
||||
i--
|
||||
) {
|
||||
const node = stack[i].node;
|
||||
if (node.cycle) {
|
||||
if (node.cycle !== cycle) {
|
||||
// merge cycles
|
||||
for (const cycleNode of node.cycle.nodes) {
|
||||
cycleNode.cycle = cycle;
|
||||
cycle.nodes.add(cycleNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
node.cycle = cycle;
|
||||
cycle.nodes.add(node);
|
||||
sccsToMerge.add(stack[i].node.scc);
|
||||
}
|
||||
for (const sccToMerge of sccsToMerge) {
|
||||
for (const nodeInMergedSCC of sccToMerge.nodes) {
|
||||
nodeInMergedSCC.scc = depSCC;
|
||||
depSCC.nodes.add(nodeInMergedSCC);
|
||||
}
|
||||
}
|
||||
// don't recurse into dependencies
|
||||
// these are already on the stack
|
||||
break;
|
||||
}
|
||||
case DONE_AND_ROOT_MARKER:
|
||||
// This node has be visited yet and is currently a root node
|
||||
// But as this is a new reference to the node
|
||||
// it's not really a root
|
||||
// so we have to convert it to a normal node
|
||||
dependency.marker = DONE_MARKER;
|
||||
roots.delete(dependency);
|
||||
case CANDIDATE_MARKER:
|
||||
// This finished SCC was previously considered as root SCC
|
||||
// We just found a new incoming edge, so it is no longer a candidate
|
||||
rootSCCs.delete(/** @type {SCC<T>} */ (depSCC));
|
||||
depSCC.marker = DONE_MARKER;
|
||||
break;
|
||||
case DONE_MAYBE_ROOT_CYCLE_MARKER:
|
||||
// This node has be visited yet and
|
||||
// is maybe currently part of a completed root cycle
|
||||
// we found a new reference to the cycle
|
||||
// so it's not really a root cycle
|
||||
// remove the cycle from the root cycles
|
||||
// and convert it to a normal node
|
||||
rootCycles.delete(/** @type {Cycle<T>} */ (dependency.cycle));
|
||||
dependency.marker = DONE_MARKER;
|
||||
case DONE_MARKER:
|
||||
// Already finalized and not a candidate
|
||||
break;
|
||||
// DONE_MARKER: nothing to do, don't recurse into dependencies
|
||||
}
|
||||
} else {
|
||||
// All dependencies of the current node has been visited
|
||||
// we leave the node
|
||||
// All dependencies of the current node have been processed
|
||||
// So we leave the node
|
||||
stack.pop();
|
||||
topOfStack.node.marker = DONE_MARKER;
|
||||
// Mark an SCC as DONE only when the popped node is the last
|
||||
// node from that SCC remaining on the current stack.
|
||||
// A -> B -> C -> D
|
||||
// ^ |
|
||||
// |_________|
|
||||
// If `B` is popped and the new stack top is `A`, they are in
|
||||
// different SCCs, so B's SCC can be finalized.
|
||||
if (
|
||||
stack.length &&
|
||||
topOfStack.node.scc !== stack[stack.length - 1].node.scc
|
||||
) {
|
||||
topOfStack.node.scc.marker = DONE_MARKER;
|
||||
}
|
||||
}
|
||||
}
|
||||
const cycle = selectedNode.cycle;
|
||||
if (cycle) {
|
||||
for (const node of cycle.nodes) {
|
||||
node.marker = DONE_MAYBE_ROOT_CYCLE_MARKER;
|
||||
}
|
||||
rootCycles.add(cycle);
|
||||
} else {
|
||||
selectedNode.marker = DONE_AND_ROOT_MARKER;
|
||||
roots.add(selectedNode);
|
||||
}
|
||||
const scc = selectedNode.scc;
|
||||
// This SCC is complete and currently has no known incoming edge
|
||||
scc.marker = CANDIDATE_MARKER;
|
||||
rootSCCs.add(scc);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract roots from root cycles
|
||||
// We take the nodes with most incoming edges
|
||||
// inside of the cycle
|
||||
for (const cycle of rootCycles) {
|
||||
/** @type {Set<T>} */
|
||||
const rootNodes = new Set();
|
||||
|
||||
// For each root SCC, we select node with the most incoming edges
|
||||
// from within the same SCC
|
||||
for (const scc of rootSCCs) {
|
||||
let max = 0;
|
||||
/** @type {Nodes<T>} */
|
||||
const cycleRoots = new Set();
|
||||
const nodes = cycle.nodes;
|
||||
for (const node of nodes) {
|
||||
const nodes = new Set(scc.nodes);
|
||||
for (const node of scc.nodes) {
|
||||
for (const dep of node.dependencies) {
|
||||
if (nodes.has(dep)) {
|
||||
if (scc.nodes.has(dep)) {
|
||||
dep.incoming++;
|
||||
if (dep.incoming < max) continue;
|
||||
if (dep.incoming > max) {
|
||||
cycleRoots.clear();
|
||||
nodes.clear();
|
||||
max = dep.incoming;
|
||||
}
|
||||
cycleRoots.add(dep);
|
||||
nodes.add(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const cycleRoot of cycleRoots) {
|
||||
roots.add(cycleRoot);
|
||||
for (const node of nodes) {
|
||||
rootNodes.add(node.item);
|
||||
}
|
||||
}
|
||||
|
||||
// When roots were found, return them
|
||||
if (roots.size > 0) {
|
||||
return Array.from(roots, (r) => r.item);
|
||||
}
|
||||
// When root nodes were found, return them
|
||||
if (rootNodes.size > 0) return rootNodes;
|
||||
|
||||
throw new Error("Implementation of findGraphRoots is broken");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user