Update npm packages (73 packages including @jqhtml 2.3.36)

Update npm registry domain from privatenpm.hanson.xyz to npm.internal.hanson.xyz

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-02-20 11:31:28 +00:00
parent d01a6179aa
commit b5eb27a827
1690 changed files with 47348 additions and 16848 deletions

4
node_modules/webpack/README.md generated vendored
View File

@@ -69,7 +69,7 @@ or packaging just about any resource or asset.
**TL;DR**
- Bundles [ES Modules](https://www.2ality.com/2014/09/es6-modules-final.html), [CommonJS](http://wiki.commonjs.org/), and [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules (even combined).
- Bundles [ES Modules](https://www.2ality.com/2014/09/es6-modules-final.html), [CommonJS](https://wiki.commonjs.org/), and [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules (even combined).
- Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
- Dependencies are resolved during compilation, reducing the runtime size.
- Loaders can preprocess files while compiling, e.g. TypeScript to JavaScript, Handlebars strings to compiled functions, images to Base64, etc.
@@ -636,7 +636,7 @@ Before we started using OpenCollective, donations were made anonymously. Now tha
<p>(In chronological order)</p>
- [@google](https://github.com/google) for [Google Web Toolkit (GWT)](http://www.gwtproject.org/), which aims to compile Java to JavaScript. It features a similar [Code Splitting](http://www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html) as webpack.
- [@google](https://github.com/google) for [Google Web Toolkit (GWT)](https://www.gwtproject.org/), which aims to compile Java to JavaScript. It features a similar [Code Splitting](https://www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html) as webpack.
- [@medikoo](https://github.com/medikoo) for [modules-webmake](https://github.com/medikoo/modules-webmake), which is a similar project. webpack was born because of the desire for code splitting for modules such as Webmake. Interestingly, the [Code Splitting issue is still open](https://github.com/medikoo/modules-webmake/issues/7) (thanks also to @Phoscur for the discussion).
- [@substack](https://github.com/substack) for [browserify](https://browserify.org/), which is a similar project and source for many ideas.
- [@jrburke](https://github.com/jrburke) for [require.js](https://requirejs.org/), which is a similar project and source for many ideas.

View File

@@ -57,9 +57,11 @@ const isInstalled = (packageName) => {
} while (dir !== (dir = path.dirname(dir)));
// https://github.com/nodejs/node/blob/v18.9.1/lib/internal/modules/cjs/loader.js#L1274
// eslint-disable-next-line no-warning-comments
// @ts-ignore
for (const internalPath of require("module").globalPaths) {
const { globalPaths } =
/** @type {typeof import("module") & { globalPaths: string[] }} */
(require("module"));
for (const internalPath of globalPaths) {
try {
if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) {
return true;
@@ -81,6 +83,7 @@ const runCli = (cli) => {
const pkgPath = require.resolve(`${cli.package}/package.json`);
/** @type {Record<string, EXPECTED_ANY> & { type: string, bin: Record<string, string> }} */
const pkg = require(pkgPath);
if (pkg.type === "module" || /\.mjs/i.test(pkg.bin[cli.binName])) {

100
node_modules/webpack/lib/APIPlugin.js generated vendored
View File

@@ -16,6 +16,8 @@ const {
const RuntimeGlobals = require("./RuntimeGlobals");
const WebpackError = require("./WebpackError");
const ConstDependency = require("./dependencies/ConstDependency");
const ModuleInitFragmentDependency = require("./dependencies/ModuleInitFragmentDependency");
const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
const {
@@ -32,7 +34,7 @@ const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
/** @typedef {import("./javascript/JavascriptParser").Range} Range */
/**
* @returns {Record<string, {expr: string, req: string[] | null, type?: string, assign: boolean}>} replacements
* @returns {Record<string, { expr: string, req: string[] | null, type?: string, assign: boolean }>} replacements
*/
function getReplacements() {
return {
@@ -160,6 +162,10 @@ class APIPlugin {
ConstDependency,
new ConstDependency.Template()
);
compilation.dependencyTemplates.set(
ModuleInitFragmentDependency,
new ModuleInitFragmentDependency.Template()
);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.chunkName)
@@ -201,6 +207,40 @@ class APIPlugin {
* @param {JavascriptParser} parser the parser
*/
const handler = (parser) => {
parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator) => {
if (
parser.scope.topLevelScope === true &&
declarator.id.type === "Identifier" &&
declarator.id.name === "module"
) {
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleArgument =
"__webpack_module__";
}
});
parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
if (parser.scope.topLevelScope === true) {
if (
statement.type === "FunctionDeclaration" &&
statement.id &&
statement.id.name === "module"
) {
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleArgument =
"__webpack_module__";
} else if (
statement.type === "ClassDeclaration" &&
statement.id &&
statement.id.name === "module"
) {
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleArgument =
"__webpack_module__";
}
}
});
for (const key of Object.keys(REPLACEMENTS)) {
const info = REPLACEMENTS[key];
parser.hooks.expression.for(key).tap(PLUGIN_NAME, (expression) => {
@@ -275,13 +315,28 @@ class APIPlugin {
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleConcatenationBailout =
"__webpack_module__.id";
const dep = new ConstDependency(
`${parser.state.module.moduleArgument}.id`,
/** @type {Range} */ (expr.range),
[RuntimeGlobals.moduleId]
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
const moduleArgument = parser.state.module.moduleArgument;
if (moduleArgument === "__webpack_module__") {
const dep = new RuntimeRequirementsDependency([
RuntimeGlobals.moduleId
]);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
} else {
const initDep = new ModuleInitFragmentDependency(
`var __webpack_internal_module_id__ = ${moduleArgument}.id;\n`,
[RuntimeGlobals.moduleId],
"__webpack_internal_module_id__"
);
parser.state.module.addPresentationalDependency(initDep);
const dep = new ConstDependency(
"__webpack_internal_module_id__",
/** @type {Range} */ (expr.range),
[]
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
}
return true;
});
@@ -291,13 +346,28 @@ class APIPlugin {
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleConcatenationBailout =
"__webpack_module__";
const dep = new ConstDependency(
parser.state.module.moduleArgument,
/** @type {Range} */ (expr.range),
[RuntimeGlobals.module]
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
const moduleArgument = parser.state.module.moduleArgument;
if (moduleArgument === "__webpack_module__") {
const dep = new RuntimeRequirementsDependency([
RuntimeGlobals.module
]);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
} else {
const initDep = new ModuleInitFragmentDependency(
`var __webpack_internal_module__ = ${moduleArgument};\n`,
[RuntimeGlobals.module],
"__webpack_internal_module__"
);
parser.state.module.addPresentationalDependency(initDep);
const dep = new ConstDependency(
"__webpack_internal_module__",
/** @type {Range} */ (expr.range),
[]
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addPresentationalDependency(dep);
}
return true;
});
parser.hooks.evaluateTypeof

View File

@@ -48,6 +48,7 @@ function Message() {
class AbstractMethodError extends WebpackError {
constructor() {
super(new Message().message);
/** @type {string} */
this.name = "AbstractMethodError";
}
}

View File

@@ -16,11 +16,11 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./util/Hash")} Hash */
/** @typedef {(ChunkGroupOptions & { entryOptions?: EntryOptions }) | string} GroupOptions */
/** @typedef {(ChunkGroupOptions & { entryOptions?: EntryOptions } & { circular?: boolean })} GroupOptions */
class AsyncDependenciesBlock extends DependenciesBlock {
/**
* @param {GroupOptions | null} groupOptions options for the group
* @param {GroupOptions | string | null} groupOptions options for the group
* @param {(DependencyLocation | null)=} loc the line of code
* @param {(string | null)=} request the request
*/
@@ -31,9 +31,17 @@ class AsyncDependenciesBlock extends DependenciesBlock {
} else if (!groupOptions) {
groupOptions = { name: undefined };
}
if (typeof groupOptions.circular !== "boolean") {
// default allow circular references
groupOptions.circular = true;
}
/** @type {GroupOptions} */
this.groupOptions = groupOptions;
/** @type {DependencyLocation | null | undefined} */
this.loc = loc;
/** @type {string | null | undefined} */
this.request = request;
/** @type {undefined | string} */
this._stringifiedGroupOptions = undefined;
}
@@ -55,6 +63,13 @@ class AsyncDependenciesBlock extends DependenciesBlock {
}
}
/**
* @returns {boolean} Whether circular references are allowed
*/
get circular() {
return Boolean(this.groupOptions.circular);
}
/**
* @param {Hash} hash the hash used to track dependencies
* @param {UpdateHashContext} context context

View File

@@ -22,8 +22,11 @@ class AsyncDependencyToInitialChunkError extends WebpackError {
`It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.`
);
/** @type {string} */
this.name = "AsyncDependencyToInitialChunkError";
/** @type {Module} */
this.module = module;
/** @type {DependencyLocation} */
this.loc = loc;
}
}

View File

@@ -29,7 +29,7 @@ class AutomaticPrefetchPlugin {
);
}
);
/** @type {{context: string | null, request: string}[] | null} */
/** @type {{ context: string | null, request: string }[] | null} */
let lastModules = null;
compiler.hooks.afterCompile.tap(PLUGIN_NAME, (compilation) => {
lastModules = [];

View File

@@ -11,12 +11,15 @@ const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const Template = require("./Template");
const createSchemaValidation = require("./util/create-schema-validation");
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerFunction} BannerFunction */
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
/** @typedef {import("./Compilation").PathData} PathData */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
/** @typedef {(data: { hash?: string, chunk: Chunk, filename: string }) => string} BannerFunction */
const validate = createSchemaValidation(
/** @type {((value: typeof import("../schemas/plugins/BannerPlugin.json")) => boolean)} */
(require("../schemas/plugins/BannerPlugin.check")),
@@ -88,6 +91,7 @@ class BannerPlugin {
undefined,
options
);
/** @type {WeakMap<Source, { source: ConcatSource, comment: string }>} */
const cache = new WeakMap();
const stage =
this.options.stage || Compilation.PROCESS_ASSETS_STAGE_ADDITIONS;

View File

@@ -13,7 +13,7 @@ const mergeEtags = require("./cache/mergeEtags");
/** @typedef {import("./Cache")} Cache */
/** @typedef {import("./Cache").Etag} Etag */
/** @typedef {import("./cache/getLazyHashedEtag").HashableObject} HashableObject */
/** @typedef {typeof import("./util/Hash")} HashConstructor */
/** @typedef {import("./util/Hash").HashFunction} HashFunction */
/**
* @template T
@@ -196,7 +196,7 @@ class CacheFacade {
/**
* @param {Cache} cache the root cache
* @param {string} name the child cache name
* @param {(string | HashConstructor)=} hashFunction the hash function to use
* @param {HashFunction=} hashFunction the hash function to use
*/
constructor(cache, name, hashFunction) {
this._cache = cache;

View File

@@ -63,6 +63,7 @@ This can lead to unexpected behavior when compiling on a filesystem with other c
Use equal casing. Compare these module identifiers:
${modulesList}`);
/** @type {string} */
this.name = "CaseSensitiveModulesWarning";
this.module = sortedModules[0];
}

14
node_modules/webpack/lib/Chunk.js generated vendored
View File

@@ -67,6 +67,7 @@ const ChunkFilesSet = createArrayToSetDeprecationSet("chunk.files");
/** @typedef {SortableSet<ChunkGroup>} SortableChunkGroups */
/** @typedef {Record<string, ChunkId[]>} ChunkChildIdsByOrdersMap */
/** @typedef {Record<string, ChunkChildIdsByOrdersMap>} ChunkChildIdsByOrdersMapByData */
/** @typedef {{ onChunks: Chunk[], chunks: Chunks }} ChunkChildOfTypeInOrder */
let debugId = 1000;
@@ -719,7 +720,7 @@ class Chunk {
* @returns {Record<string, ChunkId[]>} a record object of names to lists of child ids(?)
*/
getChildIdsByOrders(chunkGraph, filterFn) {
/** @type {Map<string, {order: number, group: ChunkGroup}[]>} */
/** @type {Map<string, { order: number, group: ChunkGroup }[]>} */
const lists = new Map();
for (const group of this.groupsIterable) {
if (group.chunks[group.chunks.length - 1] === this) {
@@ -774,14 +775,16 @@ class Chunk {
/**
* @param {ChunkGraph} chunkGraph the chunk graph
* @param {string} type option name
* @returns {{ onChunks: Chunk[], chunks: Chunks }[] | undefined} referenced chunks for a specific type
* @returns {ChunkChildOfTypeInOrder[] | undefined} referenced chunks for a specific type
*/
getChildrenOfTypeInOrder(chunkGraph, type) {
/** @type {{ order: number, group: ChunkGroup, childGroup: ChunkGroup }[]} */
const list = [];
for (const group of this.groupsIterable) {
for (const childGroup of group.childrenIterable) {
const order =
childGroup.options[/** @type {keyof ChunkGroupOptions} */ (type)];
/** @type {number} */
(childGroup.options[/** @type {keyof ChunkGroupOptions} */ (type)]);
if (order === undefined) continue;
list.push({
order,
@@ -792,12 +795,13 @@ class Chunk {
}
if (list.length === 0) return;
list.sort((a, b) => {
const cmp =
/** @type {number} */ (b.order) - /** @type {number} */ (a.order);
const cmp = b.order - a.order;
if (cmp !== 0) return cmp;
return a.group.compareTo(chunkGraph, b.group);
});
/** @type {ChunkChildOfTypeInOrder[]} */
const result = [];
/** @type {undefined | ChunkChildOfTypeInOrder} */
let lastEntry;
for (const { group, childGroup } of list) {
if (lastEntry && lastEntry.onChunks === group.chunks) {

View File

@@ -43,7 +43,7 @@ const {
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
/** @typedef {import("./RuntimeModule")} RuntimeModule */
/** @typedef {typeof import("./util/Hash")} Hash */
/** @typedef {import("./util/Hash").HashFunction} HashFunction */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
/** @type {ReadonlySet<string>} */
@@ -69,7 +69,9 @@ class ModuleHashInfo {
* @param {string} renderedHash rendered hash
*/
constructor(hash, renderedHash) {
/** @type {string} */
this.hash = hash;
/** @type {string} */
this.renderedHash = renderedHash;
}
}
@@ -95,10 +97,11 @@ const getModuleRuntimes = (chunks) => {
/**
* @param {SourceTypesByModule | undefined} sourceTypesByModule sourceTypesByModule
* @returns {(set: SortableSet<Module>) => Map<string, SortableSet<Module>>} modules by source type
* @returns {ModulesBySourceType} modules by source type
*/
const modulesBySourceType = (sourceTypesByModule) => (set) => {
/** @type {Map<SourceType, SortableSet<Module>>} */
/** @typedef {SortableSet<Module>} ModuleSortableSet */
/** @type {Map<SourceType, ModuleSortableSet>} */
const map = new Map();
for (const module of set) {
const sourceTypes =
@@ -107,6 +110,7 @@ const modulesBySourceType = (sourceTypesByModule) => (set) => {
for (const sourceType of sourceTypes) {
let innerSet = map.get(sourceType);
if (innerSet === undefined) {
/** @type {ModuleSortableSet} */
innerSet = new SortableSet();
map.set(sourceType, innerSet);
}
@@ -122,6 +126,10 @@ const modulesBySourceType = (sourceTypesByModule) => (set) => {
}
return map;
};
/** @typedef {(set: SortableSet<Module>) => Map<string, SortableSet<Module>>} ModulesBySourceType */
/** @type {ModulesBySourceType} */
const defaultModulesBySourceType = modulesBySourceType(undefined);
/**
@@ -164,11 +172,14 @@ const getModulesSize = (modules) => {
return size;
};
/** @typedef {Record<string, number>} SizesOfModules */
/**
* @param {Iterable<Module>} modules the sortable Set to get the size of
* @returns {Record<string, number>} the sizes of the modules
* @returns {SizesOfModules} the sizes of the modules
*/
const getModulesSizes = (modules) => {
/** @type {SizesOfModules} */
const sizes = Object.create(null);
for (const module of modules) {
for (const type of module.getSourceTypes()) {
@@ -199,6 +210,7 @@ const isAvailableChunk = (a, b) => {
/** @typedef {Set<Chunk>} EntryInChunks */
/** @typedef {Set<Chunk>} RuntimeInChunks */
/** @typedef {string | number} ModuleId */
/** @typedef {RuntimeSpecMap<Set<string>, RuntimeRequirements>} ChunkGraphRuntimeRequirements */
class ChunkGraphModule {
constructor() {
@@ -212,7 +224,7 @@ class ChunkGraphModule {
this.hashes = undefined;
/** @type {ModuleId | null} */
this.id = null;
/** @type {RuntimeSpecMap<Set<string>, RuntimeRequirements> | undefined} */
/** @type {ChunkGraphRuntimeRequirements | undefined} */
this.runtimeRequirements = undefined;
/** @type {RuntimeSpecMap<string, bigint> | undefined} */
this.graphHashes = undefined;
@@ -242,7 +254,7 @@ class ChunkGraphChunk {
this.runtimeRequirements = undefined;
/** @type {Set<string>} */
this.runtimeRequirementsInTree = new Set();
/** @type {ModulesBySourceType} */
this._modulesBySourceType = defaultModulesBySourceType;
}
}
@@ -251,13 +263,14 @@ class ChunkGraphChunk {
/** @typedef {Record<ModuleId, string>} IdToHashMap */
/** @typedef {Record<ChunkId, IdToHashMap>} ChunkModuleHashMap */
/** @typedef {Record<ChunkId, ModuleId[]>} ChunkModuleIdMap */
/** @typedef {Record<ChunkId, boolean>} ChunkConditionMap */
/** @typedef {(a: Module, b: Module) => -1 | 0 | 1} ModuleComparator */
class ChunkGraph {
/**
* @param {ModuleGraph} moduleGraph the module graph
* @param {string | Hash} hashFunction the hash function to use
* @param {HashFunction} hashFunction the hash function to use
*/
constructor(moduleGraph, hashFunction = DEFAULTS.HASH_FUNCTION) {
/**
@@ -809,6 +822,7 @@ class ChunkGraph {
)) {
if (filterFn(module)) {
if (idToHashMap === undefined) {
/** @type {IdToHashMap} */
idToHashMap = Object.create(null);
chunkModuleHashMap[/** @type {ChunkId} */ (asyncChunk.id)] =
/** @type {IdToHashMap} */
@@ -830,9 +844,10 @@ class ChunkGraph {
/**
* @param {Chunk} chunk the chunk
* @param {ChunkFilterPredicate} filterFn function used to filter chunks
* @returns {Record<ChunkId, boolean>} chunk map
* @returns {ChunkConditionMap} chunk condition map
*/
getChunkConditionMap(chunk, filterFn) {
/** @type {ChunkConditionMap} */
const map = Object.create(null);
for (const c of chunk.getAllReferencedChunks()) {
map[/** @type {ChunkId} */ (c.id)] = filterFn(c, this);
@@ -848,6 +863,7 @@ class ChunkGraph {
*/
hasModuleInGraph(chunk, filterFn, filterChunkFn) {
const queue = new Set(chunk.groupsIterable);
/** @type {Set<Chunk>} */
const chunksProcessed = new Set();
for (const chunkGroup of queue) {
@@ -1556,6 +1572,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
const cgm = this._getChunkGraphModule(module);
const runtimeRequirementsMap = cgm.runtimeRequirements;
if (runtimeRequirementsMap === undefined) {
/** @type {ChunkGraphRuntimeRequirements} */
const map = new RuntimeSpecMap();
// TODO avoid cloning item and track ownership instead
map.set(runtime, transferOwnership ? items : new Set(items));
@@ -1740,6 +1757,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
} else {
// cspell:word Tnamespace
for (const connection of connections) {
/** @type {Set<ConnectionState>} */
const states = new Set();
let stateInfo = "";
forEachRuntime(
@@ -1754,7 +1772,10 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
if (states.size === 1) {
const state = first(states);
if (state === false) continue;
stateInfo = activeStateToString(state);
stateInfo = activeStateToString(
/** @type {ConnectionState} */
(state)
);
}
processConnection(connection, stateInfo);
}

View File

@@ -56,7 +56,7 @@ const sortById = (a, b) => {
/**
* @param {OriginRecord} a the first comparator in sort
* @param {OriginRecord} b the second comparator in sort
* @returns {1 | -1| 0} returns sorting order as index
* @returns {1 | -1 | 0} returns sorting order as index
*/
const sortOrigin = (a, b) => {
const aIdent = a.module ? a.module.identifier() : "";
@@ -79,13 +79,15 @@ class ChunkGroup {
}
/** @type {number} */
this.groupDebugId = debugId++;
this.options = /** @type {ChunkGroupOptions} */ (options);
/** @type {ChunkGroupOptions} */
this.options = options;
/** @type {SortableSet<ChunkGroup>} */
this._children = new SortableSet(undefined, sortById);
/** @type {SortableSet<ChunkGroup>} */
this._parents = new SortableSet(undefined, sortById);
/** @type {SortableSet<ChunkGroup>} */
this._asyncEntrypoints = new SortableSet(undefined, sortById);
/** @type {SortableSet<AsyncDependenciesBlock>} */
this._blocks = new SortableSet();
/** @type {Chunk[]} */
this.chunks = [];
@@ -429,6 +431,7 @@ class ChunkGroup {
* @returns {string[]} the files contained this chunk group
*/
getFiles() {
/** @type {Set<string>} */
const files = new Set();
for (const chunk of this.chunks) {
@@ -505,7 +508,7 @@ class ChunkGroup {
* @returns {Record<string, ChunkGroup[]>} mapping from children type to ordered list of ChunkGroups
*/
getChildrenByOrders(moduleGraph, chunkGraph) {
/** @type {Map<string, {order: number, group: ChunkGroup}[]>} */
/** @type {Map<string, { order: number, group: ChunkGroup }[]>} */
const lists = new Map();
for (const childGroup of this._children) {
for (const key of Object.keys(childGroup.options)) {

View File

@@ -19,13 +19,20 @@ class ChunkRenderError extends WebpackError {
constructor(chunk, file, error) {
super();
/** @type {string} */
this.name = "ChunkRenderError";
this.error = error;
this.message = error.message;
this.details = error.stack;
this.file = file;
/** @type {Chunk} */
this.chunk = chunk;
/** @type {string} */
this.file = file;
/** @type {Error} */
this.error = error;
/** @type {string} */
this.message = error.message;
/** @type {string} */
this.details = error.stack;
}
}
/** @type {typeof ChunkRenderError} */
module.exports = ChunkRenderError;

View File

@@ -70,6 +70,7 @@ const mergeAssets = (as1, as2) => {
* @returns {Set<string>} Set of directory paths
*/
function getDirectories(assets) {
/** @type {Set<string>} */
const directories = new Set();
/**
* @param {string} filename asset filename
@@ -143,6 +144,7 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
* @returns {Diff} diff
*/
const getDiffToOldAssets = (currentAssets, oldAssets) => {
/** @type {Diff} */
const diff = new Set();
const now = Date.now();
for (const [asset, ts] of oldAssets) {
@@ -416,7 +418,8 @@ class CleanPlugin {
const currentAssets = new Map();
const now = Date.now();
for (const asset of Object.keys(compilation.assets)) {
if (/^[A-Za-z]:\\|^\/|^\\\\/.test(asset)) continue;
if (/^[a-z]:\\|^\/|^\\\\/i.test(asset)) continue;
/** @type {string} */
let normalizedAsset;
let newNormalizedAsset = asset.replace(/\\/g, "/");
do {

View File

@@ -18,12 +18,18 @@ class CodeGenerationError extends WebpackError {
constructor(module, error) {
super();
/** @type {string} */
this.name = "CodeGenerationError";
this.error = error;
this.message = error.message;
this.details = error.stack;
/** @type {Module} */
this.module = module;
/** @type {Error} */
this.error = error;
/** @type {string} */
this.message = error.message;
/** @type {string} */
this.details = error.stack;
}
}
/** @type {typeof CodeGenerationError} */
module.exports = CodeGenerationError;

View File

@@ -17,16 +17,17 @@ const { RuntimeSpecMap, runtimeToString } = require("./util/runtime");
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
/** @typedef {typeof import("./util/Hash")} Hash */
/** @typedef {import("./util/Hash").HashFunction} HashFunction */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
class CodeGenerationResults {
/**
* @param {string | Hash} hashFunction the hash function to use
* @param {HashFunction} hashFunction the hash function to use
*/
constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
/** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */
this.map = new Map();
/** @type {HashFunction} */
this._hashFunction = hashFunction;
}
@@ -152,7 +153,13 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
* @returns {void}
*/
add(module, runtime, result) {
const map = getOrInsert(this.map, module, () => new RuntimeSpecMap());
const map = getOrInsert(
this.map,
module,
() =>
/** @type {RuntimeSpecMap<CodeGenerationResult>} */
new RuntimeSpecMap()
);
map.set(runtime, result);
}
}

View File

@@ -18,8 +18,9 @@ class CommentCompilationWarning extends WebpackError {
constructor(message, loc) {
super(message);
/** @type {string} */
this.name = "CommentCompilationWarning";
/** @type {DependencyLocation} */
this.loc = loc;
}
}

View File

@@ -286,7 +286,7 @@ const { isSourceEqual } = require("./util/source");
/**
* @typedef {object} LogEntry
* @property {string} type
* @property {keyof LogType} type
* @property {EXPECTED_ANY[]=} args
* @property {number} time
* @property {string[]=} trace
@@ -403,11 +403,11 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {KnownCreateStatsOptionsContext & Record<string, EXPECTED_ANY>} CreateStatsOptionsContext */
/** @typedef {{ module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}} CodeGenerationJob */
/** @typedef {{ module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[] }} CodeGenerationJob */
/** @typedef {CodeGenerationJob[]} CodeGenerationJobs */
/** @typedef {{javascript: ModuleTemplate}} ModuleTemplates */
/** @typedef {{ javascript: ModuleTemplate }} ModuleTemplates */
/** @typedef {Set<Module>} NotCodeGeneratedModules */
@@ -491,6 +491,8 @@ const compareErrors = concatComparators(byModule, byLocation, byMessage);
* @typedef {Module & { restoreFromUnsafeCache?: (unsafeCacheData: UnsafeCacheData, moduleFactory: ModuleFactory, compilationParams: CompilationParams) => void }} ModuleWithRestoreFromUnsafeCache
*/
/** @typedef {(module: Module) => boolean} UnsafeCachePredicate */
/** @type {WeakMap<Dependency, ModuleWithRestoreFromUnsafeCache | null>} */
const unsafeCacheDependencies = new WeakMap();
@@ -514,22 +516,25 @@ class Compilation {
/** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */
const processAssetsHook = new AsyncSeriesHook(["assets"]);
/** @type {Set<string>} */
let savedAssets = new Set();
/**
* @param {CompilationAssets} assets assets
* @returns {CompilationAssets} new assets
*/
const popNewAssets = (assets) => {
/** @type {undefined | CompilationAssets} */
let newAssets;
for (const file of Object.keys(assets)) {
if (savedAssets.has(file)) continue;
if (newAssets === undefined) {
newAssets = Object.create(null);
}
newAssets[file] = assets[file];
/** @type {CompilationAssets} */
(newAssets)[file] = assets[file];
savedAssets.add(file);
}
return newAssets;
return /** @type {CompilationAssets} */ (newAssets);
};
processAssetsHook.intercept({
name: "Compilation",
@@ -1257,7 +1262,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this._codeGenerationCache = this.getCache("Compilation/codeGeneration");
const unsafeCache = options.module.unsafeCache;
/** @type {boolean} */
this._unsafeCache = Boolean(unsafeCache);
/** @type {UnsafeCachePredicate} */
this._unsafeCachePredicate =
typeof unsafeCache === "function" ? unsafeCache : () => true;
}
@@ -1347,6 +1354,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
);
}
}
/** @type {LogEntry["trace"]} */
let trace;
switch (type) {
case LogType.warn:
@@ -1519,7 +1527,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
/**
* Attempts to search for a module by its identifier
* @param {string} identifier identifier (usually path) for module
* @returns {Module|undefined} attempt to search for module and return it, else undefined
* @returns {Module | undefined} attempt to search for module and return it, else undefined
*/
findModule(identifier) {
return this._modules.get(identifier);
@@ -2292,6 +2300,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
(originModule)
);
if (creatingModuleDuringBuildSet === undefined) {
/** @type {Set<Module>} */
creatingModuleDuringBuildSet = new Set();
this.creatingModuleDuringBuild.set(
/** @type {Module} */
@@ -2598,7 +2607,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.moduleGraph.setModuleMemCaches(this.moduleMemCaches);
}
const { moduleGraph, moduleMemCaches } = this;
/** @type {Set<Module>} */
const affectedModules = new Set();
/** @type {Set<Module>} */
const infectedModules = new Set();
let statNew = 0;
let statChanged = 0;
@@ -2714,6 +2725,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
}
return affected;
};
/** @type {Set<Module>} */
const directOnlyInfectedModules = new Set();
for (const module of infectedModules) {
for (const [
@@ -2732,6 +2744,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
}
}
for (const module of directOnlyInfectedModules) infectedModules.add(module);
/** @type {Set<Module>} */
const directOnlyAffectModules = new Set();
for (const module of affectedModules) {
for (const [
@@ -2994,6 +3007,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback
*/
const logByLoadersSummary = (category, getDuration, getParallelism) => {
/** @type {Map<string, { module: Module, profile: ModuleProfile }[]>} */
const map = new Map();
for (const [module, profile] of modulesWithProfiles) {
const list = getOrInsert(
@@ -3205,6 +3219,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.chunkGroups.push(entrypoint);
connectChunkGroupAndChunk(entrypoint, chunk);
/** @type {Set<Module>} */
const entryModules = new Set();
for (const dep of [...this.globalEntry.dependencies, ...dependencies]) {
entrypoint.addOrigin(
@@ -3252,6 +3267,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
modulesList.push(module);
}
}
/** @type {Set<Chunk>} */
const runtimeChunks = new Set();
outer: for (const [
name,
@@ -3625,6 +3641,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
const runIteration = () => {
/** @type {CodeGenerationJobs} */
let delayedJobs = [];
/** @type {Set<Module>} */
let delayedModules = new Set();
asyncLib.eachLimit(
jobs,
@@ -3668,7 +3685,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
);
},
(err) => {
if (err) return callback(err);
if (err) return callback(/** @type {WebpackError} */ (err));
if (delayedJobs.length > 0) {
if (delayedJobs.length === jobs.length) {
return callback(
@@ -3746,6 +3763,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
);
cache.get((err, cachedResult) => {
if (err) return callback(/** @type {WebpackError} */ (err));
/** @type {CodeGenerationResult} */
let result;
if (!cachedResult) {
try {
@@ -3845,6 +3863,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
continue;
}
}
/** @type {RuntimeRequirements} */
let set;
const runtimeRequirements =
codeGenerationResults.getRuntimeRequirements(module, runtime);
@@ -4407,6 +4426,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
hashDigestLength,
errors
) {
/** @type {string} */
let moduleHashDigest;
try {
const moduleHash = createHash(hashFunction);
@@ -4529,6 +4549,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
// If there are any references between chunks
// make sure to follow these chains
if (remaining > 0) {
/** @type {Chunk[]} */
const readyChunks = [];
for (const chunk of runtimeChunks) {
const hasFullHashModules =
@@ -4555,6 +4576,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
}
// If there are still remaining references we have cycles and want to create a warning
if (remaining > 0) {
/** @type {RuntimeChunkInfo[]} */
const circularRuntimeChunkInfo = [];
for (const info of runtimeChunksMap.values()) {
if (info.remaining !== 0) {
@@ -4574,6 +4596,7 @@ This prevents using hashes of each other and should be avoided.`);
}
this.logger.timeEnd("hashing: sort chunks");
/** @type {Set<Chunk>} */
const fullHashChunks = new Set();
/** @type {CodeGenerationJobs} */
const codeGenerationJobs = [];
@@ -4702,7 +4725,7 @@ This prevents using hashes of each other and should be avoided.`);
).hash = moduleHashDigest;
}
const chunkHash = createHash(hashFunction);
chunkHash.update(chunk.hash);
chunkHash.update(/** @type {string} */ (chunk.hash));
chunkHash.update(this.hash);
const chunkHashDigest = chunkHash.digest(hashDigest);
chunk.hash = chunkHashDigest;
@@ -4873,6 +4896,7 @@ This prevents using hashes of each other and should be avoided.`);
const related = info.related;
if (!related) continue;
const entry = related[key];
/** @type {string | string[]} */
let newEntry;
if (Array.isArray(entry)) {
newEntry = entry.map((x) => (x === file ? newFile : x));
@@ -5026,8 +5050,9 @@ This prevents using hashes of each other and should be avoided.`);
*/
createChunkAssets(callback) {
const outputOptions = this.outputOptions;
/** @type {WeakMap<Source, CachedSource>} */
const cachedSourceMap = new WeakMap();
/** @type {Map<string, {hash: string, source: Source, chunk: Chunk}>} */
/** @type {Map<string, { hash: string, source: Source, chunk: Chunk }>} */
const alreadyWrittenFiles = new Map();
asyncLib.forEachLimit(
@@ -5392,254 +5417,277 @@ This prevents using hashes of each other and should be avoided.`);
};
// Generate code for all aggregated modules
asyncLib.eachLimit(modules, 10, codeGen, (err) => {
if (err) return callback(err);
reportErrors();
// for backward-compat temporary set the chunk graph
// TODO webpack 6
const old = this.chunkGraph;
this.chunkGraph = chunkGraph;
this.processRuntimeRequirements({
chunkGraph,
modules,
chunks,
codeGenerationResults,
chunkGraphEntries: chunks
});
this.chunkGraph = old;
const runtimeModules =
chunkGraph.getChunkRuntimeModulesIterable(chunk);
// Hash runtime modules
for (const module of runtimeModules) {
modules.add(module);
this._createModuleHash(
module,
chunkGraph,
runtime,
hashFunction,
runtimeTemplate,
hashDigest,
hashDigestLength,
errors
);
}
// Generate code for all runtime modules
asyncLib.eachLimit(runtimeModules, 10, codeGen, (err) => {
asyncLib.eachLimit(
/** @type {import("neo-async").IterableCollection<Module>} */ (
/** @type {unknown} */ (modules)
),
10,
codeGen,
(err) => {
if (err) return callback(err);
reportErrors();
/** @type {Map<Module, ExecuteModuleArgument>} */
const moduleArgumentsMap = new Map();
/** @type {Map<string, ExecuteModuleArgument>} */
const moduleArgumentsById = new Map();
/** @type {ExecuteModuleResult["fileDependencies"]} */
const fileDependencies = new LazySet();
/** @type {ExecuteModuleResult["contextDependencies"]} */
const contextDependencies = new LazySet();
/** @type {ExecuteModuleResult["missingDependencies"]} */
const missingDependencies = new LazySet();
/** @type {ExecuteModuleResult["buildDependencies"]} */
const buildDependencies = new LazySet();
/** @type {ExecuteModuleResult["assets"]} */
const assets = new Map();
let cacheable = true;
/** @type {ExecuteModuleContext} */
const context = {
assets,
__webpack_require__: undefined,
chunk,
chunkGraph
};
// Prepare execution
asyncLib.eachLimit(
// for backward-compat temporary set the chunk graph
// TODO webpack 6
const old = this.chunkGraph;
this.chunkGraph = chunkGraph;
this.processRuntimeRequirements({
chunkGraph,
modules,
chunks,
codeGenerationResults,
chunkGraphEntries: chunks
});
this.chunkGraph = old;
const runtimeModules =
chunkGraph.getChunkRuntimeModulesIterable(chunk);
// Hash runtime modules
for (const module of runtimeModules) {
modules.add(module);
this._createModuleHash(
module,
chunkGraph,
runtime,
hashFunction,
runtimeTemplate,
hashDigest,
hashDigestLength,
errors
);
}
// Generate code for all runtime modules
asyncLib.eachLimit(
/** @type {import("neo-async").IterableCollection<RuntimeModule>} */ (
runtimeModules
),
10,
(module, callback) => {
const codeGenerationResult = codeGenerationResults.get(
module,
runtime
);
/** @type {ExecuteModuleArgument} */
const moduleArgument = {
module,
codeGenerationResult,
moduleObject: undefined
};
moduleArgumentsMap.set(module, moduleArgument);
moduleArgumentsById.set(module.identifier(), moduleArgument);
module.addCacheDependencies(
fileDependencies,
contextDependencies,
missingDependencies,
buildDependencies
);
if (
/** @type {BuildInfo} */ (module.buildInfo).cacheable ===
false
) {
cacheable = false;
}
if (module.buildInfo && module.buildInfo.assets) {
const { assets: moduleAssets, assetsInfo } = module.buildInfo;
for (const assetName of Object.keys(moduleAssets)) {
assets.set(assetName, {
source: moduleAssets[assetName],
info: assetsInfo ? assetsInfo.get(assetName) : undefined
});
}
}
this.hooks.prepareModuleExecution.callAsync(
moduleArgument,
context,
callback
);
},
codeGen,
(err) => {
if (err) return callback(err);
reportErrors();
/** @type {ExecuteModuleExports | undefined} */
let exports;
try {
const {
strictModuleErrorHandling,
strictModuleExceptionHandling
} = this.outputOptions;
/** @type {Map<Module, ExecuteModuleArgument>} */
const moduleArgumentsMap = new Map();
/** @type {Map<string, ExecuteModuleArgument>} */
const moduleArgumentsById = new Map();
/** @type {WebpackRequire} */
const __webpack_require__ = (id) => {
const cached = moduleCache[id];
if (cached !== undefined) {
if (cached.error) throw cached.error;
return cached.exports;
}
const moduleArgument = moduleArgumentsById.get(id);
return __webpack_require_module__(
/** @type {ExecuteModuleArgument} */
(moduleArgument),
id
);
};
const interceptModuleExecution = (__webpack_require__[
/** @type {"i"} */
(
RuntimeGlobals.interceptModuleExecution.replace(
`${RuntimeGlobals.require}.`,
""
)
)
] = /** @type {NonNullable<WebpackRequire["i"]>} */ ([]));
const moduleCache = (__webpack_require__[
/** @type {"c"} */ (
RuntimeGlobals.moduleCache.replace(
`${RuntimeGlobals.require}.`,
""
)
)
] = /** @type {NonNullable<WebpackRequire["c"]>} */ ({}));
/** @type {ExecuteModuleResult["fileDependencies"]} */
const fileDependencies = new LazySet();
/** @type {ExecuteModuleResult["contextDependencies"]} */
const contextDependencies = new LazySet();
/** @type {ExecuteModuleResult["missingDependencies"]} */
const missingDependencies = new LazySet();
/** @type {ExecuteModuleResult["buildDependencies"]} */
const buildDependencies = new LazySet();
context.__webpack_require__ = __webpack_require__;
/** @type {ExecuteModuleResult["assets"]} */
const assets = new Map();
/**
* @param {ExecuteModuleArgument} moduleArgument the module argument
* @param {string=} id id
* @returns {ExecuteModuleExports} exports
*/
const __webpack_require_module__ = (moduleArgument, id) => {
/** @type {ExecuteOptions} */
const execOptions = {
id,
module: {
id,
exports: {},
loaded: false,
error: undefined
},
require: __webpack_require__
};
for (const handler of interceptModuleExecution) {
handler(execOptions);
}
const module = moduleArgument.module;
this.buildTimeExecutedModules.add(module);
const moduleObject = execOptions.module;
moduleArgument.moduleObject = moduleObject;
try {
if (id) moduleCache[id] = moduleObject;
let cacheable = true;
tryRunOrWebpackError(
() =>
this.hooks.executeModule.call(
moduleArgument,
context
),
"Compilation.hooks.executeModule"
);
moduleObject.loaded = true;
return moduleObject.exports;
} catch (execErr) {
if (strictModuleExceptionHandling) {
if (id) delete moduleCache[id];
} else if (strictModuleErrorHandling) {
moduleObject.error =
/** @type {WebpackError} */
(execErr);
}
if (!(/** @type {WebpackError} */ (execErr).module)) {
/** @type {WebpackError} */
(execErr).module = module;
}
throw execErr;
}
};
for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
chunk
)) {
__webpack_require_module__(
/** @type {ExecuteModuleArgument} */
(moduleArgumentsMap.get(runtimeModule))
);
}
exports = __webpack_require__(module.identifier());
} catch (execErr) {
const { message, stack, module } =
/** @type {WebpackError} */
(execErr);
const err = new WebpackError(
`Execution of module code from module graph (${
/** @type {Module} */
(module).readableIdentifier(this.requestShortener)
}) failed: ${message}`,
{ cause: execErr }
);
err.stack = stack;
err.module = module;
return callback(err);
}
callback(null, {
exports,
/** @type {ExecuteModuleContext} */
const context = {
assets,
cacheable,
fileDependencies,
contextDependencies,
missingDependencies,
buildDependencies
});
__webpack_require__: undefined,
chunk,
chunkGraph
};
// Prepare execution
asyncLib.eachLimit(
modules,
10,
(module, callback) => {
const codeGenerationResult = codeGenerationResults.get(
module,
runtime
);
/** @type {ExecuteModuleArgument} */
const moduleArgument = {
module,
codeGenerationResult,
moduleObject: undefined
};
moduleArgumentsMap.set(module, moduleArgument);
moduleArgumentsById.set(
module.identifier(),
moduleArgument
);
module.addCacheDependencies(
fileDependencies,
contextDependencies,
missingDependencies,
buildDependencies
);
if (
/** @type {BuildInfo} */ (module.buildInfo).cacheable ===
false
) {
cacheable = false;
}
if (module.buildInfo && module.buildInfo.assets) {
const { assets: moduleAssets, assetsInfo } =
module.buildInfo;
for (const assetName of Object.keys(moduleAssets)) {
assets.set(assetName, {
source: moduleAssets[assetName],
info: assetsInfo
? assetsInfo.get(assetName)
: undefined
});
}
}
this.hooks.prepareModuleExecution.callAsync(
moduleArgument,
context,
callback
);
},
(err) => {
if (err) return callback(/** @type {WebpackError} */ (err));
/** @type {ExecuteModuleExports | undefined} */
let exports;
try {
const {
strictModuleErrorHandling,
strictModuleExceptionHandling
} = this.outputOptions;
/** @type {WebpackRequire} */
const __webpack_require__ = (id) => {
const cached = moduleCache[id];
if (cached !== undefined) {
if (cached.error) throw cached.error;
return cached.exports;
}
const moduleArgument = moduleArgumentsById.get(id);
return __webpack_require_module__(
/** @type {ExecuteModuleArgument} */
(moduleArgument),
id
);
};
const interceptModuleExecution = (__webpack_require__[
/** @type {"i"} */
(
RuntimeGlobals.interceptModuleExecution.replace(
`${RuntimeGlobals.require}.`,
""
)
)
] = /** @type {NonNullable<WebpackRequire["i"]>} */ ([]));
const moduleCache = (__webpack_require__[
/** @type {"c"} */ (
RuntimeGlobals.moduleCache.replace(
`${RuntimeGlobals.require}.`,
""
)
)
] = /** @type {NonNullable<WebpackRequire["c"]>} */ ({}));
context.__webpack_require__ = __webpack_require__;
/**
* @param {ExecuteModuleArgument} moduleArgument the module argument
* @param {string=} id id
* @returns {ExecuteModuleExports} exports
*/
const __webpack_require_module__ = (
moduleArgument,
id
) => {
/** @type {ExecuteOptions} */
const execOptions = {
id,
module: {
id,
exports: {},
loaded: false,
error: undefined
},
require: __webpack_require__
};
for (const handler of interceptModuleExecution) {
handler(execOptions);
}
const module = moduleArgument.module;
this.buildTimeExecutedModules.add(module);
const moduleObject = execOptions.module;
moduleArgument.moduleObject = moduleObject;
try {
if (id) moduleCache[id] = moduleObject;
tryRunOrWebpackError(
() =>
this.hooks.executeModule.call(
moduleArgument,
context
),
"Compilation.hooks.executeModule"
);
moduleObject.loaded = true;
return moduleObject.exports;
} catch (execErr) {
if (strictModuleExceptionHandling) {
if (id) delete moduleCache[id];
} else if (strictModuleErrorHandling) {
moduleObject.error =
/** @type {WebpackError} */
(execErr);
}
if (!(/** @type {WebpackError} */ (execErr).module)) {
/** @type {WebpackError} */
(execErr).module = module;
}
throw execErr;
}
};
for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
chunk
)) {
__webpack_require_module__(
/** @type {ExecuteModuleArgument} */
(moduleArgumentsMap.get(runtimeModule))
);
}
exports = __webpack_require__(module.identifier());
} catch (execErr) {
const { message, stack, module } =
/** @type {WebpackError} */
(execErr);
const err = new WebpackError(
`Execution of module code from module graph (${
/** @type {Module} */
(module).readableIdentifier(this.requestShortener)
}) failed: ${message}`,
{ cause: execErr }
);
err.stack = stack;
err.module = module;
return callback(err);
}
callback(null, {
exports,
assets,
cacheable,
fileDependencies,
contextDependencies,
missingDependencies,
buildDependencies
});
}
);
}
);
});
});
}
);
}
);
}

View File

@@ -39,7 +39,7 @@ const webpack = require(".");
/** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("../declarations/WebpackOptions").Plugins} Plugins */
/** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */
/** @typedef {import("./webpack").WebpackPluginFunction} WebpackPluginFunction */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./HotModuleReplacementPlugin").ChunkHashes} ChunkHashes */
@@ -756,6 +756,7 @@ class Compiler {
if (cacheEntry === undefined) {
cacheEntry = {
sizeOnlySource: undefined,
/** @type {CacheEntry["writtenTo"]} */
writtenTo: new Map()
};
this._assetEmittingSourceCache.set(source, cacheEntry);
@@ -1055,7 +1056,7 @@ ${other}`);
(cb) => this.hooks.emitRecords.callAsync(cb),
this._emitRecords.bind(this)
],
(err) => callback(err)
(err) => callback(/** @type {Error | null} */ (err))
);
} else {
this.hooks.emitRecords.callAsync(callback);
@@ -1128,7 +1129,7 @@ ${other}`);
(cb) => this.hooks.readRecords.callAsync(cb),
this._readRecords.bind(this)
],
(err) => callback(err)
(err) => callback(/** @type {Error | null} */ (err))
);
} else {
this.records = {};

View File

@@ -37,9 +37,10 @@ class ConcatenationScope {
constructor(modulesMap, currentModule, usedNames) {
this._currentModule = currentModule;
if (Array.isArray(modulesMap)) {
/** @type {Map<Module, ConcatenatedModuleInfo>} */
const map = new Map();
for (const info of modulesMap) {
map.set(info.module, info);
map.set(info.module, /** @type {ConcatenatedModuleInfo} */ (info));
}
modulesMap = map;
}

View File

@@ -9,10 +9,10 @@ const WebpackError = require("./WebpackError");
module.exports = class ConcurrentCompilationError extends WebpackError {
constructor() {
super();
super(
"You ran Webpack twice. Each instance only supports a single concurrent compilation at a time."
);
this.name = "ConcurrentCompilationError";
this.message =
"You ran Webpack twice. Each instance only supports a single concurrent compilation at a time.";
}
};

View File

@@ -17,6 +17,10 @@ const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
const RuntimeGlobals = require("./RuntimeGlobals");
const Template = require("./Template");
const WebpackError = require("./WebpackError");
const {
getOutgoingAsyncModules
} = require("./async-modules/AsyncModuleHelpers");
const { ImportPhase, ImportPhaseUtils } = require("./dependencies/ImportPhase");
const {
compareLocations,
compareModulesById,
@@ -54,6 +58,8 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./Module").LibIdent} LibIdent */
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@@ -62,6 +68,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
/** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */
@@ -81,6 +88,7 @@ const makeSerializable = require("./util/makeSerializable");
* @property {RawReferencedExports | null=} referencedExports exports referenced from modules (won't be mangled)
* @property {string | null=} layer
* @property {ImportAttributes=} attributes
* @property {ImportPhaseType=} phase
*/
/**
@@ -110,6 +118,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {1 | 3 | 7 | 9} FakeMapType */
/** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
/** @typedef {Record<string, ModuleId>} UserRequestMap */
class ContextModule extends Module {
/**
@@ -260,6 +269,9 @@ class ContextModule extends Module {
if (this.options.attributes) {
identifier += `|importAttributes: ${JSON.stringify(this.options.attributes)}`;
}
if (this.options.phase) {
identifier += `|importPhase: ${this.options.phase}`;
}
if (this.layer) {
identifier += `|layer: ${this.layer}`;
}
@@ -278,7 +290,9 @@ class ContextModule extends Module {
* @returns {string} a user readable identifier of the module
*/
readableIdentifier(requestShortener) {
/** @type {string} */
let identifier;
if (this.context) {
identifier = `${requestShortener.shorten(this.context)}/`;
} else if (
@@ -342,6 +356,7 @@ class ContextModule extends Module {
* @returns {LibIdent | null} an identifier for library inclusion
*/
libIdent(options) {
/** @type {string} */
let identifier;
if (this.context) {
@@ -509,7 +524,7 @@ class ContextModule extends Module {
for (const dep of dependencies) {
let chunkName = this.options.chunkName;
if (chunkName) {
if (!/\[(index|request)\]/.test(chunkName)) {
if (!/\[(?:index|request)\]/.test(chunkName)) {
chunkName += "[index]";
}
chunkName = chunkName.replace(/\[index\]/g, `${index++}`);
@@ -585,7 +600,7 @@ class ContextModule extends Module {
/**
* @param {Dependency[]} dependencies all dependencies
* @param {ChunkGraph} chunkGraph chunk graph
* @returns {Map<string, ModuleId>} map with user requests
* @returns {UserRequestMap} map with user requests
*/
getUserRequestMap(dependencies, chunkGraph) {
const moduleGraph = chunkGraph.moduleGraph;
@@ -602,10 +617,13 @@ class ContextModule extends Module {
}
return a.userRequest < b.userRequest ? -1 : 1;
});
/** @type {UserRequestMap} */
const map = Object.create(null);
for (const dep of sortedDependencies) {
const module = /** @type {Module} */ (moduleGraph.getModule(dep));
map[dep.userRequest] = chunkGraph.getModuleId(module);
map[dep.userRequest] =
/** @type {ModuleId} */
(chunkGraph.getModuleId(module));
}
return map;
}
@@ -690,6 +708,47 @@ class ContextModule extends Module {
: "";
}
/**
* @param {Dependency[]} dependencies all dependencies
* @param {ChunkGraph} chunkGraph chunk graph
* @returns {Map<string, ModuleId[] | undefined>} map with user requests
*/
getModuleDeferredAsyncDepsMap(dependencies, chunkGraph) {
const moduleGraph = chunkGraph.moduleGraph;
const comparator = compareModulesById(chunkGraph);
// if we filter first we get a new array
// therefore we don't need to create a clone of dependencies explicitly
// therefore the order of this is !important!
const sortedModules = dependencies
.map(
(dependency) =>
/** @type {Module} */ (moduleGraph.getModule(dependency))
)
.filter(Boolean)
.sort(comparator);
const map = Object.create(null);
for (const module of sortedModules) {
if (!(/** @type {BuildMeta} */ (module.buildMeta).async)) {
const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
map[id] = Array.from(
getOutgoingAsyncModules(chunkGraph.moduleGraph, module),
(m) => chunkGraph.getModuleId(m)
).filter((id) => id !== null);
}
}
return map;
}
/**
* @param {false | Map<string, ModuleId[] | undefined>} asyncDepsMap fake map
* @returns {string} async deps map init statement
*/
getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap) {
return typeof asyncDepsMap === "object"
? `var asyncDepsMap = ${JSON.stringify(asyncDepsMap, null, "\t")};`
: "";
}
/**
* @param {FakeMapType} type type
* @param {boolean=} asyncModule is async module
@@ -706,21 +765,30 @@ class ContextModule extends Module {
/**
* @param {FakeMap | FakeMapType} fakeMap fake map
* @param {boolean=} asyncModule us async module
* @param {boolean=} asyncModule is async module
* @param {string=} asyncDeps async deps for deferred module
* @param {string=} fakeMapDataExpression fake map data expression
* @returns {string} module object source
*/
getReturnModuleObjectSource(
fakeMap,
asyncModule,
asyncDeps,
fakeMapDataExpression = "fakeMap[id]"
) {
if (typeof fakeMap === "number") {
return `return ${this.getReturn(fakeMap, asyncModule)};`;
const source =
typeof fakeMap === "number"
? this.getReturn(fakeMap, asyncModule)
: `${RuntimeGlobals.createFakeNamespaceObject}(id, ${fakeMapDataExpression}${asyncModule ? " | 16" : ""})`;
if (asyncDeps) {
if (!asyncModule) {
throw new Error("Must be async when module is deferred");
}
const type =
typeof fakeMap === "number" ? fakeMap : fakeMapDataExpression;
return `${asyncDeps} ? ${asyncDeps}.length ? ${RuntimeGlobals.deferredModuleAsyncTransitiveDependencies}(${asyncDeps}).then(${RuntimeGlobals.makeDeferredNamespaceObject}.bind(${RuntimeGlobals.require}, id, ${type} ^ 1, true)) : ${RuntimeGlobals.makeDeferredNamespaceObject}(id, ${type} ^ 1 | 16) : ${source}`;
}
return `return ${
RuntimeGlobals.createFakeNamespaceObject
}(id, ${fakeMapDataExpression}${asyncModule ? " | 16" : ""})`;
return source;
}
/**
@@ -739,7 +807,7 @@ ${this.getFakeMapInitStatement(fakeMap)}
function webpackContext(req) {
var id = webpackContextResolve(req);
${returnModuleObject}
return ${returnModuleObject};
}
function webpackContextResolve(req) {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
@@ -778,7 +846,7 @@ function webpackContext(req) {
e.code = 'MODULE_NOT_FOUND';
throw e;
}
${returnModuleObject}
return ${returnModuleObject};
}
function webpackContextResolve(req) {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
@@ -799,43 +867,56 @@ module.exports = webpackContext;`;
/**
* @param {Dependency[]} dependencies dependencies
* @param {ModuleId} id module id
* @param {ImportPhaseType} phase import phase
* @param {object} context context
* @param {ChunkGraph} context.chunkGraph the chunk graph
* @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
* @returns {string} source code
*/
getAsyncWeakSource(dependencies, id, { chunkGraph, runtimeTemplate }) {
const arrow = runtimeTemplate.supportsArrowFunction();
getAsyncWeakSource(dependencies, id, phase, { chunkGraph, runtimeTemplate }) {
const map = this.getUserRequestMap(dependencies, chunkGraph);
const fakeMap = this.getFakeMap(dependencies, chunkGraph);
const returnModuleObject = this.getReturnModuleObjectSource(fakeMap, true);
const asyncDepsMap =
ImportPhaseUtils.isDefer(phase) &&
this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
const returnModuleObject = this.getReturnModuleObjectSource(
fakeMap,
true,
asyncDepsMap ? "asyncDepsMap[id]" : undefined
);
return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}
${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
function webpackAsyncContext(req) {
return webpackAsyncContextResolve(req).then(${
arrow ? "id =>" : "function(id)"
} {
if(!${RuntimeGlobals.moduleFactories}[id]) {
var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
${returnModuleObject}
});
return webpackAsyncContextResolve(req).then(${runtimeTemplate.basicFunction(
"id",
[
`if(!${RuntimeGlobals.moduleFactories}[id]) {`,
Template.indent([
'var e = new Error("Module \'" + req + "\' (\'" + id + "\') is not available (weak dependency)");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
]),
"}",
`return ${returnModuleObject};`
]
)});
}
function webpackAsyncContextResolve(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools
return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
});
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
Template.indent([
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
]),
"}",
"return map[req];"
])});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
"Object.keys(map)"
@@ -848,23 +929,30 @@ module.exports = webpackAsyncContext;`;
/**
* @param {Dependency[]} dependencies dependencies
* @param {ModuleId} id module id
* @param {ImportPhaseType} phase import phase
* @param {object} context context
* @param {ChunkGraph} context.chunkGraph the chunk graph
* @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
* @returns {string} source code
*/
getEagerSource(dependencies, id, { chunkGraph, runtimeTemplate }) {
const arrow = runtimeTemplate.supportsArrowFunction();
getEagerSource(dependencies, id, phase, { chunkGraph, runtimeTemplate }) {
const map = this.getUserRequestMap(dependencies, chunkGraph);
const fakeMap = this.getFakeMap(dependencies, chunkGraph);
const thenFunction =
fakeMap !== 9
? `${arrow ? "id =>" : "function(id)"} {
${this.getReturnModuleObjectSource(fakeMap, true)}
}`
: RuntimeGlobals.require;
const asyncDepsMap =
ImportPhaseUtils.isDefer(phase) &&
this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
const thenFunction = runtimeTemplate.returningFunction(
this.getReturnModuleObjectSource(
fakeMap,
true,
asyncDepsMap ? "asyncDepsMap[id]" : undefined
),
"id"
);
return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}
${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
function webpackAsyncContext(req) {
return webpackAsyncContextResolve(req).then(${thenFunction});
@@ -872,14 +960,16 @@ function webpackAsyncContext(req) {
function webpackAsyncContextResolve(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools
return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
});
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
Template.indent([
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
]),
"}",
"return map[req];"
])});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
"Object.keys(map)"
@@ -893,43 +983,58 @@ module.exports = webpackAsyncContext;`;
* @param {AsyncDependenciesBlock} block block
* @param {Dependency[]} dependencies dependencies
* @param {ModuleId} id module id
* @param {ImportPhaseType} phase import phase
* @param {object} options options object
* @param {RuntimeTemplate} options.runtimeTemplate the runtime template
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @returns {string} source code
*/
getLazyOnceSource(block, dependencies, id, { runtimeTemplate, chunkGraph }) {
getLazyOnceSource(
block,
dependencies,
id,
phase,
{ runtimeTemplate, chunkGraph }
) {
const promise = runtimeTemplate.blockPromise({
chunkGraph,
block,
message: "lazy-once context",
/** @type {RuntimeRequirements} */
runtimeRequirements: new Set()
});
const arrow = runtimeTemplate.supportsArrowFunction();
const map = this.getUserRequestMap(dependencies, chunkGraph);
const fakeMap = this.getFakeMap(dependencies, chunkGraph);
const thenFunction =
fakeMap !== 9
? `${arrow ? "id =>" : "function(id)"} {
${this.getReturnModuleObjectSource(fakeMap, true)};
}`
: RuntimeGlobals.require;
const asyncDepsMap =
ImportPhaseUtils.isDefer(phase) &&
this.getModuleDeferredAsyncDepsMap(dependencies, chunkGraph);
const thenFunction = runtimeTemplate.returningFunction(
this.getReturnModuleObjectSource(
fakeMap,
true,
asyncDepsMap ? "asyncDepsMap[id]" : undefined
),
"id"
);
return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}
${this.getModuleDeferredAsyncDepsMapInitStatement(asyncDepsMap)}
function webpackAsyncContext(req) {
return webpackAsyncContextResolve(req).then(${thenFunction});
}
function webpackAsyncContextResolve(req) {
return ${promise}.then(${arrow ? "() =>" : "function()"} {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
});
return ${promise}.then(${runtimeTemplate.basicFunction("", [
`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
Template.indent([
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
]),
"}",
"return map[req];"
])});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
"Object.keys(map)"
@@ -942,22 +1047,23 @@ module.exports = webpackAsyncContext;`;
/**
* @param {AsyncDependenciesBlock[]} blocks blocks
* @param {ModuleId} id module id
* @param {ImportPhaseType} phase import phase
* @param {object} context context
* @param {ChunkGraph} context.chunkGraph the chunk graph
* @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
* @returns {string} source code
*/
getLazySource(blocks, id, { chunkGraph, runtimeTemplate }) {
getLazySource(blocks, id, phase, { chunkGraph, runtimeTemplate }) {
const moduleGraph = chunkGraph.moduleGraph;
const arrow = runtimeTemplate.supportsArrowFunction();
let hasMultipleOrNoChunks = false;
let hasNoChunk = true;
let hasNoModuleDeferred = true;
const fakeMap = this.getFakeMap(
blocks.map((b) => b.dependencies[0]),
chunkGraph
);
const hasFakeMap = typeof fakeMap === "object";
/** @typedef {{userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock}} Item */
/** @typedef {{ userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock, asyncDeps: undefined | ModuleId[] }} Item */
/**
* @type {Item[]}
*/
@@ -971,7 +1077,8 @@ module.exports = webpackAsyncContext;`;
module: /** @type {Module} */ (moduleGraph.getModule(dependency)),
block,
userRequest: dependency.userRequest,
chunks: undefined
chunks: undefined,
asyncDeps: undefined
};
})
.filter((item) => item.module);
@@ -985,13 +1092,24 @@ module.exports = webpackAsyncContext;`;
if (chunks.length !== 1) {
hasMultipleOrNoChunks = true;
}
const isModuleDeferred =
ImportPhaseUtils.isDefer(phase) &&
!(/** @type {BuildMeta} */ (item.module.buildMeta).async);
if (isModuleDeferred) {
const asyncDeps = Array.from(
getOutgoingAsyncModules(chunkGraph.moduleGraph, item.module),
(m) => chunkGraph.getModuleId(m)
).filter((id) => id !== null);
item.asyncDeps = asyncDeps;
hasNoModuleDeferred = false;
}
}
const shortMode = hasNoChunk && !hasFakeMap;
const shortMode = hasNoChunk && hasNoModuleDeferred && !hasFakeMap;
const sortedItems = items.sort((a, b) => {
if (a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1;
});
/** @type {Record<string, ModuleId | (ModuleId[] | ChunkId[])>} */
/** @type {Record<string, ModuleId | (ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]>} */
const map = Object.create(null);
for (const item of sortedItems) {
const moduleId =
@@ -1000,28 +1118,36 @@ module.exports = webpackAsyncContext;`;
if (shortMode) {
map[item.userRequest] = moduleId;
} else {
/** @type {(ModuleId | ChunkId)[]} */
const arrayStart = [moduleId];
/** @type {(ModuleId | FakeMapType | ChunkId[] | (ModuleId[] | undefined))[]} */
const array = [moduleId];
if (hasFakeMap) {
arrayStart.push(fakeMap[moduleId]);
array.push(fakeMap[moduleId]);
}
map[item.userRequest] = [
...arrayStart,
.../** @type {Chunk[]} */
(item.chunks).map((chunk) => /** @type {ChunkId} */ (chunk.id))
];
if (!hasNoChunk) {
array.push(
/** @type {Chunk[]} */ (item.chunks).map(
(chunk) => /** @type {ChunkId} */ (chunk.id)
)
);
}
if (!hasNoModuleDeferred) {
array.push(item.asyncDeps);
}
map[item.userRequest] = array;
}
}
const chunksStartPosition = hasFakeMap ? 2 : 1;
const chunksPosition = hasFakeMap ? 2 : 1;
const asyncDepsPosition = chunksPosition + 1;
const requestPrefix = hasNoChunk
? "Promise.resolve()"
: hasMultipleOrNoChunks
? `Promise.all(ids.slice(${chunksStartPosition}).map(${RuntimeGlobals.ensureChunk}))`
: `${RuntimeGlobals.ensureChunk}(ids[${chunksStartPosition}])`;
? `Promise.all(ids[${chunksPosition}].map(${RuntimeGlobals.ensureChunk}))`
: `${RuntimeGlobals.ensureChunk}(ids[${chunksPosition}][0])`;
const returnModuleObject = this.getReturnModuleObjectSource(
fakeMap,
true,
hasNoModuleDeferred ? undefined : `ids[${asyncDepsPosition}]`,
shortMode ? "invalid" : "ids[1]"
);
@@ -1029,30 +1155,29 @@ module.exports = webpackAsyncContext;`;
requestPrefix === "Promise.resolve()"
? `
function webpackAsyncContext(req) {
return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
${shortMode ? "var id = map[req];" : "var ids = map[req], id = ids[0];"}
${returnModuleObject}
});
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
`if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {`,
Template.indent([
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
]),
"}",
shortMode ? "var id = map[req];" : "var ids = map[req], id = ids[0];",
`return ${returnModuleObject};`
])});
}`
: `function webpackAsyncContext(req) {
if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
});
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
])});
}
var ids = map[req], id = ids[0];
return ${requestPrefix}.then(${arrow ? "() =>" : "function()"} {
${returnModuleObject}
});
return ${requestPrefix}.then(${runtimeTemplate.returningFunction(returnModuleObject)});
}`;
return `var map = ${JSON.stringify(map, null, "\t")};
@@ -1087,15 +1212,14 @@ module.exports = webpackEmptyContext;`;
* @returns {string} source for empty async context
*/
getSourceForEmptyAsyncContext(id, runtimeTemplate) {
const arrow = runtimeTemplate.supportsArrowFunction();
return `function webpackEmptyAsyncContext(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools
return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
});
return Promise.resolve().then(${runtimeTemplate.basicFunction("", [
'var e = new Error("Cannot find module \'" + req + "\'");',
"e.code = 'MODULE_NOT_FOUND';",
"throw e;"
])});
}
webpackEmptyAsyncContext.keys = ${runtimeTemplate.returningFunction("[]")};
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
@@ -1105,14 +1229,15 @@ module.exports = webpackEmptyAsyncContext;`;
/**
* @param {string} asyncMode module mode
* @param {ImportPhaseType} phase import phase
* @param {CodeGenerationContext} context context info
* @returns {string} the source code
*/
getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) {
getSourceString(asyncMode, phase, { runtimeTemplate, chunkGraph }) {
const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this));
if (asyncMode === "lazy") {
if (this.blocks && this.blocks.length > 0) {
return this.getLazySource(this.blocks, id, {
return this.getLazySource(this.blocks, id, phase, {
runtimeTemplate,
chunkGraph
});
@@ -1121,7 +1246,7 @@ module.exports = webpackEmptyAsyncContext;`;
}
if (asyncMode === "eager") {
if (this.dependencies && this.dependencies.length > 0) {
return this.getEagerSource(this.dependencies, id, {
return this.getEagerSource(this.dependencies, id, phase, {
chunkGraph,
runtimeTemplate
});
@@ -1131,7 +1256,7 @@ module.exports = webpackEmptyAsyncContext;`;
if (asyncMode === "lazy-once") {
const block = this.blocks[0];
if (block) {
return this.getLazyOnceSource(block, block.dependencies, id, {
return this.getLazyOnceSource(block, block.dependencies, id, phase, {
runtimeTemplate,
chunkGraph
});
@@ -1140,7 +1265,7 @@ module.exports = webpackEmptyAsyncContext;`;
}
if (asyncMode === "async-weak") {
if (this.dependencies && this.dependencies.length > 0) {
return this.getAsyncWeakSource(this.dependencies, id, {
return this.getAsyncWeakSource(this.dependencies, id, phase, {
chunkGraph,
runtimeTemplate
});
@@ -1185,14 +1310,21 @@ module.exports = webpackEmptyAsyncContext;`;
*/
codeGeneration(context) {
const { chunkGraph, compilation } = context;
/** @type {Sources} */
const sources = new Map();
sources.set(
JAVASCRIPT_TYPE,
this.getSource(
this.getSourceString(this.options.mode, context),
this.getSourceString(
this.options.mode,
this.options.phase || ImportPhase.Evaluation,
context
),
compilation
)
);
/** @type {RuntimeRequirements} */
const set = new Set();
const allDeps =
this.dependencies.length > 0
@@ -1219,6 +1351,11 @@ module.exports = webpackEmptyAsyncContext;`;
if (this.getFakeMap(allDeps, chunkGraph) !== 9) {
set.add(RuntimeGlobals.createFakeNamespaceObject);
}
if (
ImportPhaseUtils.isDefer(this.options.phase || ImportPhase.Evaluation)
) {
set.add(RuntimeGlobals.makeDeferredNamespaceObject);
}
}
return {
sources,

View File

@@ -97,6 +97,7 @@ class ContextModuleFactory extends ModuleFactory {
),
alternativeRequests
});
/** @type {ResolverFactory} */
this.resolverFactory = resolverFactory;
}
@@ -110,8 +111,11 @@ class ContextModuleFactory extends ModuleFactory {
const dependencies = /** @type {ContextDependency[]} */ (data.dependencies);
const resolveOptions = data.resolveOptions;
const dependency = dependencies[0];
/** @type {FileSystemDependencies} */
const fileDependencies = new LazySet();
/** @type {FileSystemDependencies} */
const missingDependencies = new LazySet();
/** @type {FileSystemDependencies} */
const contextDependencies = new LazySet();
this.hooks.beforeResolve.callAsync(
{
@@ -154,6 +158,7 @@ class ContextModuleFactory extends ModuleFactory {
const idx = request.lastIndexOf("!");
if (idx >= 0) {
let loadersRequest = request.slice(0, idx + 1);
/** @type {number} */
let i;
for (
i = 0;
@@ -165,7 +170,7 @@ class ContextModuleFactory extends ModuleFactory {
loadersRequest = loadersRequest
.slice(i)
.replace(/!+$/, "")
.replace(/!!+/g, "!");
.replace(/!{2,}/g, "!");
loaders = loadersRequest === "" ? [] : loadersRequest.split("!");
resource = request.slice(idx + 1);
} else {
@@ -439,6 +444,7 @@ class ContextModuleFactory extends ModuleFactory {
if (!result) return callback(null, []);
/** @type {ContextElementDependency[]} */
const flattenedResult = [];
for (const item of result) {
@@ -466,7 +472,13 @@ class ContextModuleFactory extends ModuleFactory {
*/
const visitResource = (resource, callback) => {
if (typeof fs.realpath === "function") {
addDirectoryChecked(resource, resource, new Set(), callback);
addDirectoryChecked(
resource,
resource,
/** @type {Set<string>} */
new Set(),
callback
);
} else {
addDirectory(resource, resource, addSubDirectory, callback);
}

View File

@@ -55,12 +55,14 @@ class RuntimeValue {
* @param {true | string[] | RuntimeValueOptions=} options options
*/
constructor(fn, options) {
/** @type {GeneratorFn} */
this.fn = fn;
if (Array.isArray(options)) {
options = {
fileDependencies: options
};
}
/** @type {true | RuntimeValueOptions} */
this.options = options || {};
}
@@ -138,7 +140,7 @@ function getObjKeys(properties) {
/** @typedef {boolean | undefined | null} AsiSafe */
/**
* @param {EXPECTED_ANY[] | {[k: string]: EXPECTED_ANY}} obj obj
* @param {EXPECTED_ANY[] | { [k: string]: EXPECTED_ANY }} obj obj
* @param {JavascriptParser} parser Parser
* @param {ValueCacheVersions} valueCacheVersions valueCacheVersions
* @param {string} key the defined key
@@ -158,6 +160,7 @@ const stringifyObj = (
asiSafe,
objKeys
) => {
/** @type {string} */
let code;
const arr = Array.isArray(obj);
if (arr) {
@@ -337,6 +340,8 @@ const WEBPACK_REQUIRE_IDENTIFIER_REGEXP = new RegExp(RuntimeGlobals.require);
* @property {SyncWaterfallHook<[Record<string, CodeValue>]>} definitions
*/
/** @typedef {Record<string, CodeValue>} Definitions */
/** @type {WeakMap<Compilation, DefinePluginHooks>} */
const compilationHooksMap = new WeakMap();
@@ -358,9 +363,10 @@ class DefinePlugin {
/**
* Create a new define plugin
* @param {Record<string, CodeValue>} definitions A map of global object definitions
* @param {Definitions} definitions A map of global object definitions
*/
constructor(definitions) {
/** @type {Definitions} */
this.definitions = definitions;
}
@@ -418,6 +424,7 @@ class DefinePlugin {
* @returns {void}
*/
const handler = (parser) => {
/** @type {Set<string>} */
const hooked = new Set();
const mainValue =
/** @type {ValueCacheVersion} */
@@ -462,7 +469,7 @@ class DefinePlugin {
/**
* Walk definitions
* @param {Record<string, CodeValue>} definitions Definitions map
* @param {Definitions} definitions Definitions map
* @param {string} prefix Prefix string
* @returns {void}
*/
@@ -476,7 +483,7 @@ class DefinePlugin {
!(code instanceof RegExp)
) {
walkDefinitions(
/** @type {Record<string, CodeValue>} */ (code),
/** @type {Definitions} */ (code),
`${prefix + key}.`
);
applyObjectDefine(prefix + key, code);
@@ -535,7 +542,7 @@ class DefinePlugin {
if (destructed === undefined) {
return;
}
/** @type {Record<string, CodeValue>} */
/** @type {Definitions} */
const obj = Object.create(null);
const finalSet = finalByNestedKey.get(nested);
for (const { id } of destructed) {
@@ -782,7 +789,7 @@ class DefinePlugin {
/**
* Walk definitions
* @param {Record<string, CodeValue>} definitions Definitions map
* @param {Definitions} definitions Definitions map
* @param {string} prefix Prefix string
* @returns {void}
*/
@@ -810,7 +817,7 @@ class DefinePlugin {
!(code instanceof RegExp)
) {
walkDefinitionsForValues(
/** @type {Record<string, CodeValue>} */ (code),
/** @type {Definitions} */ (code),
`${prefix + key}.`
);
}
@@ -818,7 +825,7 @@ class DefinePlugin {
};
/**
* @param {Record<string, CodeValue>} definitions Definitions map
* @param {Definitions} definitions Definitions map
* @returns {void}
*/
const walkDefinitionsForKeys = (definitions) => {

View File

@@ -32,6 +32,8 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./Module").LibIdent} LibIdent */
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
@@ -76,6 +78,7 @@ class DelegatedModule extends Module {
this.delegateData = data;
// Build info
/** @type {undefined | DelegatedSourceDependency} */
this.delegatedSourceDependency = undefined;
}
@@ -152,6 +155,7 @@ class DelegatedModule extends Module {
codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
const dep = /** @type {DelegatedSourceDependency} */ (this.dependencies[0]);
const sourceModule = moduleGraph.getModule(dep);
/** @type {string} */
let str;
if (!sourceModule) {
@@ -163,6 +167,7 @@ class DelegatedModule extends Module {
module: sourceModule,
chunkGraph,
request: dep.request,
/** @type {RuntimeRequirements} */
runtimeRequirements: new Set()
})})`;
@@ -178,6 +183,7 @@ class DelegatedModule extends Module {
str += ";";
}
/** @type {Sources} */
const sources = new Map();
if (this.useSourceMap || this.useSimpleSourceMap) {
sources.set(JAVASCRIPT_TYPE, new OriginalSource(str, this.identifier()));

View File

@@ -9,6 +9,7 @@ const DelegatedModule = require("./DelegatedModule");
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
/** @typedef {import("./DelegatedModule").DelegatedModuleData} DelegatedModuleData */
/** @typedef {import("./DelegatedModule").DelegatedModuleSourceRequest} DelegatedModuleSourceRequest */
/** @typedef {import("./DelegatedModule").DelegatedModuleType} DelegatedModuleType */
/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
@@ -51,6 +52,7 @@ class DelegatedModuleFactoryPlugin {
const { request } = dependency;
if (request && request.startsWith(`${scope}/`)) {
const innerRequest = `.${request.slice(scope.length)}`;
/** @type {undefined | DelegatedModuleData} */
let resolved;
if (innerRequest in this.options.content) {
resolved = this.options.content[innerRequest];

View File

@@ -48,9 +48,11 @@ const memoize = require("./util/memoize");
/** @typedef {SyntheticDependencyLocation | RealDependencyLocation} DependencyLocation */
/** @typedef {string} ExportInfoName */
/**
* @typedef {object} ExportSpec
* @property {string} name the name of the export
* @property {ExportInfoName} name the name of the export
* @property {boolean=} canMangle can the export be renamed (defaults to true)
* @property {boolean=} terminalBinding is the export a terminal binding that should be checked for export star conflicts
* @property {(string | ExportSpec)[]=} exports nested exports
@@ -113,8 +115,11 @@ class Dependency {
this._locSC = 0;
this._locEL = 0;
this._locEC = 0;
/** @type {undefined | number} */
this._locI = undefined;
/** @type {undefined | string} */
this._locN = undefined;
/** @type {undefined | DependencyLocation} */
this._loc = undefined;
}

View File

@@ -10,17 +10,18 @@ const createHash = require("./util/createHash");
/** @typedef {import("./Compilation").DependencyConstructor} DependencyConstructor */
/** @typedef {import("./DependencyTemplate")} DependencyTemplate */
/** @typedef {typeof import("./util/Hash")} Hash */
/** @typedef {import("./util/Hash").HashFunction} HashFunction */
class DependencyTemplates {
/**
* @param {string | Hash} hashFunction the hash function to use
* @param {HashFunction} hashFunction the hash function to use
*/
constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
/** @type {Map<DependencyConstructor, DependencyTemplate>} */
this._map = new Map();
/** @type {string} */
this._hash = "31d6cfe0d16ae931b73c59d7e0c089c0";
/** @type {HashFunction} */
this._hashFunction = hashFunction;
}

View File

@@ -25,6 +25,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
@@ -93,6 +94,7 @@ class DllModule extends Module {
* @returns {CodeGenerationResult} result
*/
codeGeneration(context) {
/** @type {Sources} */
const sources = new Map();
sources.set(
JAVASCRIPT_TYPE,

View File

@@ -109,6 +109,7 @@ class DllReferencePlugin {
"content" in this.options ? this.options.content : undefined;
if ("manifest" in this.options) {
const manifestParameter = this.options.manifest;
/** @type {undefined | DllReferencePluginOptionsManifest} */
let manifest;
if (typeof manifestParameter === "string") {
const data =

View File

@@ -25,9 +25,9 @@ const DEFAULT_OPTIONS = {
};
// Regex for parsing .env files
// ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L32
// ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L49
const LINE =
/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
/^\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?$/gm;
const PLUGIN_NAME = "DotenvPlugin";
@@ -60,9 +60,11 @@ function parse(src) {
let lines = src.toString();
// Convert line breaks to same format
lines = lines.replace(/\r\n?/gm, "\n");
lines = lines.replace(/\r\n?/g, "\n");
/** @type {null | RegExpExecArray} */
let match;
while ((match = LINE.exec(lines)) !== null) {
const key = match[1];
@@ -112,10 +114,12 @@ function _resolveEscapeSequences(value) {
function expandValue(value, processEnv, runningParsed) {
const env = { ...runningParsed, ...processEnv }; // process.env wins
const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g;
const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([a-z_]\w*)/gi;
let result = value;
/** @type {null | RegExpExecArray} */
let match;
/** @type {Set<string>} */
const seen = new Set(); // self-referential checker
while ((match = regex.exec(result)) !== null) {
@@ -133,7 +137,9 @@ function expandValue(value, processEnv, runningParsed) {
const r = expression.split(/** @type {string} */ (splitter));
// const r = splitter ? expression.split(splitter) : [expression];
/** @type {string} */
let defaultValue;
/** @type {undefined | null | string} */
let value;
const key = r.shift();
@@ -303,7 +309,7 @@ class DotenvPlugin {
* @param {InputFileSystem} fs input file system
* @param {string} dir dir to load `.env` files
* @param {string} mode mode
* @returns {Promise<{parsed: Env, fileDependencies: string[], missingDependencies: string[]}>} parsed env variables and dependencies
* @returns {Promise<{ parsed: Env, fileDependencies: string[], missingDependencies: string[] }>} parsed env variables and dependencies
*/
async _getParsed(fs, dir, mode) {
/** @type {string[]} */

View File

@@ -10,18 +10,24 @@ const EntryPlugin = require("./EntryPlugin");
const EntryDependency = require("./dependencies/EntryDependency");
/** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */
/** @typedef {import("../declarations/WebpackOptions").EntryDynamicNormalized} EntryDynamic */
/** @typedef {import("../declarations/WebpackOptions").EntryStatic} EntryStatic */
/** @typedef {import("../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */
/** @typedef {import("./Compiler")} Compiler */
const PLUGIN_NAME = "DynamicEntryPlugin";
/** @typedef {() => EntryStatic | Promise<EntryStatic>} RawEntryDynamic */
/** @typedef {() => Promise<EntryStaticNormalized>} EntryDynamic */
class DynamicEntryPlugin {
/**
* @param {string} context the context path
* @param {EntryDynamic} entry the entry value
*/
constructor(context, entry) {
/** @type {string} */
this.context = context;
/** @type {EntryDynamic} */
this.entry = entry;
}
@@ -44,6 +50,7 @@ class DynamicEntryPlugin {
compiler.hooks.make.tapPromise(PLUGIN_NAME, (compilation) =>
Promise.resolve(this.entry())
.then((entry) => {
/** @type {Promise<void>[]} */
const promises = [];
for (const name of Object.keys(entry)) {
const desc = entry[name];

View File

@@ -24,6 +24,7 @@ However, your target environment does not appear to support 'async/await'.
As a result, the code may not run as expected or may cause runtime errors.`;
super(message);
/** @type {string} */
this.name = "EnvironmentNotSupportAsyncWarning";
this.module = module;
}

View File

@@ -119,6 +119,7 @@ class EvalSourceMapDevToolPlugin {
});
/** @type {RawSourceMap} */
let sourceMap;
/** @type {string | Buffer} */
let content;
if (source.sourceAndMap) {
const sourceAndMap = source.sourceAndMap(options);
@@ -164,20 +165,23 @@ class EvalSourceMapDevToolPlugin {
}
);
sourceMap.sources = moduleFilenames;
sourceMap.ignoreList = options.ignoreList
? sourceMap.sources.reduce(
/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
(acc, sourceName, idx) => {
const rule = /** @type {Rules} */ (options.ignoreList);
if (ModuleFilenameHelpers.matchPart(sourceName, rule)) {
acc.push(idx);
}
return acc;
if (options.ignoreList) {
const ignoreList = sourceMap.sources.reduce(
/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
(acc, sourceName, idx) => {
const rule = /** @type {Rules} */ (options.ignoreList);
if (ModuleFilenameHelpers.matchPart(sourceName, rule)) {
acc.push(idx);
}
),
[]
)
: [];
return acc;
}
),
[]
);
if (ignoreList.length > 0) {
sourceMap.ignoreList = ignoreList;
}
}
if (options.noSources) {
sourceMap.sourcesContent = undefined;

View File

@@ -13,6 +13,7 @@ const { forEachRuntime } = require("./util/runtime");
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */
/** @typedef {import("./Dependency").ExportInfoName} ExportInfoName */
/** @typedef {import("./Dependency").ExportsSpecExcludeExports} ExportsSpecExcludeExports */
/** @typedef {import("./dependencies/HarmonyImportDependency")} HarmonyImportDependency */
/** @typedef {import("./Module")} Module */
@@ -25,8 +26,6 @@ const { forEachRuntime } = require("./util/runtime");
/** @typedef {typeof UsageState.OnlyPropertiesUsed | typeof UsageState.NoInfo | typeof UsageState.Unknown | typeof UsageState.Used} RuntimeUsageStateType */
/** @typedef {typeof UsageState.Unused | RuntimeUsageStateType} UsageStateType */
/** @typedef {string} ExportInfoName */
/** @typedef {Map<string, RuntimeUsageStateType>} UsedInRuntime */
/** @typedef {{ module: Module, export: ExportInfoName[], deferred: boolean }} TargetItemWithoutConnection */
/** @typedef {{ module: Module, connection: ModuleGraphConnection, export: ExportInfoName[] | undefined }} TargetItemWithConnection */
@@ -111,8 +110,11 @@ class ExportsInfo {
constructor() {
/** @type {Exports} */
this._exports = new Map();
/** @type {ExportInfo} */
this._otherExportsInfo = new ExportInfo(null);
/** @type {ExportInfo} */
this._sideEffectsOnlyInfo = new ExportInfo("*side effects only*");
/** @type {boolean} */
this._exportsAreOrdered = false;
/** @type {ExportsInfo=} */
this._redirectTo = undefined;
@@ -613,6 +615,7 @@ class ExportsInfo {
* @returns {ExportInfo[]} exports that are relevant (not unused and potential provided)
*/
getRelevantExports(runtime) {
/** @type {ExportInfo[]} */
const list = [];
for (const exportInfo of this._exports.values()) {
const used = exportInfo.getUsed(runtime);
@@ -655,6 +658,7 @@ class ExportsInfo {
* @returns {string} key representing the usage
*/
getUsageKey(runtime) {
/** @type {(string | number)[]} */
const key = [];
if (this._redirectTo !== undefined) {
key.push(this._redirectTo.getUsageKey(runtime));
@@ -916,7 +920,7 @@ class ExportInfo {
/** @type {Target | undefined} */
this._target = undefined;
if (initFrom && initFrom._target) {
this._target = new Map();
this._target = /** @type {Target} */ (new Map());
for (const [key, value] of initFrom._target) {
this._target.set(key, {
connection: value.connection,
@@ -1155,7 +1159,7 @@ class ExportInfo {
setTarget(key, connection, exportName, priority = 0) {
if (exportName) exportName = [...exportName];
if (!this._target) {
this._target = new Map();
this._target = /** @type {Target} */ (new Map());
this._target.set(key, {
connection,
export: /** @type {ExportInfoName[]} */ (exportName),

View File

@@ -45,12 +45,15 @@ const { register } = require("./util/serialization");
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").CodeGenerationResultData} CodeGenerationResultData */
/** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").LibIdent} LibIdent */
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
/** @typedef {import("./RequestShortener")} RequestShortener */
@@ -82,11 +85,15 @@ const { register } = require("./util/serialization");
/** @typedef {true | [string, string][]} Imported */
/** @type {RuntimeRequirements} */
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
/** @type {RuntimeRequirements} */
const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]);
/** @type {RuntimeRequirements} */
const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([
RuntimeGlobals.definePropertyGetters
]);
/** @type {RuntimeRequirements} */
const EMPTY_RUNTIME_REQUIREMENTS = new Set();
/**
@@ -400,6 +407,7 @@ const generateModuleRemapping = (
runtimeTemplate
) => {
if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) {
/** @type {string[]} */
const properties = [];
for (const exportInfo of exportsInfo.orderedExports) {
const used = exportInfo.getUsedName(exportInfo.name, runtime);
@@ -488,6 +496,7 @@ const getSourceForModuleExternal = (
let expression = baseAccess;
const useNamespace = imported === true;
/** @type {undefined | string} */
let moduleRemapping;
if (useNamespace) {
moduleRemapping = generateModuleRemapping(
@@ -978,22 +987,27 @@ class ExternalModule extends Module {
const { request, externalType } = this._getRequestAndExternalType();
switch (externalType) {
case "asset": {
/** @type {Sources} */
const sources = new Map();
sources.set(
JAVASCRIPT_TYPE,
new RawSource(`module.exports = ${JSON.stringify(request)};`)
);
/** @type {CodeGenerationResultData} */
const data = new Map();
data.set("url", { javascript: request });
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
}
case "css-url": {
/** @type {Sources} */
const sources = new Map();
/** @type {CodeGenerationResultData} */
const data = new Map();
data.set("url", { "css-url": request });
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data };
}
case "css-import": {
/** @type {Sources} */
const sources = new Map();
const dependencyMeta = /** @type {CssImportDependencyMeta} */ (
this.dependencyMeta
@@ -1056,12 +1070,14 @@ class ExternalModule extends Module {
sourceString = `${sourceData.init}\n${sourceString}`;
}
/** @type {undefined | CodeGenerationResultData} */
let data;
if (sourceData.chunkInitFragments) {
data = new Map();
data.set("chunkInitFragments", sourceData.chunkInitFragments);
}
/** @type {Sources} */
const sources = new Map();
if (this.useSourceMap || this.useSimpleSourceMap) {
sources.set(

View File

@@ -17,10 +17,12 @@ const { cachedSetProperty, resolveByProperty } = require("./util/cleverMerge");
/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
/** @typedef {import("../declarations/WebpackOptions").ExternalsType} ExternalsType */
/** @typedef {import("../declarations/WebpackOptions").ExternalItem} ExternalItem */
/** @typedef {import("../declarations/WebpackOptions").ExternalItemValue} ExternalItemValue */
/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectKnown} ExternalItemObjectKnown */
/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectUnknown} ExternalItemObjectUnknown */
/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./ExternalModule").DependencyMeta} DependencyMeta */
/** @typedef {import("./ModuleFactory").IssuerLayer} IssuerLayer */
/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
@@ -61,6 +63,7 @@ const callDeprecatedExternals = util.deprecate(
"DEP_WEBPACK_EXTERNALS_FUNCTION_PARAMETERS"
);
/** @typedef {(layer: string | null) => ExternalItem} ExternalItemByLayerFn */
/** @typedef {ExternalItemObjectKnown & ExternalItemObjectUnknown} ExternalItemObject */
/**
@@ -96,7 +99,7 @@ const PLUGIN_NAME = "ExternalModuleFactoryPlugin";
class ExternalModuleFactoryPlugin {
/**
* @param {ExternalsType} type default external type
* @param {ExternalsType | ((dependency: Dependency) => ExternalsType)} type default external type
* @param {Externals} externals externals config
*/
constructor(type, externals) {
@@ -159,7 +162,11 @@ class ExternalModuleFactoryPlugin {
}
}
const resolvedType = type || globalType;
const defaultType =
typeof globalType === "function"
? globalType(dependency)
: globalType;
const resolvedType = type || defaultType;
// TODO make it pluggable/add hooks to `ExternalModule` to allow output modules own externals?
/** @type {DependencyMeta | undefined} */

View File

@@ -13,12 +13,13 @@ const ConcatenatedModule = require("./optimize/ConcatenatedModule");
/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./ExternalModule").Imported} Imported */
/** @typedef {import("./Dependency")} Dependency */
const PLUGIN_NAME = "ExternalsPlugin";
class ExternalsPlugin {
/**
* @param {ExternalsType} type default external type
* @param {ExternalsType | ((dependency: Dependency) => ExternalsType)} type default external type
* @param {Externals} externals externals config
*/
constructor(type, externals) {

View File

@@ -10,6 +10,7 @@ const WebpackError = require("./WebpackError");
class FalseIIFEUmdWarning extends WebpackError {
constructor() {
super();
/** @type {string} */
this.name = "FalseIIFEUmdWarning";
this.message =
"Configuration:\nSetting 'output.iife' to 'false' is incompatible with 'output.library.type' set to 'umd'. This configuration may cause unexpected behavior, as UMD libraries are expected to use an IIFE (Immediately Invoked Function Expression) to support various module formats. Consider setting 'output.iife' to 'true' or choosing a different 'library.type' to ensure compatibility.\nLearn more: https://webpack.js.org/configuration/output/";

View File

@@ -25,6 +25,7 @@ const processAsyncTree = require("./util/processAsyncTree");
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
/** @typedef {import("./util/fs").JsonObject} JsonObject */
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/**
@@ -43,6 +44,7 @@ const builtinModules = new Set(nodeModule.builtinModules);
let FS_ACCURACY = 2000;
/** @type {Set<string>} */
const EMPTY_SET = new Set();
const RBDT_RESOLVE_INITIAL = 0;
@@ -60,6 +62,9 @@ const RBDT_FILE_DEPENDENCIES = 9;
const INVALID = Symbol("invalid");
// eslint-disable-next-line jsdoc/ts-no-empty-object-type
/** @typedef {{ }} ExistenceOnlyTimeEntry */
/**
* @typedef {object} FileSystemInfoEntry
* @property {number} safeTime
@@ -767,6 +772,7 @@ class SnapshotOptimization {
continue;
}
// Extract common timestamps from both snapshots
/** @type {Set<string> | Map<string, T>} */
let commonMap;
if (this._isSet) {
commonMap = new Set();
@@ -818,6 +824,7 @@ class SnapshotOptimization {
// Incomplete snapshot, that can't be used
continue;
}
/** @type {Set<string> | Map<string, T>} */
let commonMap;
if (this._isSet) {
commonMap = new Set();
@@ -1401,22 +1408,30 @@ class FileSystemInfo {
}
/**
* @param {ReadonlyMap<string, FileTimestamp>} map timestamps
* @param {ReadonlyMap<string, FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
* @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
* @returns {void}
*/
addFileTimestamps(map, immutable) {
this._fileTimestamps.addAll(map, immutable);
this._fileTimestamps.addAll(
/** @type {ReadonlyMap<string, FileTimestamp>} */
(map),
immutable
);
this._cachedDeprecatedFileTimestamps = undefined;
}
/**
* @param {ReadonlyMap<string, ContextTimestamp>} map timestamps
* @param {ReadonlyMap<string, ContextFileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
* @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
* @returns {void}
*/
addContextTimestamps(map, immutable) {
this._contextTimestamps.addAll(map, immutable);
this._contextTimestamps.addAll(
/** @type {ReadonlyMap<string, ContextTimestamp>} */
(map),
immutable
);
this._cachedDeprecatedContextTimestamps = undefined;
}
@@ -1889,7 +1904,7 @@ class FileSystemInfo {
for (const modulePath of module.paths) {
if (childPath.startsWith(modulePath)) {
const subPath = childPath.slice(modulePath.length + 1);
const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec(
const packageMatch = /^@[^\\/]+[\\/][^\\/]+/.exec(
subPath
);
if (packageMatch) {
@@ -1954,9 +1969,11 @@ class FileSystemInfo {
const context = dirname(this.fs, path);
const source = /** @type {Buffer} */ (content).toString();
const [imports] = lexer.parse(source);
/** @type {Set<string>} */
const added = new Set();
for (const imp of imports) {
try {
/** @type {string} */
let dependency;
if (imp.d === -1) {
// import ... from "..."
@@ -2043,6 +2060,7 @@ class FileSystemInfo {
return callback(err);
}
resolveFiles.add(packageJson);
/** @type {JsonObject} */
let packageData;
try {
packageData = JSON.parse(
@@ -2054,7 +2072,9 @@ class FileSystemInfo {
}
const depsObject = packageData.dependencies;
const optionalDepsObject = packageData.optionalDependencies;
/** @type {Set<string>} */
const allDeps = new Set();
/** @type {Set<string>} */
const optionalDeps = new Set();
if (typeof depsObject === "object" && depsObject) {
for (const dep of Object.keys(depsObject)) {
@@ -2172,15 +2192,17 @@ class FileSystemInfo {
* @param {Error | typeof INVALID=} err error or invalid flag
* @returns {void}
*/
(err) => {
if (err === INVALID) {
return callback(null, false);
/** @type {import("neo-async").ErrorCallback<Error | typeof INVALID>} */ (
(err) => {
if (err === INVALID) {
return callback(null, false);
}
if (err) {
return callback(err);
}
return callback(null, true);
}
if (err) {
return callback(err);
}
return callback(null, true);
}
)
);
}
@@ -2492,6 +2514,7 @@ class FileSystemInfo {
);
for (const path of capturedDirectories) {
const cache = this._contextHashes.get(path);
/** @type {undefined | null | string} */
let resolved;
if (
cache !== undefined &&
@@ -2533,6 +2556,7 @@ class FileSystemInfo {
for (const path of capturedDirectories) {
const cache = this._contextTimestamps.get(path);
if (cache === "ignore") continue;
/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
let resolved;
if (
cache !== undefined &&
@@ -2653,6 +2677,7 @@ class FileSystemInfo {
*/
const process = (set, fn) => {
if (set.size === 0) return;
/** @type {Set<string>} */
const captured = new Set();
for (const file of set) {
if (file.startsWith(path)) captured.add(file);
@@ -3068,6 +3093,7 @@ class FileSystemInfo {
for (const [path, ts] of contextTimestamps) {
const cache = this._contextTimestamps.get(path);
if (cache === "ignore") continue;
/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
let resolved;
if (
cache !== undefined &&
@@ -3117,6 +3143,7 @@ class FileSystemInfo {
*/
const processContextHashSnapshot = (path, hash) => {
const cache = this._contextHashes.get(path);
/** @type {undefined | null | string} */
let resolved;
if (
cache !== undefined &&
@@ -3165,20 +3192,13 @@ class FileSystemInfo {
} else {
const cache = this._contextTimestamps.get(path);
if (cache === "ignore") continue;
/** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
let resolved;
if (
cache !== undefined &&
(resolved = getResolvedTimestamp(cache)) !== undefined
) {
if (
!checkContext(
path,
/** @type {ResolvedContextFileSystemInfoEntry | null} */
(resolved),
tsh,
false
)
) {
if (!checkContext(path, resolved, tsh, false)) {
processContextHashSnapshot(path, tsh && tsh.hash);
}
} else {
@@ -3298,6 +3318,7 @@ class FileSystemInfo {
return callback(/** @type {WebpackError} */ (err));
}
const stat = /** @type {IStats} */ (_stat);
/** @type {FileSystemInfoEntry} */
let ts;
if (stat.isDirectory()) {
ts = {
@@ -3576,6 +3597,7 @@ class FileSystemInfo {
});
},
reduce: (files, tsEntries) => {
/** @type {undefined | Symlinks} */
let symlinks;
const hash = createHash(this._hashFunction);
@@ -3725,6 +3747,7 @@ class FileSystemInfo {
* @returns {ContextHash} reduced hash
*/
reduce: (files, fileHashes) => {
/** @type {undefined | Symlinks} */
let symlinks;
const hash = createHash(this._hashFunction);
@@ -3867,6 +3890,7 @@ class FileSystemInfo {
* @returns {ContextTimestampAndHash} tsh
*/
reduce: (files, results) => {
/** @type {undefined | Symlinks} */
let symlinks;
const tsHash = createHash(this._hashFunction);
@@ -3997,9 +4021,8 @@ class FileSystemInfo {
return callback(/** @type {WebpackError} */ (err));
}
const set = new Set(
/** @type {string[]} */ (elements).map((element) =>
join(this.fs, path, element)
)
/** @type {string[]} */
(elements).map((element) => join(this.fs, path, element))
);
callback(null, set);
});
@@ -4058,6 +4081,7 @@ class FileSystemInfo {
}
return callback(/** @type {WebpackError} */ (err));
}
/** @type {JsonObject} */
let data;
try {
data = JSON.parse(/** @type {Buffer} */ (content).toString("utf8"));

View File

@@ -14,6 +14,7 @@ const Queue = require("./util/Queue");
/** @typedef {import("./Dependency").ExportSpec} ExportSpec */
/** @typedef {import("./Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("./ExportsInfo")} ExportsInfo */
/** @typedef {import("./ExportsInfo").ExportInfoName} ExportInfoName */
/** @typedef {import("./ExportsInfo").RestoreProvidedData} RestoreProvidedData */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./Module").BuildInfo} BuildInfo */
@@ -50,7 +51,9 @@ class FlagDependencyExportsPlugin {
// Step 1: Try to restore cached provided export info from cache
logger.time("restore cached provided exports");
asyncLib.each(
modules,
/** @type {import("neo-async").IterableCollection<Module>} */ (
/** @type {unknown} */ (modules)
),
(module, callback) => {
const exportsInfo = moduleGraph.getExportsInfo(module);
// If the module doesn't have an exportsType, it's a module
@@ -188,11 +191,14 @@ class FlagDependencyExportsPlugin {
*/
const mergeExports = (exportsInfo, exports) => {
for (const exportNameOrSpec of exports) {
/** @type {ExportInfoName} */
let name;
let canMangle = globalCanMangle;
let terminalBinding = globalTerminalBinding;
/** @type {ExportSpec["exports"]} */
let exports;
let from = globalFrom;
/** @type {ExportSpec["export"]} */
let fromExport;
let priority = globalPriority;
let hidden = false;
@@ -270,6 +276,7 @@ class FlagDependencyExportsPlugin {
// Recalculate target exportsInfo
const target = exportInfo.getTarget(moduleGraph);
/** @type {undefined | ExportsInfo} */
let targetExportsInfo;
if (target) {
const targetModuleExportsInfo =

View File

@@ -31,6 +31,7 @@ class FlagDependencyUsagePlugin {
* @param {boolean} global do a global analysis instead of per runtime
*/
constructor(global) {
/** @type {boolean} */
this.global = global;
}
@@ -80,6 +81,7 @@ class FlagDependencyUsagePlugin {
return;
}
for (const usedExportInfo of usedExports) {
/** @type {string[]} */
let usedExport;
let canMangle = true;
if (Array.isArray(usedExportInfo)) {
@@ -167,7 +169,8 @@ class FlagDependencyUsagePlugin {
* @returns {void}
*/
const processModule = (module, runtime, forceSideEffects) => {
/** @type {Map<Module, ReferencedExports | Map<string, string[] | ReferencedExport>>} */
/** @typedef {Map<string, string[] | ReferencedExport>} ExportMaps */
/** @type {Map<Module, ReferencedExports | ExportMaps>} */
const map = new Map();
/** @type {ArrayQueue<DependenciesBlock>} */
@@ -177,14 +180,12 @@ class FlagDependencyUsagePlugin {
const block = queue.dequeue();
if (block === undefined) break;
for (const b of block.blocks) {
if (
!this.global &&
b.groupOptions &&
b.groupOptions.entryOptions
) {
if (b.groupOptions && b.groupOptions.entryOptions) {
processModule(
b,
b.groupOptions.entryOptions.runtime || undefined,
this.global
? undefined
: b.groupOptions.entryOptions.runtime || undefined,
true
);
} else {
@@ -221,6 +222,7 @@ class FlagDependencyUsagePlugin {
) {
continue;
} else {
/** @type {undefined | ExportMaps} */
let exportsMap;
if (Array.isArray(oldReferencedExports)) {
exportsMap = new Map();

View File

@@ -10,6 +10,7 @@ module.exports = class HarmonyLinkingError extends WebpackError {
/** @param {string} message Error message */
constructor(message) {
super(message);
/** @type {string} */
this.name = "HarmonyLinkingError";
this.hideStack = true;
}

View File

@@ -30,6 +30,7 @@ class HookWebpackError extends WebpackError {
this.hook = hook;
this.error = error;
/** @type {string} */
this.name = "HookWebpackError";
this.hideStack = true;
this.stack += `\n-- inner error --\n${error ? error.stack : ""}`;
@@ -104,6 +105,7 @@ module.exports.makeWebpackErrorCallback = makeWebpackErrorCallback;
* @returns {T} the result
*/
const tryRunOrWebpackError = (fn, hook) => {
/** @type {T} */
let r;
try {
r = fn();

View File

@@ -75,7 +75,10 @@ const {
/** @typedef {Record<ChunkId, string>} ChunkRuntime */
/** @typedef {Record<ChunkId, ModuleId[]>} ChunkModuleIds */
/** @typedef {{ updatedChunkIds: Set<ChunkId>, removedChunkIds: Set<ChunkId>, removedModules: Set<Module>, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
/** @typedef {Set<ChunkId>} ChunkIds */
/** @typedef {Set<Module>} ModuleSet */
/** @typedef {{ updatedChunkIds: ChunkIds, removedChunkIds: ChunkIds, removedModules: ModuleSet, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
/** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */
/** @type {WeakMap<JavascriptParser, HMRJavascriptParserHooks>} */
@@ -517,6 +520,7 @@ class HotModuleReplacementPlugin {
/** @type {HotUpdateMainContentByRuntime} */
const hotUpdateMainContentByRuntime = new Map();
/** @type {RuntimeSpec} */
let allOldRuntime;
const chunkRuntime =
/** @type {ChunkRuntime} */
@@ -537,8 +541,11 @@ class HotModuleReplacementPlugin {
hotUpdateMainContentByRuntime.set(
/** @type {string} */ (runtime),
{
/** @type {ChunkIds} */
updatedChunkIds: new Set(),
/** @type {ChunkIds} */
removedChunkIds: new Set(),
/** @type {ModuleSet} */
removedModules: new Set(),
filename,
assetInfo
@@ -580,11 +587,17 @@ class HotModuleReplacementPlugin {
/** @type {ChunkId | null} */
let chunkId;
/** @type {undefined | Module[]} */
let newModules;
/** @type {undefined | RuntimeModule[]} */
let newRuntimeModules;
/** @type {undefined | RuntimeModule[]} */
let newFullHashModules;
/** @type {undefined | RuntimeModule[]} */
let newDependentHashModules;
/** @type {RuntimeSpec} */
let newRuntime;
/** @type {RuntimeSpec} */
let removedFromRuntime;
const currentChunk = find(
compilation.chunks,
@@ -775,6 +788,7 @@ class HotModuleReplacementPlugin {
}
}
const completelyRemovedModulesArray = [...completelyRemovedModules];
/** @type {Map<string, Omit<HotUpdateMainContentByRuntimeItem, "filename">>} */
const hotUpdateMainContentByFilename = new Map();
for (const {
removedChunkIds,
@@ -818,7 +832,7 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
filename,
{ removedChunkIds, removedModules, updatedChunkIds, assetInfo }
] of hotUpdateMainContentByFilename) {
/** @type {{c: ChunkId[], r: ChunkId[], m: ModuleId[], css?: {r: ChunkId[]}}} */
/** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], css?: { r: ChunkId[] } }} */
const hotUpdateMainJson = {
c: [...updatedChunkIds],
r: [...removedChunkIds],

View File

@@ -5,16 +5,19 @@
"use strict";
/** @typedef {import("../declarations/WebpackOptions").IgnoreWarningsNormalized} IgnoreWarningsNormalized */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {(warning: Error, compilation: Compilation) => boolean} IgnoreFn */
const PLUGIN_NAME = "IgnoreWarningsPlugin";
class IgnoreWarningsPlugin {
/**
* @param {IgnoreWarningsNormalized} ignoreWarnings conditions to ignore warnings
* @param {IgnoreFn[]} ignoreWarnings conditions to ignore warnings
*/
constructor(ignoreWarnings) {
/** @type {IgnoreFn[]} */
this._ignoreWarnings = ignoreWarnings;
}

View File

@@ -133,6 +133,7 @@ class InitFragment {
}
const concatSource = new ConcatSource();
/** @type {(string | Source)[]} */
const endContents = [];
for (let fragment of keyedFragments.values()) {
if (Array.isArray(fragment)) {

View File

@@ -29,6 +29,7 @@ ${depsList.slice(0, 3).join("\n")}${
depsList.length > 3 ? "\n * and more ..." : ""
}`);
/** @type {string} */
this.name = "InvalidDependenciesModuleWarning";
this.details = depsList.slice(3).join("\n");
this.module = module;

View File

@@ -55,6 +55,7 @@ class LibManifestPlugin {
(compilation, callback) => {
const moduleGraph = compilation.moduleGraph;
// store used paths to detect issue and output an error. #18200
/** @type {Set<string>} */
const usedPaths = new Set();
asyncLib.each(
[...compilation.chunks],

View File

@@ -22,6 +22,10 @@ const createSchemaValidation = require("./util/create-schema-validation");
/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestEntrypoint} ManifestEntrypoint */
/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestItem} ManifestItem */
/** @typedef {(item: ManifestItem) => boolean} Filter */
/** @typedef {(manifest: ManifestObject) => ManifestObject} Generate */
/** @typedef {(manifest: ManifestObject) => string} Serialize */
const PLUGIN_NAME = "ManifestPlugin";
const validate = createSchemaValidation(
@@ -42,7 +46,9 @@ const extname = (filename) => {
const split = replaced.split(".");
const last = split.pop();
if (!last) return "";
return last && /^(gz|br|map)$/i.test(last) ? `${split.pop()}.${last}` : last;
return last && /^(?:gz|br|map)$/i.test(last)
? `${split.pop()}.${last}`
: last;
};
class ManifestPlugin {
@@ -121,6 +127,7 @@ class ManifestPlugin {
const entrypoints = {};
for (const [name, entrypoint] of compilation.entrypoints) {
/** @type {string[]} */
const imports = [];
for (const chunk of entrypoint.chunks) {

11
node_modules/webpack/lib/Module.js generated vendored
View File

@@ -106,13 +106,15 @@ const makeSerializable = require("./util/makeSerializable");
/** @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>} KnownCodeGenerationResultDataForAssetModules */
/** @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 {Map<SourceType, Source>} Sources */
/**
* @typedef {object} CodeGenerationResult
* @property {Map<SourceType, Source>} sources the resulting sources for all source types
* @property {Sources} sources the resulting sources for all source types
* @property {CodeGenerationResultData=} data the resulting data for all source types
* @property {ReadOnlyRuntimeRequirements | null} runtimeRequirements the runtime requirements
* @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
@@ -135,8 +137,8 @@ const makeSerializable = require("./util/makeSerializable");
* @property {boolean=} sideEffectFree
* @property {boolean=} isCSSModule
* @property {Record<string, string>=} jsIncompatibleExports
* @property {Map<RuntimeSpec, Record<string, string>>=} exportsFinalNameByRuntime
* @property {Map<RuntimeSpec, string>=} exportsSourceByRuntime
* @property {Map<string, Record<string, string>>=} exportsFinalNameByRuntime
* @property {Map<string, string>=} exportsSourceByRuntime
*/
/**
@@ -1026,6 +1028,7 @@ class Module extends DependenciesBlock {
*/
codeGeneration(context) {
// Best override this method
/** @type {Sources} */
const sources = new Map();
for (const type of this.getSourceTypes()) {
if (type !== UNKNOWN_TYPE) {

View File

@@ -17,10 +17,11 @@ const makeSerializable = require("./util/makeSerializable");
class ModuleBuildError extends WebpackError {
/**
* @param {string | ErrorWithHideStack} err error thrown
* @param {{from?: string | null}} info additional info
* @param {{ from?: string | null }} info additional info
*/
constructor(err, { from = null } = {}) {
let message = "Module build failed";
/** @type {undefined | string} */
let details;
message += from ? ` (from ${from}):\n` : ": ";
@@ -48,6 +49,7 @@ class ModuleBuildError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleBuildError";
this.details = details;
this.error = err;

View File

@@ -21,6 +21,7 @@ class ModuleDependencyError extends WebpackError {
constructor(module, err, loc) {
super(err.message);
/** @type {string} */
this.name = "ModuleDependencyError";
this.details =
err && !err.hideStack

View File

@@ -21,6 +21,7 @@ class ModuleDependencyWarning extends WebpackError {
constructor(module, err, loc) {
super(err ? err.message : "");
/** @type {string} */
this.name = "ModuleDependencyWarning";
this.details =
err && !err.hideStack

View File

@@ -15,7 +15,7 @@ const makeSerializable = require("./util/makeSerializable");
class ModuleError extends WebpackError {
/**
* @param {Error} err error thrown
* @param {{from?: string | null}} info additional info
* @param {{ from?: string | null }} info additional info
*/
constructor(err, { from = null } = {}) {
let message = "Module Error";
@@ -30,8 +30,11 @@ class ModuleError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleError";
/** @type {Error} */
this.error = err;
/** @type {string | undefined} */
this.details =
err && typeof err === "object" && err.stack
? cleanUp(err.stack, this.message)

View File

@@ -15,7 +15,8 @@ const memoize = require("./util/memoize");
/** @typedef {import("./Module")} Module */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {string | RegExp | ((str: string) => boolean) | (string | RegExp | ((str: string) => boolean))[]} Matcher */
/** @typedef {(str: string) => boolean} MatcherFn */
/** @typedef {string | RegExp | MatcherFn | (string | RegExp | MatcherFn)[]} Matcher */
/** @typedef {{ test?: Matcher, include?: Matcher, exclude?: Matcher }} MatchObject */
const ModuleFilenameHelpers = module.exports;
@@ -115,7 +116,7 @@ const lazyObject = (obj) => {
return newObj;
};
const SQUARE_BRACKET_TAG_REGEXP = /\[\\*([\w-]+)\\*\]/gi;
const SQUARE_BRACKET_TAG_REGEXP = /\[\\*([\w-]+)\\*\]/g;
/**
* @typedef {object} ModuleFilenameTemplateContext
* @property {string} identifier the identifier of the module
@@ -157,6 +158,7 @@ ModuleFilenameHelpers.createFilename = (
/** @type {ReturnStringCallback} */
let absoluteResourcePath;
/** @type {ReturnStringCallback} */
let hash;
/** @type {ReturnStringCallback} */
let identifier;

View File

@@ -33,6 +33,7 @@ const { sortWithSourceOrder } = require("./util/comparators");
* @returns {string}
*/
/** @type {Iterable<ModuleGraphConnection>} */
const EMPTY_SET = new Set();
/**
@@ -42,6 +43,7 @@ const EMPTY_SET = new Set();
* @returns {ReadonlyMap<T, ReadonlyArray<ModuleGraphConnection>>} mapped by key
*/
const getConnectionsByKey = (set, getKey) => {
/** @type {Map<T, ModuleGraphConnection[]>} */
const map = new Map();
/** @type {T | 0} */
let lastKey = 0;
@@ -528,6 +530,7 @@ class ModuleGraph {
mgm._unassignedConnections &&
mgm._unassignedConnections.length !== 0
) {
/** @type {undefined | ModuleGraphConnection} */
let foundConnection;
for (const connection of mgm._unassignedConnections) {
this._dependencyMap.set(

View File

@@ -57,7 +57,7 @@ class ModuleGraphConnection {
* @param {Module} module the referenced module
* @param {string=} explanation some extra detail
* @param {boolean=} weak the reference is weak
* @param {false | null | GetConditionFn | undefined} condition condition for the connection
* @param {false | null | GetConditionFn=} condition condition for the connection
*/
constructor(
originModule,
@@ -67,14 +67,23 @@ class ModuleGraphConnection {
weak = false,
condition = undefined
) {
/** @type {Module | null} */
this.originModule = originModule;
/** @type {Module | null} */
this.resolvedOriginModule = originModule;
/** @type {Dependency | null} */
this.dependency = dependency;
/** @type {Module} */
this.resolvedModule = module;
/** @type {Module} */
this.module = module;
/** @type {boolean | undefined} */
this.weak = weak;
/** @type {boolean} */
this.conditional = Boolean(condition);
/** @type {boolean} */
this._active = condition !== false;
/** @type {false | null | GetConditionFn | undefined} */
this.condition = condition || undefined;
/** @type {Set<string> | undefined} */
this.explanations = undefined;

View File

@@ -18,6 +18,7 @@ class ModuleHashingError extends WebpackError {
constructor(module, error) {
super();
/** @type {string} */
this.name = "ModuleHashingError";
this.error = error;
this.message = error.message;
@@ -26,4 +27,5 @@ class ModuleHashingError extends WebpackError {
}
}
/** @type {typeof ModuleHashingError} */
module.exports = ModuleHashingError;

View File

@@ -63,6 +63,7 @@ const printExportsInfoToSource = (
let alreadyPrintedExports = 0;
// determine exports to print
/** @type {ExportInfo[]} */
const printedExports = [];
for (const exportInfo of exportsInfo.orderedExports) {
if (!alreadyPrinted.has(exportInfo)) {
@@ -145,7 +146,8 @@ const printExportsInfoToSource = (
}
};
/** @type {WeakMap<RequestShortener, WeakMap<Module, { header: RawSource | undefined, full: WeakMap<Source, CachedSource> }>>} */
/** @typedef {{ header: RawSource | undefined, full: WeakMap<Source, CachedSource> }} CacheEntry */
/** @type {WeakMap<RequestShortener, WeakMap<Module, CacheEntry>>} */
const caches = new WeakMap();
const PLUGIN_NAME = "ModuleInfoHeaderPlugin";
@@ -155,6 +157,7 @@ class ModuleInfoHeaderPlugin {
* @param {boolean=} verbose add more information like exports, runtime requirements and bailouts
*/
constructor(verbose = true) {
/** @type {boolean} */
this._verbose = verbose;
}
@@ -175,6 +178,7 @@ class ModuleInfoHeaderPlugin {
{ chunk, chunkGraph, moduleGraph, runtimeTemplate }
) => {
const { requestShortener } = runtimeTemplate;
/** @type {undefined | CacheEntry} */
let cacheEntry;
let cache = caches.get(requestShortener);
if (cache === undefined) {
@@ -256,6 +260,7 @@ class ModuleInfoHeaderPlugin {
PLUGIN_NAME,
(moduleSource, module, { runtimeTemplate }) => {
const { requestShortener } = runtimeTemplate;
/** @type {undefined | CacheEntry} */
let cacheEntry;
let cache = caches.get(requestShortener);
if (cache === undefined) {

View File

@@ -78,6 +78,7 @@ class ModuleNotFoundError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleNotFoundError";
this.details = err.details;
this.module = module;

View File

@@ -8,6 +8,7 @@
const WebpackError = require("./WebpackError");
const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("./Dependency").SourcePosition} SourcePosition */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
@@ -23,6 +24,7 @@ class ModuleParseError extends WebpackError {
*/
constructor(source, err, loaders, type) {
let message = `Module parse failed: ${err && err.message}`;
/** @type {undefined | DependencyLocation} */
let loc;
if (
@@ -40,7 +42,8 @@ class ModuleParseError extends WebpackError {
"\nFor files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: \"webassembly/async\"').";
} else if (!loaders) {
message +=
"\nYou may need an appropriate loader to handle this file type.";
"\nYou may need an appropriate loader to handle this file type. " +
"See https://webpack.js.org/concepts/loaders";
} else if (loaders.length >= 1) {
message += `\nFile was processed with these loaders:${loaders
.map((loader) => `\n * ${loader}`)
@@ -88,6 +91,7 @@ class ModuleParseError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleParseError";
this.loc = loc;
this.error = err;

View File

@@ -34,7 +34,7 @@ class ModuleProfile {
this.storing = 0;
this.storingParallelismFactor = 0;
/** @type {{ start: number, end: number }[] | undefined } */
/** @type {{ start: number, end: number }[] | undefined} */
this.additionalFactoryTimes = undefined;
this.additionalFactories = 0;
this.additionalFactoriesParallelismFactor = 0;

View File

@@ -33,6 +33,7 @@ class ModuleRestoreError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleRestoreError";
/** @type {string | undefined} */
this.details = details;
@@ -41,4 +42,5 @@ class ModuleRestoreError extends WebpackError {
}
}
/** @type {typeof ModuleRestoreError} */
module.exports = ModuleRestoreError;

View File

@@ -61,17 +61,7 @@ const CONSUME_SHARED_GENERATOR_TYPE = "consume-shared";
const UNKNOWN_TYPE = "unknown";
/**
* @typedef {JAVASCRIPT_TYPE |
* RUNTIME_TYPE |
* WEBASSEMBLY_TYPE |
* ASSET_TYPE |
* CSS_TYPE |
* CSS_IMPORT_TYPE |
* CSS_URL_TYPE |
* SHARED_INIT_TYPE |
* REMOTE_GENERATOR_TYPE |
* CONSUME_SHARED_GENERATOR_TYPE |
* UNKNOWN_TYPE} AllTypes
* @typedef {JAVASCRIPT_TYPE | RUNTIME_TYPE | WEBASSEMBLY_TYPE | ASSET_TYPE | CSS_TYPE | CSS_IMPORT_TYPE | CSS_URL_TYPE | SHARED_INIT_TYPE | REMOTE_GENERATOR_TYPE | CONSUME_SHARED_GENERATOR_TYPE | UNKNOWN_TYPE} AllTypes
*/
/**

View File

@@ -33,6 +33,7 @@ class ModuleStoreError extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleStoreError";
this.details = /** @type {string | undefined} */ (details);
this.module = module;
@@ -40,4 +41,5 @@ class ModuleStoreError extends WebpackError {
}
}
/** @type {typeof ModuleStoreError} */
module.exports = ModuleStoreError;

View File

@@ -15,7 +15,7 @@ const makeSerializable = require("./util/makeSerializable");
class ModuleWarning extends WebpackError {
/**
* @param {Error} warning error thrown
* @param {{from?: string | null}} info additional info
* @param {{ from?: string | null }} info additional info
*/
constructor(warning, { from = null } = {}) {
let message = "Module Warning";
@@ -30,6 +30,7 @@ class ModuleWarning extends WebpackError {
super(message);
/** @type {string} */
this.name = "ModuleWarning";
this.warning = warning;
this.details =
@@ -63,4 +64,5 @@ class ModuleWarning extends WebpackError {
makeSerializable(ModuleWarning, "webpack/lib/ModuleWarning");
/** @type {typeof ModuleWarning} */
module.exports = ModuleWarning;

View File

@@ -137,10 +137,11 @@ module.exports = class MultiCompiler {
compilation.warnings.push(warning);
});
};
/** @type {Set<string>} */
const cacheNames = new Set();
for (const compiler of this.compilers) {
if (compiler.options.cache && "name" in compiler.options.cache) {
const name = compiler.options.cache.name;
const name = /** @type {string} */ (compiler.options.cache.name);
if (cacheNames.has(name)) {
addWarning(
compiler,
@@ -255,7 +256,7 @@ module.exports = class MultiCompiler {
* @returns {boolean} true if the dependencies are valid
*/
validateDependencies(callback) {
/** @type {Set<{source: Compiler, target: Compiler}>} */
/** @type {Set<{ source: Compiler, target: Compiler }>} */
const edges = new Set();
/** @type {string[]} */
const missing = [];
@@ -272,8 +273,8 @@ module.exports = class MultiCompiler {
return false;
};
/**
* @param {{source: Compiler, target: Compiler}} e1 edge 1
* @param {{source: Compiler, target: Compiler}} e2 edge 2
* @param {{ source: Compiler, target: Compiler }} e1 edge 1
* @param {{ source: Compiler, target: Compiler }} e2 edge 2
* @returns {number} result
*/
const sortEdges = (e1, e2) =>
@@ -339,6 +340,7 @@ module.exports = class MultiCompiler {
* @returns {void}
*/
runWithDependencies(compilers, fn, callback) {
/** @type {Set<string>} */
const fulfilledNames = new Set();
let remainingCompilers = compilers;
/**
@@ -350,6 +352,7 @@ module.exports = class MultiCompiler {
* @returns {Compiler[]} compilers
*/
const getReadyCompilers = () => {
/** @type {Compiler[]} */
const readyCompilers = [];
const list = remainingCompilers;
remainingCompilers = [];
@@ -376,12 +379,12 @@ module.exports = class MultiCompiler {
(compiler, callback) => {
fn(compiler, (err) => {
if (err) return callback(err);
fulfilledNames.add(compiler.name);
fulfilledNames.add(/** @type {string} */ (compiler.name));
runCompilers(callback);
});
},
(err, results) => {
callback(err, results);
callback(/** @type {Error | null} */ (err), results);
}
);
};
@@ -567,6 +570,7 @@ module.exports = class MultiCompiler {
running === 0 &&
nodes.every((node) => node.state === "done")
) {
/** @type {Stats[]} */
const stats = [];
for (const node of nodes) {
const result = node.result;
@@ -667,7 +671,7 @@ module.exports = class MultiCompiler {
compiler.close(callback);
},
(error) => {
callback(error);
callback(/** @type {Error | null} */ (error));
}
);
}

View File

@@ -31,7 +31,7 @@ class MultiWatching {
this.watchings,
(watching, callback) => watching.invalidate(callback),
(err) => {
callback(err);
callback(/** @type {Error | null} */ (err));
}
);
} else {
@@ -67,7 +67,7 @@ class MultiWatching {
this.compiler.hooks.watchClose.call();
if (typeof callback === "function") {
this.compiler.running = false;
callback(err);
callback(/** @type {Error | null} */ (err));
}
}
);

View File

@@ -11,6 +11,7 @@ module.exports = class NoModeWarning extends WebpackError {
constructor() {
super();
/** @type {string} */
this.name = "NoModeWarning";
this.message =
"configuration\n" +

View File

@@ -24,6 +24,7 @@ class NodeStuffInWebError extends WebpackError {
${description}`
);
/** @type {string} */
this.name = "NodeStuffInWebError";
this.loc = loc;
}

View File

@@ -79,6 +79,7 @@ const memoize = require("./util/memoize");
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").BuildCallback} BuildCallback */
/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./Module").SourceType} SourceType */
/** @typedef {import("./Module").SourceTypes} SourceTypes */
/** @typedef {import("./Module").UnsafeCacheData} UnsafeCacheData */
@@ -115,6 +116,8 @@ const memoize = require("./util/memoize");
* @typedef {import("../declarations/LoaderContext").NormalModuleLoaderContext<T>} NormalModuleLoaderContext
*/
/** @typedef {(content: string) => boolean} NoParseFn */
const getInvalidDependenciesModuleWarning = memoize(() =>
require("./InvalidDependenciesModuleWarning")
);
@@ -123,7 +126,7 @@ const getExtractSourceMap = memoize(() => require("./util/extractSourceMap"));
const getValidate = memoize(() => require("schema-utils").validate);
const ABSOLUTE_PATH_REGEX = /^([a-zA-Z]:\\|\\\\|\/)/;
const ABSOLUTE_PATH_REGEX = /^(?:[a-z]:\\|\\\\|\/)/i;
/**
* @typedef {object} LoaderItem
@@ -360,7 +363,7 @@ class NormalModule extends Module {
/** @type {NormalModuleCreateData['rawRequest']} */
this.rawRequest = rawRequest;
/** @type {boolean} */
this.binary = /^(asset|webassembly)\b/.test(type);
this.binary = /^(?:asset|webassembly)\b/.test(type);
/** @type {NormalModuleCreateData['parser'] | undefined} */
this.parser = parser;
/** @type {NormalModuleCreateData['parserOptions']} */
@@ -403,14 +406,31 @@ class NormalModule extends Module {
* @type {undefined | SourceTypes}
*/
this._sourceTypes = undefined;
// Cache
/**
* @private
* @type {BuildMeta}
*/
this._lastSuccessfulBuildMeta = {};
/**
* @private
* @type {boolean}
*/
this._forceBuild = true;
/**
* @private
* @type {boolean}
*/
this._isEvaluatingSideEffects = false;
/** @type {WeakSet<ModuleGraph> | undefined} */
/**
* @private
* @type {WeakSet<ModuleGraph> | undefined}
*/
this._addedSideEffectsBailout = undefined;
/** @type {CodeGenerationResultData} */
/**
* @private
* @type {CodeGenerationResultData}
*/
this._codeGeneratorData = new Map();
}
@@ -718,6 +738,7 @@ class NormalModule extends Module {
if (schema) {
let name = "Loader";
let baseDataPath = "options";
/** @type {RegExpExecArray | null} */
let match;
if (schema.title && (match = /^(.+) (.+)$/.exec(schema.title))) {
[, name, baseDataPath] = match;
@@ -982,6 +1003,7 @@ class NormalModule extends Module {
compilation.compiler.root
);
if (this._sourceSizes !== undefined) this._sourceSizes.clear();
/** @type {PreparsedAst | null} */
this._ast =
typeof extraInfo === "object" &&
extraInfo !== null &&
@@ -1518,6 +1540,7 @@ class NormalModule extends Module {
const getData = () => this._codeGeneratorData;
/** @type {Sources} */
const sources = new Map();
for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) {
// TODO webpack@6 make generateError required

View File

@@ -54,6 +54,7 @@ const {
/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
/** @typedef {import("./rules/RuleSetCompiler").RuleSetRules} RuleSetRules */
/** @typedef {import("./rules/RuleSetCompiler").RuleSet} RuleSet */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
@@ -104,7 +105,7 @@ const {
/**
* @typedef {object} ParsedLoaderRequest
* @property {string} loader loader
* @property {string|undefined} options options
* @property {string | undefined} options options
*/
/** @typedef {import("./ModuleTypeConstants").JAVASCRIPT_MODULE_TYPE_AUTO} JAVASCRIPT_MODULE_TYPE_AUTO */
@@ -195,6 +196,7 @@ const needCalls = (times, callback) => (err) => {
*/
const mergeGlobalOptions = (globalOptions, type, localOptions) => {
const parts = type.split("/");
/** @type {undefined | T} */
let result;
let current = "";
for (const part of parts) {
@@ -302,6 +304,7 @@ const ruleSetCompiler = new RuleSetCompiler([
/** @typedef {import("../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */
/* eslint-disable jsdoc/type-formatting */
/**
* @typedef {[
* [JAVASCRIPT_MODULE_TYPE_AUTO, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
@@ -322,6 +325,7 @@ const ruleSetCompiler = new RuleSetCompiler([
* [string, Parser, ParserOptions, Generator, GeneratorOptions],
* ]} ParsersAndGeneratorsByTypes
*/
/* eslint-enable jsdoc/type-formatting */
/**
* @template {unknown[]} T
@@ -391,7 +395,9 @@ class NormalModuleFactory extends ModuleFactory {
() => new SyncBailHook(["createData", "resolveData"])
)
});
/** @type {ResolverFactory} */
this.resolverFactory = resolverFactory;
/** @type {RuleSet} */
this.ruleSet = ruleSetCompiler.compile([
{
rules: /** @type {RuleSetRules} */ (options.defaultRules)
@@ -400,7 +406,9 @@ class NormalModuleFactory extends ModuleFactory {
rules: /** @type {RuleSetRules} */ (options.rules)
}
]);
/** @type {string} */
this.context = context || "";
/** @type {InputFileSystem} */
this.fs = fs;
this._globalParserOptions = options.parser;
this._globalGeneratorOptions = options.generator;
@@ -662,7 +670,9 @@ class NormalModuleFactory extends ModuleFactory {
const useLoadersPre = [];
// handle .webpack[] suffix
/** @type {string} */
let resource;
/** @type {RegExpExecArray | null} */
let match;
if (
matchResourceData &&
@@ -853,7 +863,7 @@ class NormalModuleFactory extends ModuleFactory {
* @param {string} context context
*/
const defaultResolve = (context) => {
if (/^($|\?)/.test(unresolvedResource)) {
if (/^(?:$|\?)/.test(unresolvedResource)) {
resourceData = {
...cacheParseResource(unresolvedResource),
resource: unresolvedResource,
@@ -969,8 +979,11 @@ class NormalModuleFactory extends ModuleFactory {
(dependency).attributes;
const dependencyType = dependency.category || "";
const contextInfo = data.contextInfo;
/** @type {FileSystemDependencies} */
const fileDependencies = new LazySet();
/** @type {FileSystemDependencies} */
const missingDependencies = new LazySet();
/** @type {FileSystemDependencies} */
const contextDependencies = new LazySet();
/** @type {ResolveData} */
const resolveData = {
@@ -1185,7 +1198,7 @@ Add the extension to the request.`
(err, resolvedResource) => {
if (!err && resolvedResource) {
let hint = "";
const match = /(\.[^.]+)(\?|$)/.exec(unresolvedResource);
const match = /\.[^.]+(?:\?|$)/.exec(unresolvedResource);
if (match) {
const fixedRequest = unresolvedResource.replace(
/(\.[^.]+)(\?|$)/,
@@ -1335,7 +1348,10 @@ If changing the source code is not an option there is also a resolve options cal
);
},
(err, value) => {
callback(err, /** @type {(LoaderItem)[]} */ (value));
callback(
/** @type {Error | null} */ (err),
/** @type {(LoaderItem)[]} */ (value)
);
}
);
}

View File

@@ -6,15 +6,17 @@
"use strict";
/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
/** @typedef {import("./config/normalization").WebpackOptionsInterception} WebpackOptionsInterception */
/** @typedef {import("./Compiler")} Compiler */
class OptionsApply {
/**
* @param {WebpackOptions} options options object
* @param {Compiler} compiler compiler object
* @param {WebpackOptionsInterception=} interception intercepted options
* @returns {WebpackOptions} options object
*/
process(options, compiler) {
process(options, compiler, interception) {
return options;
}
}

View File

@@ -235,6 +235,7 @@ class ProgressPlugin {
let doneModules = 0;
let doneDependencies = 0;
let doneEntries = 0;
/** @type {Set<string>} */
const activeModules = new Set();
let lastUpdate = 0;
@@ -254,6 +255,7 @@ class ProgressPlugin {
const percentByDependencies =
doneDependencies /
Math.max(lastDependenciesCount || 1, dependenciesCount);
/** @type {number} */
let percentageFactor;
switch (this.percentBy) {
@@ -285,6 +287,7 @@ class ProgressPlugin {
)}`
);
} else {
/** @type {string[]} */
const statItems = [];
if (showEntries) {
statItems.push(`${doneEntries}/${entriesCount} entries`);
@@ -480,6 +483,7 @@ class ProgressPlugin {
// @ts-expect-error avoid dynamic require if bundled with webpack
if (typeof __webpack_require__ !== "function") {
/** @type {Set<string>} */
const requiredLoaders = new Set();
NormalModule.getCompilationHooks(compilation).beforeLoaders.tap(
PLUGIN_NAME,

View File

@@ -24,6 +24,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
/** @typedef {import("./RequestShortener")} RequestShortener */
@@ -122,6 +123,7 @@ class RawModule extends Module {
* @returns {CodeGenerationResult} result
*/
codeGeneration(context) {
/** @type {Sources} */
const sources = new Map();
if (this.useSourceMap || this.useSimpleSourceMap) {
sources.set(

View File

@@ -17,11 +17,14 @@ const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants");
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
/** @typedef {import("./Generator").SourceTypes} SourceTypes */
/** @typedef {import("./Module").BuildMeta} BuildMeta */
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./Module").BuildCallback} BuildCallback */
/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").Sources} Sources */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./util/Hash")} Hash */
@@ -34,9 +37,13 @@ class RuntimeModule extends Module {
*/
constructor(name, stage = 0) {
super(WEBPACK_MODULE_TYPE_RUNTIME);
/** @type {string} */
this.name = name;
/** @type {number} */
this.stage = stage;
/** @type {BuildMeta} */
this.buildMeta = {};
/** @type {BuildInfo} */
this.buildInfo = {};
/** @type {Compilation | undefined} */
this.compilation = undefined;
@@ -44,7 +51,9 @@ class RuntimeModule extends Module {
this.chunk = undefined;
/** @type {ChunkGraph | undefined} */
this.chunkGraph = undefined;
/** @type {boolean} */
this.fullHash = false;
/** @type {boolean} */
this.dependentHash = false;
/** @type {string | undefined | null} */
this._cachedGeneratedCode = undefined;
@@ -134,6 +143,7 @@ class RuntimeModule extends Module {
* @returns {CodeGenerationResult} result
*/
codeGeneration(context) {
/** @type {Sources} */
const sources = new Map();
const generatedCode = this.getGeneratedCode();
if (generatedCode) {

View File

@@ -111,6 +111,8 @@ const TREE_DEPENDENCIES = {
[RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
};
const FULLHASH_REGEXP = /\[(?:full)?hash(?::\d+)?\]/;
const PLUGIN_NAME = "RuntimePlugin";
class RuntimePlugin {
@@ -266,7 +268,7 @@ class RuntimePlugin {
if (
typeof publicPath !== "string" ||
/\[(full)?hash\]/.test(publicPath)
/\[(?:full)?hash\]/.test(publicPath)
) {
module.fullHash = true;
}
@@ -314,9 +316,7 @@ class RuntimePlugin {
.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
if (
typeof compilation.outputOptions.chunkFilename === "string" &&
/\[(full)?hash(:\d+)?\]/.test(
compilation.outputOptions.chunkFilename
)
FULLHASH_REGEXP.test(compilation.outputOptions.chunkFilename)
) {
set.add(RuntimeGlobals.getFullHash);
}
@@ -342,9 +342,7 @@ class RuntimePlugin {
.tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
if (
typeof compilation.outputOptions.cssChunkFilename === "string" &&
/\[(full)?hash(:\d+)?\]/.test(
compilation.outputOptions.cssChunkFilename
)
FULLHASH_REGEXP.test(compilation.outputOptions.cssChunkFilename)
) {
set.add(RuntimeGlobals.getFullHash);
}
@@ -374,7 +372,7 @@ class RuntimePlugin {
.for(RuntimeGlobals.getChunkUpdateScriptFilename)
.tap(PLUGIN_NAME, (chunk, set) => {
if (
/\[(full)?hash(:\d+)?\]/.test(
FULLHASH_REGEXP.test(
compilation.outputOptions.hotUpdateChunkFilename
)
) {
@@ -396,7 +394,7 @@ class RuntimePlugin {
.for(RuntimeGlobals.getUpdateManifestFilename)
.tap(PLUGIN_NAME, (chunk, set) => {
if (
/\[(full)?hash(:\d+)?\]/.test(
FULLHASH_REGEXP.test(
compilation.outputOptions.hotUpdateMainFilename
)
) {

View File

@@ -84,7 +84,7 @@ function getGlobalObject(definition) {
// iife
// call expression
// expression in parentheses
/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu.test(trimmed)
/^(?:[_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu.test(trimmed)
) {
return trimmed;
}
@@ -356,6 +356,7 @@ class RuntimeTemplate {
* @returns {string} comment
*/
comment({ request, chunkName, chunkReason, message, exportName }) {
/** @type {string} */
let content;
if (this.outputOptions.pathinfo) {
content = [message, request, chunkName, chunkReason]
@@ -678,6 +679,7 @@ class RuntimeTemplate {
runtimeRequirements
});
/** @type {string} */
let appending;
let idExpr = JSON.stringify(chunkGraph.getModuleId(module));
const comment = this.comment({
@@ -711,7 +713,10 @@ class RuntimeTemplate {
if (isModuleDeferred) {
runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
const mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
let mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
if (mode) mode = `${mode} | 16`;
const asyncDeps = Array.from(
getOutgoingAsyncModules(chunkGraph.moduleGraph, module),
(m) => chunkGraph.getModuleId(m)
@@ -852,14 +857,14 @@ class RuntimeTemplate {
* @param {object} options options object
* @param {boolean=} options.update whether a new variable should be created or the existing one updated
* @param {Module} options.module the module
* @param {Module} options.originModule module in which the statement is emitted
* @param {ModuleGraph} options.moduleGraph the module graph
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {string} options.importVar name of the import variable
* @param {Module} options.originModule module in which the statement is emitted
* @param {boolean=} options.weak true, if this is a weak dependency
* @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
* @param {ModuleDependency} options.dependency module dependency
* @param {string} options.importVar name of the import variable
* @param {string=} options.request the request that should be printed as comment
* @param {boolean=} options.weak true, if this is a weak dependency
* @param {ModuleDependency=} options.dependency module dependency
* @returns {[string, string]} the import statement and the compat statement
*/
importStatement({
@@ -918,6 +923,8 @@ class RuntimeTemplate {
(originModule.buildMeta).strictHarmonyModule
);
runtimeRequirements.add(RuntimeGlobals.require);
/** @type {string} */
let importContent;
const isModuleDeferred =
@@ -961,7 +968,7 @@ class RuntimeTemplate {
* @param {string | string[]} options.exportName the export name
* @param {Module} options.originModule the origin module
* @param {boolean | undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted
* @param {boolean} options.isCall true, if expression will be called
* @param {boolean | undefined} options.isCall true, if expression will be called
* @param {boolean | null} options.callContext when false, call context will not be preserved
* @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated
* @param {string} options.importVar the identifier name of the import variable

View File

@@ -51,9 +51,9 @@ const validate = createSchemaValidation(
*/
const METACHARACTERS_REGEXP = /[-[\]\\/{}()*+?.^$|]/g;
const CONTENT_HASH_DETECT_REGEXP = /\[contenthash(:\w+)?\]/;
const CONTENT_HASH_DETECT_REGEXP = /\[contenthash(?::\w+)?\]/;
const CSS_AND_JS_MODULE_EXTENSIONS_REGEXP = /\.((c|m)?js|css)($|\?)/i;
const CSS_EXTENSION_DETECT_REGEXP = /\.css($|\?)/i;
const CSS_EXTENSION_DETECT_REGEXP = /\.css(?:$|\?)/i;
const MAP_URL_COMMENT_REGEXP = /\[map\]/g;
const URL_COMMENT_REGEXP = /\[url\]/g;
const URL_FORMATTING_REGEXP = /^\n\/\/(.*)$/;
@@ -93,18 +93,19 @@ const getTaskForFile = (
compilation,
cacheItem
) => {
/** @type {string | Buffer} */
let source;
/** @type {RawSourceMap} */
/** @type {null | RawSourceMap} */
let sourceMap;
/**
* Check if asset can build source map
*/
if (asset.sourceAndMap) {
const sourceAndMap = asset.sourceAndMap(options);
sourceMap = /** @type {RawSourceMap} */ (sourceAndMap.map);
sourceMap = sourceAndMap.map;
source = sourceAndMap.source;
} else {
sourceMap = /** @type {RawSourceMap} */ (asset.map(options));
sourceMap = asset.map(options);
source = asset.source();
}
if (!sourceMap || typeof source !== "string") return;
@@ -173,6 +174,7 @@ class SourceMapDevToolPlugin {
const options = this.options;
options.test = options.test || CSS_AND_JS_MODULE_EXTENSIONS_REGEXP;
/** @type {(filename: string) => boolean} */
const matchObject = ModuleFilenameHelpers.matchObject.bind(
undefined,
options
@@ -310,7 +312,7 @@ class SourceMapDevToolPlugin {
if (
typeof module === "string" &&
/^(data|https?):/.test(module)
/^(?:data|https?):/.test(module)
) {
moduleToSourceNameMapping.set(module, module);
continue;
@@ -416,7 +418,9 @@ class SourceMapDevToolPlugin {
asyncLib.each(
tasks,
(task, callback) => {
/** @type {Record<string, Source>} */
const assets = Object.create(null);
/** @type {Record<string, AssetInfo | undefined>} */
const assetsInfo = Object.create(null);
const file = task.file;
const chunk = fileToChunk.get(file);
@@ -434,24 +438,27 @@ class SourceMapDevToolPlugin {
moduleToSourceNameMapping.get(m)
);
sourceMap.sources = /** @type {string[]} */ (moduleFilenames);
sourceMap.ignoreList = options.ignoreList
? sourceMap.sources.reduce(
/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
(acc, sourceName, idx) => {
const rule = /** @type {Rules} */ (
options.ignoreList
);
if (
ModuleFilenameHelpers.matchPart(sourceName, rule)
) {
acc.push(idx);
}
return acc;
if (options.ignoreList) {
const ignoreList = sourceMap.sources.reduce(
/** @type {(acc: number[], sourceName: string, idx: number) => number[]} */ (
(acc, sourceName, idx) => {
const rule = /** @type {Rules} */ (
options.ignoreList
);
if (
ModuleFilenameHelpers.matchPart(sourceName, rule)
) {
acc.push(idx);
}
),
[]
)
: [];
return acc;
}
),
[]
);
if (ignoreList.length > 0) {
sourceMap.ignoreList = ignoreList;
}
}
if (options.noSources) {
sourceMap.sourcesContent = undefined;

15
node_modules/webpack/lib/Template.js generated vendored
View File

@@ -36,10 +36,10 @@ const NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS =
const FUNCTION_CONTENT_REGEX = /^function\s?\(\)\s?\{\r?\n?|\r?\n?\}$/g;
const INDENT_MULTILINE_REGEX = /^\t/gm;
const LINE_SEPARATOR_REGEX = /\r?\n/g;
const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-zA-Z$_])/;
const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-zA-Z0-9$]+/g;
const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-z$_])/i;
const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-z0-9$]+/gi;
const COMMENT_END_REGEX = /\*\//g;
const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-z0-9_!§$()=\-^°]+/gi;
const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
/**
@@ -83,10 +83,14 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
* @typedef {(module: Module) => boolean} ModuleFilterPredicate
*/
/**
* @typedef {object} Stringable
* @property {() => string} toString
*/
class Template {
/**
* @template {EXPECTED_FUNCTION} T
* @param {T} fn a runtime function (.runtime.js) "template"
* @param {Stringable} fn a runtime function (.runtime.js) "template"
* @returns {string} the updated and normalized function string
*/
static getFunctionContent(fn) {
@@ -359,6 +363,7 @@ class Template {
const source = new ConcatSource();
for (const module of runtimeModules) {
const codeGenerationResults = renderContext.codeGenerationResults;
/** @type {undefined | Source} */
let runtimeSource;
if (codeGenerationResults) {
runtimeSource = codeGenerationResults.getSource(

View File

@@ -18,7 +18,7 @@ const { parseResource } = require("./util/identifier");
/** @typedef {import("./Compilation").PathData} PathData */
/** @typedef {import("./Compiler")} Compiler */
const REGEXP = /\[\\*([\w:]+)\\*\]/gi;
const REGEXP = /\[\\*([\w:]+)\\*\]/g;
/** @type {PathData["prepareId"]} */
const prepareId = (id) => {
@@ -32,7 +32,7 @@ const prepareId = (id) => {
} + "").replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_") + "`;
}
return id.replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_");
return id.replace(/(^[.-]|[^a-z0-9_-])+/gi, "_");
};
/**
@@ -52,6 +52,7 @@ const prepareId = (id) => {
const hashLength = (replacer, handler, assetInfo, hashName) => {
/** @type {Replacer} */
const fn = (match, arg, input) => {
/** @type {string} */
let result;
const length = arg && Number.parseInt(arg, 10);
@@ -107,6 +108,7 @@ const replacer = (value, allowEmpty) => {
return fn;
};
/** @type {Map<string, (...args: EXPECTED_ANY[]) => EXPECTED_ANY>} */
const deprecationCache = new Map();
const deprecatedFunction = (() => () => {})();
/**

View File

@@ -20,6 +20,7 @@ class UnhandledSchemeError extends WebpackError {
`\nYou may need an additional plugin to handle "${scheme}:" URIs.`
);
this.file = resource;
/** @type {string} */
this.name = "UnhandledSchemeError";
}
}

View File

@@ -18,8 +18,11 @@ class UnsupportedFeatureWarning extends WebpackError {
constructor(message, loc) {
super(message);
/** @type {string} */
this.name = "UnsupportedFeatureWarning";
/** @type {DependencyLocation} */
this.loc = loc;
/** @type {boolean} */
this.hideStack = true;
}
}

View File

@@ -48,6 +48,7 @@ class DeprecatedOptionWarning extends WebpackError {
constructor(option, value, suggestion) {
super();
/** @type {string} */
this.name = "DeprecatedOptionWarning";
this.message =
"configuration\n" +

View File

@@ -8,9 +8,9 @@
const { groupBy } = require("./util/ArrayHelpers");
const createSchemaValidation = require("./util/create-schema-validation");
/** @typedef {import("watchpack").TimeInfoEntries} TimeInfoEntries */
/** @typedef {import("../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions} WatchIgnorePluginOptions */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */
/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
/** @typedef {import("./util/fs").WatchMethod} WatchMethod */
/** @typedef {import("./util/fs").Watcher} Watcher */

View File

@@ -15,6 +15,7 @@ const Stats = require("./Stats");
/** @typedef {import("./logging/Logger").Logger} Logger */
/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */
/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
/** @typedef {import("./util/fs").Watcher} Watcher */
/**
* @template T
@@ -31,8 +32,10 @@ class Watching {
* @param {Callback<Stats>} handler completion handler
*/
constructor(compiler, watchOptions, handler) {
/** @type {null | number} */
this.startTime = null;
this.invalid = false;
/** @type {Callback<Stats>} */
this.handler = handler;
/** @type {ErrorCallback[]} */
this.callbacks = [];
@@ -64,7 +67,9 @@ class Watching {
this._initial = true;
this._invalidReported = true;
this._needRecords = true;
/** @type {undefined | null | Watcher} */
this.watcher = undefined;
/** @type {undefined | null | Watcher} */
this.pausedWatcher = undefined;
/** @type {CollectedFiles | undefined} */
this._collectedChangedFiles = undefined;

View File

@@ -37,6 +37,9 @@ class WebpackError extends Error {
this.file = undefined;
}
/**
* @returns {string} inspect message
*/
[inspect]() {
return (
this.stack +
@@ -74,4 +77,5 @@ class WebpackError extends Error {
makeSerializable(WebpackError, "webpack/lib/WebpackError");
/** @type {typeof WebpackError} */
module.exports = WebpackError;

View File

@@ -74,8 +74,9 @@ const DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
const { cleverMerge } = require("./util/cleverMerge");
/** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */
/** @typedef {import("./webpack").WebpackPluginFunction} WebpackPluginFunction */
/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
/** @typedef {import("./config/normalization").WebpackOptionsInterception} WebpackOptionsInterception */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
@@ -90,9 +91,10 @@ class WebpackOptionsApply extends OptionsApply {
/**
* @param {WebpackOptions} options options object
* @param {Compiler} compiler compiler object
* @param {WebpackOptionsInterception=} interception intercepted options
* @returns {WebpackOptions} options object
*/
process(options, compiler) {
process(options, compiler, interception) {
compiler.outputPath = options.output.path;
compiler.recordsInputPath = options.recordsInputPath || null;
compiler.recordsOutputPath = options.recordsOutputPath || null;
@@ -113,11 +115,7 @@ class WebpackOptionsApply extends OptionsApply {
// Some older versions of Node.js don't support all built-in modules via import, only via `require`,
// but it seems like there shouldn't be a warning here since these versions are rarely used in real applications
new NodeTargetPlugin(
options.output.module &&
compiler.platform.node === null &&
compiler.platform.web === null
? "module-import"
: "node-commonjs"
options.output.module ? "module-import" : "node-commonjs"
).apply(compiler);
// Handle external CSS `@import` and `url()`
@@ -129,8 +127,8 @@ class WebpackOptionsApply extends OptionsApply {
"module",
({ request, dependencyType, contextInfo }, callback) => {
if (
/\.css(\?|$)/.test(contextInfo.issuer) &&
/^(\/\/|https?:\/\/|#)/.test(request)
/\.css(?:\?|$)/.test(contextInfo.issuer) &&
/^(?:\/\/|https?:\/\/|#)/.test(request)
) {
if (dependencyType === "url") {
return callback(null, `asset ${request}`);
@@ -156,7 +154,7 @@ class WebpackOptionsApply extends OptionsApply {
const ExternalsPlugin = require("./ExternalsPlugin");
new ExternalsPlugin(type, ({ request, dependencyType }, callback) => {
if (/^(\/\/|https?:\/\/|#|std:|jsr:|npm:)/.test(request)) {
if (/^(?:\/\/|https?:\/\/|#|std:|jsr:|npm:)/.test(request)) {
if (dependencyType === "url") {
return callback(null, `asset ${request}`);
} else if (
@@ -166,7 +164,7 @@ class WebpackOptionsApply extends OptionsApply {
options.experiments.css
) {
return callback(null, `css-import ${request}`);
} else if (/^(\/\/|https?:\/\/|std:|jsr:|npm:)/.test(request)) {
} else if (/^(?:\/\/|https?:\/\/|std:|jsr:|npm:)/.test(request)) {
return callback(null, `${type} ${request}`);
}
}
@@ -315,37 +313,59 @@ class WebpackOptionsApply extends OptionsApply {
).apply(compiler);
}
if (options.devtool) {
if (options.devtool.includes("source-map")) {
const hidden = options.devtool.includes("hidden");
const inline = options.devtool.includes("inline");
const evalWrapped = options.devtool.includes("eval");
const cheap = options.devtool.includes("cheap");
const moduleMaps = options.devtool.includes("module");
const noSources = options.devtool.includes("nosources");
const debugIds = options.devtool.includes("debugids");
const Plugin = evalWrapped
? require("./EvalSourceMapDevToolPlugin")
: require("./SourceMapDevToolPlugin");
new Plugin({
filename: inline ? null : options.output.sourceMapFilename,
moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
fallbackModuleFilenameTemplate:
options.output.devtoolFallbackModuleFilenameTemplate,
append: hidden ? false : undefined,
module: moduleMaps ? true : !cheap,
columns: !cheap,
noSources,
namespace: options.output.devtoolNamespace,
debugIds
}).apply(compiler);
} else if (options.devtool.includes("eval")) {
const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
let devtool =
interception === undefined ? options.devtool : interception.devtool;
devtool = Array.isArray(devtool)
? devtool
: typeof devtool === "string"
? [{ type: "all", use: devtool }]
: [];
new EvalDevToolModulePlugin({
moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
namespace: options.output.devtoolNamespace
}).apply(compiler);
for (const item of devtool) {
const { type, use } = item;
if (use) {
if (use.includes("source-map")) {
const hidden = use.includes("hidden");
const inline = use.includes("inline");
const evalWrapped = use.includes("eval");
const cheap = use.includes("cheap");
const moduleMaps = use.includes("module");
const noSources = use.includes("nosources");
const debugIds = use.includes("debugids");
const Plugin = evalWrapped
? require("./EvalSourceMapDevToolPlugin")
: require("./SourceMapDevToolPlugin");
const assetExt =
type === "javascript"
? /\.((c|m)?js)($|\?)/i
: type === "css"
? /\.(css)($|\?)/i
: /\.((c|m)?js|css)($|\?)/i;
new Plugin({
test: evalWrapped ? undefined : assetExt,
filename: inline ? null : options.output.sourceMapFilename,
moduleFilenameTemplate:
options.output.devtoolModuleFilenameTemplate,
fallbackModuleFilenameTemplate:
options.output.devtoolFallbackModuleFilenameTemplate,
append: hidden ? false : undefined,
module: moduleMaps ? true : !cheap,
columns: !cheap,
noSources,
namespace: options.output.devtoolNamespace,
debugIds
}).apply(compiler);
} else if (use.includes("eval")) {
const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
new EvalDevToolModulePlugin({
moduleFilenameTemplate:
options.output.devtoolModuleFilenameTemplate,
namespace: options.output.devtoolNamespace
}).apply(compiler);
}
}
}

View File

@@ -60,6 +60,7 @@ class AssetSourceGenerator extends Generator {
runtimeRequirements.add(RuntimeGlobals.requireScope);
runtimeRequirements.add(RuntimeGlobals.toBinary);
/** @type {string} */
let sourceContent;
if (concatenationScope) {
concatenationScope.registerNamespaceExport(

View File

@@ -43,6 +43,7 @@ const getMimeTypes = memoize(() => require("mime-types"));
/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").NameForCondition} NameForCondition */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
@@ -54,6 +55,8 @@ const getMimeTypes = memoize(() => require("mime-types"));
/** @typedef {import("../util/Hash")} Hash */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
/** @typedef {(source: string | Buffer, context: { filename: string, module: Module }) => string} DataUrlFunction */
/**
* @template T
* @template U
@@ -62,12 +65,13 @@ const getMimeTypes = memoize(() => require("mime-types"));
* @returns {T[] & U[]} array
*/
const mergeMaybeArrays = (a, b) => {
/** @type {Set<T | U | null | undefined | string | Set<T> | Set<U>>} */
const set = new Set();
if (Array.isArray(a)) for (const item of a) set.add(item);
else set.add(a);
if (Array.isArray(b)) for (const item of b) set.add(item);
else set.add(b);
return [...set];
return /** @type {T[] & U[]} */ ([.../** @type {Set<T | U>} */ (set)]);
};
/**
@@ -204,11 +208,17 @@ class AssetGenerator extends Generator {
emit
) {
super();
/** @type {AssetGeneratorOptions["dataUrl"] | undefined} */
this.dataUrlOptions = dataUrlOptions;
/** @type {AssetModuleFilename | undefined} */
this.filename = filename;
/** @type {RawPublicPath | undefined} */
this.publicPath = publicPath;
/** @type {AssetModuleOutputPath | undefined} */
this.outputPath = outputPath;
/** @type {boolean | undefined} */
this.emit = emit;
/** @type {ModuleGraph} */
this._moduleGraph = moduleGraph;
}
@@ -333,6 +343,7 @@ class AssetGenerator extends Generator {
runtimeTemplate
);
/** @type {undefined | string} */
let assetPath;
if (generatorOptions.publicPath !== undefined && type === JAVASCRIPT_TYPE) {
@@ -457,6 +468,7 @@ class AssetGenerator extends Generator {
generateDataUri(module) {
const source = /** @type {Source} */ (module.originalSource());
/** @type {string} */
let encodedSource;
if (typeof this.dataUrlOptions === "function") {
@@ -480,6 +492,7 @@ class AssetGenerator extends Generator {
}
const mimeType = this.getMimeType(module);
/** @type {string} */
let encodedContent;
if (
@@ -490,7 +503,9 @@ class AssetGenerator extends Generator {
/** @type {string} */ (module.resourceResolveData.encodedContent)
).equals(source.buffer())
) {
encodedContent = module.resourceResolveData.encodedContent;
encodedContent =
/** @type {string} */
(module.resourceResolveData.encodedContent);
} else {
encodedContent = encodeDataUri(
/** @type {"base64" | false} */ (encoding),
@@ -520,10 +535,10 @@ class AssetGenerator extends Generator {
concatenationScope
} = generateContext;
/** @type {string} */
let content;
const needContent = type === JAVASCRIPT_TYPE || type === CSS_URL_TYPE;
const data = getData ? getData() : undefined;
if (

View File

@@ -12,17 +12,22 @@ const {
ASSET_MODULE_TYPE_RESOURCE,
ASSET_MODULE_TYPE_SOURCE
} = require("../ModuleTypeConstants");
const { compareModulesByIdOrIdentifier } = require("../util/comparators");
const { compareModulesByFullName } = require("../util/comparators");
const createSchemaValidation = require("../util/create-schema-validation");
const memoize = require("../util/memoize");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("schema-utils").Schema} Schema */
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorDataUrl} AssetGeneratorDataUrl */
/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */
/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */
/** @typedef {import("../../declarations/WebpackOptions").FilenameTemplate} FilenameTemplate */
/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../NormalModule").NormalModuleCreateData} NormalModuleCreateData */
/**
* @param {string} name name of definitions
@@ -76,6 +81,7 @@ const getAssetSourceGenerator = memoize(() =>
require("./AssetSourceGenerator")
);
const getAssetBytesGenerator = memoize(() => require("./AssetBytesGenerator"));
const getNormalModule = memoize(() => require("../NormalModule"));
const type = ASSET_MODULE_TYPE;
const PLUGIN_NAME = "AssetModulesPlugin";
@@ -90,6 +96,27 @@ class AssetModulesPlugin {
compiler.hooks.compilation.tap(
PLUGIN_NAME,
(compilation, { normalModuleFactory }) => {
const NormalModule = getNormalModule();
for (const type of [
ASSET_MODULE_TYPE,
ASSET_MODULE_TYPE_BYTES,
ASSET_MODULE_TYPE_INLINE,
ASSET_MODULE_TYPE_RESOURCE,
ASSET_MODULE_TYPE_SOURCE
]) {
normalModuleFactory.hooks.createModuleClass
.for(type)
.tap(PLUGIN_NAME, (createData, _resolveData) => {
// TODO create the module via new AssetModule with its own properties
const module = new NormalModule(
/** @type {NormalModuleCreateData} */
(createData)
);
module.factoryMeta = { sideEffectFree: true };
return module;
});
}
normalModuleFactory.hooks.createParser
.for(ASSET_MODULE_TYPE)
.tap(PLUGIN_NAME, (parserOptions) => {
@@ -146,6 +173,7 @@ class AssetModulesPlugin {
.tap(PLUGIN_NAME, (generatorOptions) => {
validateGeneratorOptions[type](generatorOptions);
/** @type {undefined | AssetGeneratorDataUrl} */
let dataUrl;
if (type !== ASSET_MODULE_TYPE_RESOURCE) {
dataUrl = generatorOptions.dataUrl;
@@ -158,8 +186,11 @@ class AssetModulesPlugin {
}
}
/** @type {undefined | FilenameTemplate} */
let filename;
/** @type {undefined | RawPublicPath} */
let publicPath;
/** @type {undefined | AssetModuleOutputPath} */
let outputPath;
if (type !== ASSET_MODULE_TYPE_INLINE) {
filename = generatorOptions.filename;
@@ -202,7 +233,7 @@ class AssetModulesPlugin {
const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
chunk,
ASSET_MODULE_TYPE,
compareModulesByIdOrIdentifier(chunkGraph)
compareModulesByFullName(compilation.compiler)
);
if (modules) {
for (const module of modules) {

View File

@@ -9,17 +9,21 @@ const Parser = require("../Parser");
/** @typedef {import("../../declarations/WebpackOptions").AssetParserDataUrlOptions} AssetParserDataUrlOptions */
/** @typedef {import("../../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../Parser").ParserState} ParserState */
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
/** @typedef {((source: string | Buffer, context: { filename: string, module: Module }) => boolean)} AssetParserDataUrlFunction */
class AssetParser extends Parser {
/**
* @param {AssetParserOptions["dataUrlCondition"] | boolean} dataUrlCondition condition for inlining as DataUrl
*/
constructor(dataUrlCondition) {
super();
/** @type {AssetParserOptions["dataUrlCondition"] | boolean} */
this.dataUrlCondition = dataUrlCondition;
}

View File

@@ -59,6 +59,7 @@ class AssetSourceGenerator extends Generator {
const encodedSource =
typeof content === "string" ? content : content.toString("utf8");
/** @type {string} */
let sourceContent;
if (concatenationScope) {
concatenationScope.registerNamespaceExport(

View File

@@ -22,8 +22,10 @@ const makeSerializable = require("../util/makeSerializable");
/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
/** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("../Module").Sources} Sources */
/** @typedef {import("../Module").SourceTypes} SourceTypes */
/** @typedef {import("../RequestShortener")} RequestShortener */
/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
@@ -114,11 +116,13 @@ class RawDataUrlModule extends Module {
if (this.url === undefined) {
this.url = /** @type {Buffer} */ (this.urlBuffer).toString();
}
/** @type {Sources} */
const sources = new Map();
sources.set(
JAVASCRIPT_TYPE,
new RawSource(`module.exports = ${JSON.stringify(this.url)};`)
);
/** @type {CodeGenerationResultData} */
const data = new Map();
data.set("url", {
javascript: this.url

View File

@@ -12,12 +12,14 @@ const Template = require("../Template");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {Map<string, string>} Dependencies */
/**
* @extends {InitFragment<GenerateContext>}
*/
class AwaitDependenciesInitFragment extends InitFragment {
/**
* @param {Map<string, string>} dependencies maps an import var to an async module that needs to be awaited
* @param {Dependencies} dependencies maps an import var to an async module that needs to be awaited
*/
constructor(dependencies) {
super(
@@ -26,6 +28,7 @@ class AwaitDependenciesInitFragment extends InitFragment {
0,
"await-dependencies"
);
/** @type {Dependencies} */
this.dependencies = dependencies;
}

View File

@@ -50,6 +50,8 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
* @property {number} postOrderIndex next post order index
* @property {boolean} chunkLoading has a chunk loading mechanism
* @property {boolean} asyncChunks create async chunks
* @property {Module | null} depModule the module that is the dependency of the block
* @property {boolean} circular Whether to deduplicate to avoid circular references
*/
/**
@@ -165,6 +167,7 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
for (const modules of arrays) {
if (modules.length === 0) continue;
/** @type {undefined | Map<Module | ModuleGraphConnection | ConnectionState, number>} */
let indexMap;
let length = 0;
outer: for (let j = 0; j < modules.length; j += 3) {
@@ -360,6 +363,9 @@ const visitModules = (
/** @type {NamedChunkGroup} */
const namedAsyncEntrypoints = new Map();
/** @type {Map<Module, ChunkGroupInfo>} */
const depModuleAsyncEntrypoints = new Map();
/** @type {Set<ChunkGroupInfo>} */
const outdatedOrderIndexChunkGroups = new Set();
@@ -373,7 +379,8 @@ const visitModules = (
/** @type {QueueItem[]} */
let queue = [];
/** @type {Map<ChunkGroupInfo, Set<[ChunkGroupInfo, QueueItem | null]>>} */
/** @typedef {Set<[ChunkGroupInfo, QueueItem | null]>} ConnectList */
/** @type {Map<ChunkGroupInfo, ConnectList>} */
const queueConnect = new Map();
/** @type {Set<ChunkGroupInfo>} */
const chunkGroupsForCombining = new Set();
@@ -388,6 +395,8 @@ const visitModules = (
);
/** @type {ChunkGroupInfo} */
const chunkGroupInfo = {
depModule: null,
circular: false,
initialized: false,
chunkGroup,
runtime,
@@ -496,11 +505,16 @@ const visitModules = (
let c;
/** @type {Entrypoint | undefined} */
let entrypoint;
/** @type {Module | null} */
const depModule = moduleGraph.getModule(b.dependencies[0]);
const entryOptions = b.groupOptions && b.groupOptions.entryOptions;
if (cgi === undefined) {
const chunkName = (b.groupOptions && b.groupOptions.name) || b.chunkName;
if (entryOptions) {
cgi = namedAsyncEntrypoints.get(/** @type {string} */ (chunkName));
if (!cgi && !b.circular && depModule) {
cgi = depModuleAsyncEntrypoints.get(depModule);
}
if (!cgi) {
entrypoint = compilation.addAsyncEntrypoint(
entryOptions,
@@ -511,6 +525,8 @@ const visitModules = (
maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT);
entrypoint.index = nextChunkGroupIndex++;
cgi = {
depModule,
circular: b.circular,
chunkGroup: entrypoint,
initialized: false,
runtime:
@@ -548,6 +564,12 @@ const visitModules = (
(cgi)
);
}
if (!b.circular && depModule) {
depModuleAsyncEntrypoints.set(
depModule,
/** @type {ChunkGroupInfo} */ (cgi)
);
}
} else {
entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
// TODO merge entryOptions
@@ -590,6 +612,8 @@ const visitModules = (
maskByChunk.set(c.chunks[0], ZERO_BIGINT);
c.index = nextChunkGroupIndex++;
cgi = {
depModule,
circular: b.circular,
initialized: false,
chunkGroup: c,
runtime: chunkGroupInfo.runtime,
@@ -651,6 +675,7 @@ const visitModules = (
// 3. We enqueue the chunk group info creation/updating
let connectList = queueConnect.get(chunkGroupInfo);
if (connectList === undefined) {
/** @type {ConnectList} */
connectList = new Set();
queueConnect.set(chunkGroupInfo, connectList);
}
@@ -665,7 +690,10 @@ const visitModules = (
chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
}
]);
} else if (entrypoint !== undefined) {
} else if (
entrypoint !== undefined &&
(chunkGroupInfo.circular || chunkGroupInfo.depModule !== depModule)
) {
chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint);
}
};
@@ -1091,6 +1119,7 @@ const visitModules = (
for (const cgi of info.children) {
let connectList = queueConnect.get(info);
if (connectList === undefined) {
/** @type {ConnectList} */
connectList = new Set();
queueConnect.set(info, connectList);
}

View File

@@ -43,6 +43,7 @@ class MemoryWithGcCachePlugin {
compiler.hooks.afterDone.tap(PLUGIN_NAME, () => {
generation++;
let clearedEntries = 0;
/** @type {undefined | string} */
let lastClearedIdentifier;
// Avoid coverage problems due indirect changes
/* istanbul ignore next */

View File

@@ -28,7 +28,7 @@ const {
/** @typedef {import("../logging/Logger").Logger} Logger */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {typeof import("../util/Hash")} Hash */
/** @typedef {import("../util/Hash").HashFunction} HashFunction */
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {Set<string>} Items */
@@ -134,13 +134,17 @@ class Pack {
this.itemInfo = new Map();
/** @type {(string | undefined)[]} */
this.requests = [];
/** @type {undefined | NodeJS.Timeout} */
this.requestsTimeout = undefined;
/** @type {ItemInfo} */
this.freshContent = new Map();
/** @type {(undefined | PackContent)[]} */
this.content = [];
/** @type {boolean} */
this.invalid = false;
/** @type {Logger} */
this.logger = logger;
/** @type {number} */
this.maxAge = maxAge;
}
@@ -243,6 +247,7 @@ class Pack {
* @returns {number} new location of data entries
*/
_findLocation() {
/** @type {number} */
let i;
for (i = 0; i < this.content.length && this.content[i] !== undefined; i++);
return i;
@@ -256,6 +261,7 @@ class Pack {
*/
_gcAndUpdateLocation(items, usedItems, newLoc) {
let count = 0;
/** @type {undefined | string} */
let lastGC;
const now = Date.now();
for (const identifier of items) {
@@ -381,6 +387,7 @@ class Pack {
}
// 2. Check if minimum number is reached
/** @type {number[]} */
let mergedIndices;
if (
smallUsedContents.length >= CONTENT_COUNT_TO_MERGE ||
@@ -505,6 +512,7 @@ class Pack {
// 5. Determine items for the unused content file
const unusedItems = new Set(content.items);
/** @type {Items} */
const usedOfUnusedItems = new Set();
for (const identifier of usedItems) {
unusedItems.delete(identifier);
@@ -521,6 +529,7 @@ class Pack {
await content.unpack(
"it should be splitted into used and unused items"
);
/** @type {Content} */
const map = new Map();
for (const identifier of unusedItems) {
map.set(
@@ -579,6 +588,7 @@ class Pack {
await content.unpack(
"it contains old items that should be garbage collected"
);
/** @type {Content} */
const map = new Map();
for (const identifier of items) {
map.set(
@@ -691,7 +701,7 @@ class PackContentItems {
}
/**
* @param {ObjectSerializerContext & { logger: Logger, profile: boolean | undefined }} context context
* @param {ObjectSerializerContext & { logger: Logger, profile: boolean | undefined }} context context
*/
serialize({ write, snapshot, rollback, logger, profile }) {
if (profile) {
@@ -774,6 +784,7 @@ class PackContentItems {
if (read()) {
this.map = read();
} else if (profile) {
/** @type {Map<EXPECTED_ANY, EXPECTED_ANY>} */
const map = new Map();
let key = read();
while (key !== null) {
@@ -799,6 +810,7 @@ class PackContentItems {
}
this.map = map;
} else {
/** @type {Map<EXPECTED_ANY, EXPECTED_ANY>} */
const map = new Map();
let key = read();
while (key !== null) {
@@ -816,7 +828,7 @@ makeSerializable(
"PackContentItems"
);
/** @typedef {(() => Promise<PackContentItems> | PackContentItems) & Partial<{ options: { size?: number }}>} LazyFunction */
/** @typedef {(() => Promise<PackContentItems> | PackContentItems) & Partial<{ options: { size?: number } }>} LazyFunction */
class PackContent {
/*
@@ -846,14 +858,19 @@ class PackContent {
* @param {string=} lazyName name of dataOrFn for logging
*/
constructor(items, usedItems, dataOrFn, logger, lazyName) {
/** @type {Items} */
this.items = items;
/** @type {LazyFunction | undefined} */
this.lazy = typeof dataOrFn === "function" ? dataOrFn : undefined;
/** @type {Content | undefined} */
this.content = typeof dataOrFn === "function" ? undefined : dataOrFn.map;
/** @type {boolean} */
this.outdated = false;
/** @type {Items} */
this.used = usedItems;
/** @type {Logger | undefined} */
this.logger = logger;
/** @type {string | undefined} */
this.lazyName = lazyName;
}
@@ -1091,10 +1108,10 @@ class PackFileCacheStrategy {
* @param {Logger} options.logger a logger
* @param {SnapshotOptions} options.snapshot options regarding snapshotting
* @param {number} options.maxAge max age of cache items
* @param {boolean | undefined} options.profile track and log detailed timing information for individual cache items
* @param {boolean | undefined} options.allowCollectingMemory allow to collect unused memory created during deserialization
* @param {false | "gzip" | "brotli" | undefined} options.compression compression used
* @param {boolean | undefined} options.readonly disable storing cache into filesystem
* @param {boolean=} options.profile track and log detailed timing information for individual cache items
* @param {boolean=} options.allowCollectingMemory allow to collect unused memory created during deserialization
* @param {false | "gzip" | "brotli"=} options.compression compression used
* @param {boolean=} options.readonly disable storing cache into filesystem
*/
constructor({
compiler,
@@ -1113,31 +1130,44 @@ class PackFileCacheStrategy {
/** @type {import("../serialization/Serializer")<PackContainer, null, EXPECTED_OBJECT>} */
this.fileSerializer = createFileSerializer(
fs,
/** @type {string | Hash} */
/** @type {HashFunction} */
(compiler.options.output.hashFunction)
);
/** @type {FileSystemInfo} */
this.fileSystemInfo = new FileSystemInfo(fs, {
managedPaths: snapshot.managedPaths,
immutablePaths: snapshot.immutablePaths,
logger: logger.getChildLogger("webpack.FileSystemInfo"),
hashFunction: compiler.options.output.hashFunction
});
/** @type {Compiler} */
this.compiler = compiler;
/** @type {string} */
this.context = context;
/** @type {string} */
this.cacheLocation = cacheLocation;
/** @type {string} */
this.version = version;
/** @type {Logger} */
this.logger = logger;
/** @type {number} */
this.maxAge = maxAge;
/** @type {boolean | undefined} */
this.profile = profile;
/** @type {boolean | undefined} */
this.readonly = readonly;
/** @type {boolean | undefined} */
this.allowCollectingMemory = allowCollectingMemory;
/** @type {false | "gzip" | "brotli" | undefined} */
this.compression = compression;
/** @type {string} */
this._extension =
compression === "brotli"
? ".pack.br"
: compression === "gzip"
? ".pack.gz"
: ".pack";
/** @type {SnapshotOptions} */
this.snapshot = snapshot;
/** @type {BuildDependencies} */
this.buildDependencies = new Set();
@@ -1151,6 +1181,7 @@ class PackFileCacheStrategy {
this.buildSnapshot = undefined;
/** @type {Promise<Pack> | undefined} */
this.packPromise = this._openPack();
/** @type {Promise<void>} */
this.storePromise = Promise.resolve();
}
@@ -1382,7 +1413,9 @@ class PackFileCacheStrategy {
if (!pack.invalid) return;
this.packPromise = undefined;
this.logger.log("Storing pack...");
/** @type {undefined | Promise<void>} */
let promise;
/** @type {Set<string>} */
const newBuildDependencies = new Set();
for (const dep of this.newBuildDependencies) {
if (!this.buildDependencies.has(dep)) {

Some files were not shown because too many files have changed in this diff Show More