fix: types

This commit is contained in:
alexander.akait 2024-08-07 18:22:25 +03:00
parent 13560eac2e
commit ff9e19809a
30 changed files with 537 additions and 228 deletions

View File

@ -20,11 +20,15 @@ function createMessage(method) {
* @constructor * @constructor
*/ */
function Message() { function Message() {
/** @type {string} */ /** @type {string | undefined} */
this.stack = undefined; this.stack = undefined;
Error.captureStackTrace(this); Error.captureStackTrace(this);
/** @type {RegExpMatchArray} */ /** @type {RegExpMatchArray | null} */
const match = this.stack.split("\n")[3].match(CURRENT_METHOD_REGEXP); const match =
/** @type {string} */
(/** @type {unknown} */ (this.stack))
.split("\n")[3]
.match(CURRENT_METHOD_REGEXP);
this.message = match && match[1] ? createMessage(match[1]) : createMessage(); this.message = match && match[1] ? createMessage(match[1]) : createMessage();
} }

View File

@ -22,7 +22,7 @@ const {
/** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {{id: number}} HasId */ /** @typedef {{id: number}} HasId */
/** @typedef {{module: Module, loc: DependencyLocation, request: string}} OriginRecord */ /** @typedef {{module: Module | null, loc: DependencyLocation, request: string}} OriginRecord */
/** /**
* @typedef {object} RawChunkGroupOptions * @typedef {object} RawChunkGroupOptions
@ -404,7 +404,7 @@ class ChunkGroup {
} }
/** /**
* @param {Module} module origin module * @param {Module | null} module origin module
* @param {DependencyLocation} loc location of the reference in the origin module * @param {DependencyLocation} loc location of the reference in the origin module
* @param {string} request request name of the reference * @param {string} request request name of the reference
* @returns {void} * @returns {void}

View File

@ -153,7 +153,7 @@ const { isSourceEqual } = require("./util/source");
/** /**
* @callback ExecuteModuleCallback * @callback ExecuteModuleCallback
* @param {(WebpackError | null)=} err * @param {WebpackError | null} err
* @param {ExecuteModuleResult=} result * @param {ExecuteModuleResult=} result
* @returns {void} * @returns {void}
*/ */
@ -1966,6 +1966,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
callback callback
) { ) {
// Check for cycles when build is trigger inside another build // Check for cycles when build is trigger inside another build
/** @type {Set<Module> | undefined} */
let creatingModuleDuringBuildSet; let creatingModuleDuringBuildSet;
if (checkCycle && this.buildQueue.isProcessing(originModule)) { if (checkCycle && this.buildQueue.isProcessing(originModule)) {
// Track build dependency // Track build dependency
@ -4963,12 +4964,6 @@ This prevents using hashes of each other and should be avoided.`);
processAsyncTree( processAsyncTree(
modules, modules,
10, 10,
/**
* @param {Module} module the module
* @param {function(Module): void} push push more jobs
* @param {Callback} callback callback
* @returns {void}
*/
(module, push, callback) => { (module, push, callback) => {
this.buildQueue.waitFor(module, err => { this.buildQueue.waitFor(module, err => {
if (err) return callback(err); if (err) return callback(err);

View File

@ -201,7 +201,7 @@ class Compiler {
/** @type {AsyncSeriesHook<[]>} */ /** @type {AsyncSeriesHook<[]>} */
shutdown: new AsyncSeriesHook([]), shutdown: new AsyncSeriesHook([]),
/** @type {SyncBailHook<[string, string, any[]], true>} */ /** @type {SyncBailHook<[string, string, any[] | undefined], true>} */
infrastructureLog: new SyncBailHook(["origin", "type", "args"]), infrastructureLog: new SyncBailHook(["origin", "type", "args"]),
// TODO the following hooks are weirdly located here // TODO the following hooks are weirdly located here
@ -1227,9 +1227,16 @@ ${other}`);
"done", "done",
"thisCompilation" "thisCompilation"
].includes(name) && ].includes(name) &&
childCompiler.hooks[name] childCompiler.hooks[/** @type {keyof Compiler["hooks"]} */ (name)]
) { ) {
childCompiler.hooks[name].taps = this.hooks[name].taps.slice(); childCompiler.hooks[
/** @type {keyof Compiler["hooks"]} */
(name)
].taps =
this.hooks[
/** @type {keyof Compiler["hooks"]} */
(name)
].taps.slice();
} }
} }

View File

@ -30,6 +30,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Chunk").ChunkId} ChunkId */
/** @typedef {import("./ChunkGraph")} ChunkGraph */ /** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ /** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
@ -86,7 +87,7 @@ const makeSerializable = require("./util/makeSerializable");
/** /**
* @callback ResolveDependenciesCallback * @callback ResolveDependenciesCallback
* @param {(Error | null)=} err * @param {Error | null} err
* @param {ContextElementDependency[]=} dependencies * @param {ContextElementDependency[]=} dependencies
*/ */
@ -99,7 +100,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {1 | 3 | 7 | 9} FakeMapType */ /** @typedef {1 | 3 | 7 | 9} FakeMapType */
/** @typedef {Map<string, string | number> | FakeMapType} FakeMap */ /** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
const SNAPSHOT_OPTIONS = { timestamp: true }; const SNAPSHOT_OPTIONS = { timestamp: true };
@ -602,7 +603,7 @@ class ContextModule extends Module {
/** /**
* @param {Dependency[]} dependencies all dependencies * @param {Dependency[]} dependencies all dependencies
* @param {ChunkGraph} chunkGraph chunk graph * @param {ChunkGraph} chunkGraph chunk graph
* @returns {FakeMap} fake map * @returns {FakeMap | FakeMapType} fake map
*/ */
getFakeMap(dependencies, chunkGraph) { getFakeMap(dependencies, chunkGraph) {
if (!this.options.namespaceObject) { if (!this.options.namespaceObject) {
@ -621,13 +622,14 @@ class ContextModule extends Module {
) )
.filter(Boolean) .filter(Boolean)
.sort(comparator); .sort(comparator);
/** @type {FakeMap} */
const fakeMap = Object.create(null); const fakeMap = Object.create(null);
for (const module of sortedModules) { for (const module of sortedModules) {
const exportsType = module.getExportsType( const exportsType = module.getExportsType(
moduleGraph, moduleGraph,
this.options.namespaceObject === "strict" this.options.namespaceObject === "strict"
); );
const id = chunkGraph.getModuleId(module); const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
switch (exportsType) { switch (exportsType) {
case "namespace": case "namespace":
fakeMap[id] = 9; fakeMap[id] = 9;
@ -668,7 +670,7 @@ class ContextModule extends Module {
} }
/** /**
* @param {FakeMap} fakeMap fake map * @param {FakeMap | FakeMapType} fakeMap fake map
* @returns {string} fake map init statement * @returns {string} fake map init statement
*/ */
getFakeMapInitStatement(fakeMap) { getFakeMapInitStatement(fakeMap) {
@ -692,7 +694,7 @@ class ContextModule extends Module {
} }
/** /**
* @param {FakeMap} fakeMap fake map * @param {FakeMap | FakeMapType} fakeMap fake map
* @param {boolean=} asyncModule us async module * @param {boolean=} asyncModule us async module
* @param {string=} fakeMapDataExpression fake map data expression * @param {string=} fakeMapDataExpression fake map data expression
* @returns {string} module object source * @returns {string} module object source
@ -944,6 +946,10 @@ module.exports = webpackAsyncContext;`;
chunkGraph chunkGraph
); );
const hasFakeMap = typeof fakeMap === "object"; const hasFakeMap = typeof fakeMap === "object";
/** @typedef {{userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock}} Item */
/**
* @type {Item[]}
*/
const items = blocks const items = blocks
.map(block => { .map(block => {
const dependency = const dependency =
@ -974,18 +980,23 @@ module.exports = webpackAsyncContext;`;
if (a.userRequest === b.userRequest) return 0; if (a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1; return a.userRequest < b.userRequest ? -1 : 1;
}); });
/** @type {Record<string, ModuleId | (ModuleId[] | ChunkId[])>} */
const map = Object.create(null); const map = Object.create(null);
for (const item of sortedItems) { for (const item of sortedItems) {
const moduleId = chunkGraph.getModuleId(item.module); const moduleId =
/** @type {ModuleId} */
(chunkGraph.getModuleId(item.module));
if (shortMode) { if (shortMode) {
map[item.userRequest] = moduleId; map[item.userRequest] = moduleId;
} else { } else {
/** @type {(ModuleId | ChunkId)[]} */
const arrayStart = [moduleId]; const arrayStart = [moduleId];
if (hasFakeMap) { if (hasFakeMap) {
arrayStart.push(fakeMap[moduleId]); arrayStart.push(fakeMap[moduleId]);
} }
map[item.userRequest] = arrayStart.concat( map[item.userRequest] = arrayStart.concat(
item.chunks.map(chunk => chunk.id) /** @type {Chunk[]} */
(item.chunks).map(chunk => /** @type {ChunkId} */ (chunk.id))
); );
} }
} }
@ -1086,7 +1097,7 @@ module.exports = webpackEmptyAsyncContext;`;
* @returns {string} the source code * @returns {string} the source code
*/ */
getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) { getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) {
const id = chunkGraph.getModuleId(this); const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this));
if (asyncMode === "lazy") { if (asyncMode === "lazy") {
if (this.blocks && this.blocks.length > 0) { if (this.blocks && this.blocks.length > 0) {
return this.getLazySource(this.blocks, id, { return this.getLazySource(this.blocks, id, {

View File

@ -22,8 +22,14 @@ const { join } = require("./util/fs");
/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
/** @typedef {import("./ResolverFactory")} ResolverFactory */ /** @typedef {import("./ResolverFactory")} ResolverFactory */
/** @typedef {import("./dependencies/ContextDependency")} ContextDependency */ /** @typedef {import("./dependencies/ContextDependency")} ContextDependency */
/** @template T @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T> */ /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
/**
* @template T
* @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T>
*/
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {{ context: string, request: string }} ContextAlternativeRequest */
const EMPTY_RESOLVE_OPTIONS = {}; const EMPTY_RESOLVE_OPTIONS = {};
@ -33,7 +39,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
*/ */
constructor(resolverFactory) { constructor(resolverFactory) {
super(); super();
/** @type {AsyncSeriesWaterfallHook<[TODO[], ContextModuleOptions]>} */ /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[], ContextModuleOptions]>} */
const alternativeRequests = new AsyncSeriesWaterfallHook([ const alternativeRequests = new AsyncSeriesWaterfallHook([
"modules", "modules",
"options" "options"
@ -45,27 +51,27 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
afterResolve: new AsyncSeriesWaterfallHook(["data"]), afterResolve: new AsyncSeriesWaterfallHook(["data"]),
/** @type {SyncWaterfallHook<[string[]]>} */ /** @type {SyncWaterfallHook<[string[]]>} */
contextModuleFiles: new SyncWaterfallHook(["files"]), contextModuleFiles: new SyncWaterfallHook(["files"]),
/** @type {FakeHook<Pick<AsyncSeriesWaterfallHook<[TODO[]]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */ /** @type {FakeHook<Pick<AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
alternatives: createFakeHook( alternatives: createFakeHook(
{ {
name: "alternatives", name: "alternatives",
/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["intercept"]} */ /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["intercept"]} */
intercept: interceptor => { intercept: interceptor => {
throw new Error( throw new Error(
"Intercepting fake hook ContextModuleFactory.hooks.alternatives is not possible, use ContextModuleFactory.hooks.alternativeRequests instead" "Intercepting fake hook ContextModuleFactory.hooks.alternatives is not possible, use ContextModuleFactory.hooks.alternativeRequests instead"
); );
}, },
/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tap"]} */ /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tap"]} */
tap: (options, fn) => { tap: (options, fn) => {
alternativeRequests.tap(options, fn); alternativeRequests.tap(options, fn);
}, },
/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapAsync"]} */ /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tapAsync"]} */
tapAsync: (options, fn) => { tapAsync: (options, fn) => {
alternativeRequests.tapAsync(options, (items, _options, callback) => alternativeRequests.tapAsync(options, (items, _options, callback) =>
fn(items, callback) fn(items, callback)
); );
}, },
/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapPromise"]} */ /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tapPromise"]} */
tapPromise: (options, fn) => { tapPromise: (options, fn) => {
alternativeRequests.tapPromise(options, fn); alternativeRequests.tapPromise(options, fn);
} }
@ -164,7 +170,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
asyncLib.parallel( asyncLib.parallel(
[ [
callback => { callback => {
const results = []; const results = /** @type ResolveRequest[] */ ([]);
const yield_ = obj => results.push(obj); const yield_ = obj => results.push(obj);
contextResolver.resolve( contextResolver.resolve(
@ -198,7 +204,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
}, },
(err, result) => { (err, result) => {
if (err) return callback(err); if (err) return callback(err);
callback(null, result); callback(null, /** @type {string} */ (result));
} }
); );
}, },
@ -214,7 +220,8 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
contextDependencies contextDependencies
}); });
} }
let [contextResult, loaderResult] = result; let [contextResult, loaderResult] =
/** @type {[ResolveRequest[], string[]]} */ (result);
if (contextResult.length > 1) { if (contextResult.length > 1) {
const first = contextResult[0]; const first = contextResult[0];
contextResult = contextResult.filter(r => r.path); contextResult = contextResult.filter(r => r.path);
@ -290,10 +297,19 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
} = options; } = options;
if (!regExp || !resource) return callback(null, []); if (!regExp || !resource) return callback(null, []);
/**
* @param {string} ctx context
* @param {string} directory directory
* @param {Set<string>} visited visited
* @param {ResolveDependenciesCallback} callback callback
*/
const addDirectoryChecked = (ctx, directory, visited, callback) => { const addDirectoryChecked = (ctx, directory, visited, callback) => {
fs.realpath(directory, (err, realPath) => { /** @type {NonNullable<InputFileSystem["realpath"]>} */
(fs.realpath)(directory, (err, _realPath) => {
if (err) return callback(err); if (err) return callback(err);
const realPath = /** @type {string} */ (_realPath);
if (visited.has(realPath)) return callback(null, []); if (visited.has(realPath)) return callback(null, []);
/** @type {Set<string> | undefined} */
let recursionStack; let recursionStack;
addDirectory( addDirectory(
ctx, ctx,
@ -310,6 +326,12 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
}); });
}; };
/**
* @param {string} ctx context
* @param {string} directory directory
* @param {function(string, string, function(): void): void} addSubDirectory addSubDirectoryFn
* @param {ResolveDependenciesCallback} callback callback
*/
const addDirectory = (ctx, directory, addSubDirectory, callback) => { const addDirectory = (ctx, directory, addSubDirectory, callback) => {
fs.readdir(directory, (err, files) => { fs.readdir(directory, (err, files) => {
if (err) return callback(err); if (err) return callback(err);
@ -324,7 +346,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
const subResource = join(fs, directory, segment); const subResource = join(fs, directory, segment);
if (!exclude || !subResource.match(exclude)) { if (!exclude || !subResource.match(exclude)) {
fs.stat(subResource, (err, stat) => { fs.stat(subResource, (err, _stat) => {
if (err) { if (err) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
// ENOENT is ok here because the file may have been deleted between // ENOENT is ok here because the file may have been deleted between
@ -334,6 +356,8 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
return callback(err); return callback(err);
} }
const stat = /** @type {IStats} */ (_stat);
if (stat.isDirectory()) { if (stat.isDirectory()) {
if (!recursive) return callback(); if (!recursive) return callback();
addSubDirectory(ctx, subResource, callback); addSubDirectory(ctx, subResource, callback);
@ -341,6 +365,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
stat.isFile() && stat.isFile() &&
(!include || subResource.match(include)) (!include || subResource.match(include))
) { ) {
/** @type {{ context: string, request: string }} */
const obj = { const obj = {
context: ctx, context: ctx,
request: `.${subResource.slice(ctx.length).replace(/\\/g, "/")}` request: `.${subResource.slice(ctx.length).replace(/\\/g, "/")}`
@ -351,22 +376,29 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
options, options,
(err, alternatives) => { (err, alternatives) => {
if (err) return callback(err); if (err) return callback(err);
alternatives = alternatives callback(
.filter(obj => regExp.test(obj.request)) null,
/** @type {ContextAlternativeRequest[]} */
(alternatives)
.filter(obj =>
regExp.test(/** @type {string} */ (obj.request))
)
.map(obj => { .map(obj => {
const dep = new ContextElementDependency( const dep = new ContextElementDependency(
`${obj.request}${resourceQuery}${resourceFragment}`, `${obj.request}${resourceQuery}${resourceFragment}`,
obj.request, obj.request,
typePrefix, typePrefix,
category, /** @type {string} */
(category),
referencedExports, referencedExports,
obj.context, /** @type {TODO} */
(obj.context),
attributes attributes
); );
dep.optional = true; dep.optional = true;
return dep; return dep;
}); })
callback(null, alternatives); );
} }
); );
} else { } else {
@ -394,9 +426,19 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
}); });
}; };
/**
* @param {string} ctx context
* @param {string} dir dir
* @param {ResolveDependenciesCallback} callback callback
* @returns {void}
*/
const addSubDirectory = (ctx, dir, callback) => const addSubDirectory = (ctx, dir, callback) =>
addDirectory(ctx, dir, addSubDirectory, callback); addDirectory(ctx, dir, addSubDirectory, callback);
/**
* @param {string} resource resource
* @param {ResolveDependenciesCallback} callback callback
*/
const visitResource = (resource, callback) => { const visitResource = (resource, callback) => {
if (typeof fs.realpath === "function") { if (typeof fs.realpath === "function") {
addDirectoryChecked(resource, resource, new Set(), callback); addDirectoryChecked(resource, resource, new Set(), callback);
@ -408,12 +450,15 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
if (typeof resource === "string") { if (typeof resource === "string") {
visitResource(resource, callback); visitResource(resource, callback);
} else { } else {
asyncLib.map(resource, visitResource, (err, result) => { asyncLib.map(resource, visitResource, (err, _result) => {
if (err) return callback(err); if (err) return callback(err);
const result = /** @type {ContextElementDependency[][]} */ (_result);
// result dependencies should have unique userRequest // result dependencies should have unique userRequest
// ordered by resolve result // ordered by resolve result
/** @type {Set<string>} */
const temp = new Set(); const temp = new Set();
/** @type {ContextElementDependency[]} */
const res = []; const res = [];
for (let i = 0; i < result.length; i++) { for (let i = 0; i < result.length; i++) {
const inner = result[i]; const inner = result[i];

View File

@ -134,7 +134,9 @@ class HotModuleReplacementPlugin {
(module.buildInfo).moduleConcatenationBailout = (module.buildInfo).moduleConcatenationBailout =
"Hot Module Replacement"; "Hot Module Replacement";
if (expr.arguments.length >= 1) { if (expr.arguments.length >= 1) {
const arg = parser.evaluateExpression(expr.arguments[0]); const arg = parser.evaluateExpression(
/** @type {Expression} */ (expr.arguments[0])
);
/** @type {BasicEvaluatedExpression[]} */ /** @type {BasicEvaluatedExpression[]} */
let params = []; let params = [];
if (arg.isString()) { if (arg.isString()) {

View File

@ -82,6 +82,10 @@ const memoize = require("./util/memoize");
/** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/Hash")} Hash */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
/**
* @template T
* @typedef {import("./util/deprecation").FakeHook<T>} FakeHook
*/
/** @typedef {{[k: string]: any}} ParserOptions */ /** @typedef {{[k: string]: any}} ParserOptions */
/** @typedef {{[k: string]: any}} GeneratorOptions */ /** @typedef {{[k: string]: any}} GeneratorOptions */
@ -217,8 +221,8 @@ makeSerializable(
* @property {SyncHook<[LoaderItem[], NormalModule, LoaderContext<any>]>} beforeLoaders * @property {SyncHook<[LoaderItem[], NormalModule, LoaderContext<any>]>} beforeLoaders
* @property {SyncHook<[NormalModule]>} beforeParse * @property {SyncHook<[NormalModule]>} beforeParse
* @property {SyncHook<[NormalModule]>} beforeSnapshot * @property {SyncHook<[NormalModule]>} beforeSnapshot
* @property {HookMap<AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>>} readResourceForScheme * @property {HookMap<FakeHook<AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>>>} readResourceForScheme
* @property {HookMap<AsyncSeriesBailHook<[LoaderContext<any>], string | Buffer>>} readResource * @property {HookMap<AsyncSeriesBailHook<[LoaderContext<any>], string | Buffer | null>>} readResource
* @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
*/ */
@ -268,7 +272,7 @@ class NormalModule extends Module {
/** @type {NormalModuleCompilationHooks} */ /** @type {NormalModuleCompilationHooks} */
(hooks).readResource.for(scheme); (hooks).readResource.for(scheme);
return createFakeHook( return createFakeHook(
/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer>} */ ({ /** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({
tap: (options, fn) => tap: (options, fn) =>
hook.tap(options, loaderContext => hook.tap(options, loaderContext =>
fn( fn(
@ -1150,7 +1154,7 @@ class NormalModule extends Module {
try { try {
hooks.beforeSnapshot.call(this); hooks.beforeSnapshot.call(this);
} catch (err) { } catch (err) {
this.markModuleAsErrored(err); this.markModuleAsErrored(/** @type {WebpackError} */ (err));
return callback(); return callback();
} }
@ -1240,7 +1244,7 @@ class NormalModule extends Module {
try { try {
hooks.beforeParse.call(this); hooks.beforeParse.call(this);
} catch (err) { } catch (err) {
this.markModuleAsErrored(err); this.markModuleAsErrored(/** @type {WebpackError} */ (err));
this._initBuildHash(compilation); this._initBuildHash(compilation);
return callback(); return callback();
} }

View File

@ -71,7 +71,7 @@ class WebpackOptionsApply extends OptionsApply {
* @returns {WebpackOptions} options object * @returns {WebpackOptions} options object
*/ */
process(options, compiler) { process(options, compiler) {
compiler.outputPath = options.output.path; compiler.outputPath = /** @type {string} */ (options.output.path);
compiler.recordsInputPath = options.recordsInputPath || null; compiler.recordsInputPath = options.recordsInputPath || null;
compiler.recordsOutputPath = options.recordsOutputPath || null; compiler.recordsOutputPath = options.recordsOutputPath || null;
compiler.name = options.name; compiler.name = options.name;
@ -200,22 +200,34 @@ class WebpackOptionsApply extends OptionsApply {
} }
} }
if (options.output.enabledChunkLoadingTypes.length > 0) { const enabledChunkLoadingTypes =
for (const type of options.output.enabledChunkLoadingTypes) { /** @type {NonNullable<WebpackOptions["output"]["enabledChunkLoadingTypes"]>} */
(options.output.enabledChunkLoadingTypes);
if (enabledChunkLoadingTypes.length > 0) {
for (const type of enabledChunkLoadingTypes) {
const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin"); const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin");
new EnableChunkLoadingPlugin(type).apply(compiler); new EnableChunkLoadingPlugin(type).apply(compiler);
} }
} }
if (options.output.enabledWasmLoadingTypes.length > 0) { const enabledWasmLoadingTypes =
for (const type of options.output.enabledWasmLoadingTypes) { /** @type {NonNullable<WebpackOptions["output"]["enabledWasmLoadingTypes"]>} */
(options.output.enabledWasmLoadingTypes);
if (enabledWasmLoadingTypes.length > 0) {
for (const type of enabledWasmLoadingTypes) {
const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin"); const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin");
new EnableWasmLoadingPlugin(type).apply(compiler); new EnableWasmLoadingPlugin(type).apply(compiler);
} }
} }
if (options.output.enabledLibraryTypes.length > 0) { const enabledLibraryTypes =
for (const type of options.output.enabledLibraryTypes) { /** @type {NonNullable<WebpackOptions["output"]["enabledLibraryTypes"]>} */
(options.output.enabledLibraryTypes);
if (enabledLibraryTypes.length > 0) {
for (const type of enabledLibraryTypes) {
const EnableLibraryPlugin = require("./library/EnableLibraryPlugin"); const EnableLibraryPlugin = require("./library/EnableLibraryPlugin");
new EnableLibraryPlugin(type).apply(compiler); new EnableLibraryPlugin(type).apply(compiler);
} }
@ -320,7 +332,7 @@ class WebpackOptionsApply extends OptionsApply {
const lazyOptions = const lazyOptions =
typeof options.experiments.lazyCompilation === "object" typeof options.experiments.lazyCompilation === "object"
? options.experiments.lazyCompilation ? options.experiments.lazyCompilation
: null; : {};
new LazyCompilationPlugin({ new LazyCompilationPlugin({
backend: backend:
typeof lazyOptions.backend === "function" typeof lazyOptions.backend === "function"
@ -348,7 +360,11 @@ class WebpackOptionsApply extends OptionsApply {
} }
new EntryOptionPlugin().apply(compiler); new EntryOptionPlugin().apply(compiler);
compiler.hooks.entryOption.call(options.context, options.entry); compiler.hooks.entryOption.call(
/** @type {string} */
(options.context),
options.entry
);
new RuntimePlugin().apply(compiler); new RuntimePlugin().apply(compiler);
@ -595,9 +611,12 @@ class WebpackOptionsApply extends OptionsApply {
const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin"); const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin");
new AddManagedPathsPlugin( new AddManagedPathsPlugin(
options.snapshot.managedPaths, /** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
options.snapshot.immutablePaths, (options.snapshot.managedPaths),
options.snapshot.unmanagedPaths /** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
(options.snapshot.immutablePaths),
/** @type {NonNullable<WebpackOptions["snapshot"]["managedPaths"]>} */
(options.snapshot.unmanagedPaths)
).apply(compiler); ).apply(compiler);
if (options.cache && typeof options.cache === "object") { if (options.cache && typeof options.cache === "object") {
@ -608,7 +627,9 @@ class WebpackOptionsApply extends OptionsApply {
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin"); const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin");
new MemoryWithGcCachePlugin({ new MemoryWithGcCachePlugin({
maxGenerations: cacheOptions.maxGenerations maxGenerations:
/** @type {number} */
(cacheOptions.maxGenerations)
}).apply(compiler); }).apply(compiler);
} else { } else {
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
@ -658,17 +679,19 @@ class WebpackOptionsApply extends OptionsApply {
new IdleFileCachePlugin( new IdleFileCachePlugin(
new PackFileCacheStrategy({ new PackFileCacheStrategy({
compiler, compiler,
fs: /** @type {IntermediateFileSystem} */ ( fs:
compiler.intermediateFileSystem /** @type {IntermediateFileSystem} */
), (compiler.intermediateFileSystem),
context: options.context, context: /** @type {string} */ (options.context),
cacheLocation: cacheOptions.cacheLocation, cacheLocation:
/** @type {string} */
(cacheOptions.cacheLocation),
version: cacheOptions.version, version: cacheOptions.version,
logger: compiler.getInfrastructureLogger( logger: compiler.getInfrastructureLogger(
"webpack.cache.PackFileCacheStrategy" "webpack.cache.PackFileCacheStrategy"
), ),
snapshot: options.snapshot, snapshot: options.snapshot,
maxAge: cacheOptions.maxAge, maxAge: /** @type {number} */ (cacheOptions.maxAge),
profile: cacheOptions.profile, profile: cacheOptions.profile,
allowCollectingMemory: cacheOptions.allowCollectingMemory, allowCollectingMemory: cacheOptions.allowCollectingMemory,
compression: cacheOptions.compression, compression: cacheOptions.compression,

View File

@ -816,6 +816,7 @@ class PackContent {
return this.content.get(identifier); return this.content.get(identifier);
} }
const logger = /** @type {Logger} */ (this.logger);
// We are in state B // We are in state B
const { lazyName } = this; const { lazyName } = this;
/** @type {string | undefined} */ /** @type {string | undefined} */
@ -826,19 +827,19 @@ class PackContent {
timeMessage = `restore cache content ${lazyName} (${formatSize( timeMessage = `restore cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)})`; )})`;
this.logger.log( logger.log(
`starting to restore cache content ${lazyName} (${formatSize( `starting to restore cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)}) because of request to: ${identifier}` )}) because of request to: ${identifier}`
); );
this.logger.time(timeMessage); logger.time(timeMessage);
} }
const value = this.lazy(); const value = this.lazy();
if ("then" in value) { if ("then" in value) {
return value.then(data => { return value.then(data => {
const map = data.map; const map = data.map;
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
// Move to state C // Move to state C
this.content = map; this.content = map;
@ -849,7 +850,7 @@ class PackContent {
const map = value.map; const map = value.map;
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
// Move to state C // Move to state C
this.content = map; this.content = map;
@ -864,6 +865,7 @@ class PackContent {
unpack(reason) { unpack(reason) {
if (this.content) return; if (this.content) return;
const logger = /** @type {Logger} */ (this.logger);
// Move from state B to C // Move from state B to C
if (this.lazy) { if (this.lazy) {
const { lazyName } = this; const { lazyName } = this;
@ -875,24 +877,24 @@ class PackContent {
timeMessage = `unpack cache content ${lazyName} (${formatSize( timeMessage = `unpack cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)})`; )})`;
this.logger.log( logger.log(
`starting to unpack cache content ${lazyName} (${formatSize( `starting to unpack cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)}) because ${reason}` )}) because ${reason}`
); );
this.logger.time(timeMessage); logger.time(timeMessage);
} }
const value = this.lazy(); const value = this.lazy();
if ("then" in value) { if ("then" in value) {
return value.then(data => { return value.then(data => {
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
this.content = data.map; this.content = data.map;
}); });
} }
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
this.content = value.map; this.content = value.map;
} }
@ -955,6 +957,7 @@ class PackContent {
); );
return; return;
} }
const logger = /** @type {Logger} */ (this.logger);
// State B2 // State B2
const { lazyName } = this; const { lazyName } = this;
/** @type {string | undefined} */ /** @type {string | undefined} */
@ -965,12 +968,12 @@ class PackContent {
timeMessage = `unpack cache content ${lazyName} (${formatSize( timeMessage = `unpack cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)})`; )})`;
this.logger.log( logger.log(
`starting to unpack cache content ${lazyName} (${formatSize( `starting to unpack cache content ${lazyName} (${formatSize(
this.getSize() this.getSize()
)}) because it's outdated and need to be serialized` )}) because it's outdated and need to be serialized`
); );
this.logger.time(timeMessage); logger.time(timeMessage);
} }
const value = this.lazy(); const value = this.lazy();
this.outdated = false; this.outdated = false;
@ -979,7 +982,7 @@ class PackContent {
this.lazy = write(() => this.lazy = write(() =>
value.then(data => { value.then(data => {
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
const oldMap = data.map; const oldMap = data.map;
/** @type {Map<string, any>} */ /** @type {Map<string, any>} */
@ -997,7 +1000,7 @@ class PackContent {
} else { } else {
// Move to state C1 // Move to state C1
if (timeMessage) { if (timeMessage) {
this.logger.timeEnd(timeMessage); logger.timeEnd(timeMessage);
} }
const oldMap = value.map; const oldMap = value.map;
/** @type {Map<string, any>} */ /** @type {Map<string, any>} */

View File

@ -76,7 +76,7 @@ class ContainerPlugin {
const dep = new ContainerEntryDependency(name, exposes, shareScope); const dep = new ContainerEntryDependency(name, exposes, shareScope);
dep.loc = { name }; dep.loc = { name };
compilation.addEntry( compilation.addEntry(
compilation.options.context, /** @type {string} */ (compilation.options.context),
dep, dep,
{ {
name, name,

View File

@ -12,6 +12,7 @@ const Template = require("../Template");
/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Chunk").ChunkId} ChunkId */ /** @typedef {import("../Chunk").ChunkId} ChunkId */
/** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("./RemoteModule")} RemoteModule */ /** @typedef {import("./RemoteModule")} RemoteModule */
@ -29,7 +30,7 @@ class RemoteRuntimeModule extends RuntimeModule {
const { runtimeTemplate, moduleGraph } = compilation; const { runtimeTemplate, moduleGraph } = compilation;
/** @type {Record<ChunkId, (string | number)[]>} */ /** @type {Record<ChunkId, (string | number)[]>} */
const chunkToRemotesMapping = {}; const chunkToRemotesMapping = {};
/** @type {Record<string | number, [string, string, string | number | null]>} */ /** @type {Record<ModuleId, [string, string, string | number | null]>} */
const idToExternalAndNameMapping = {}; const idToExternalAndNameMapping = {};
for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) { for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) {
const modules = chunkGraph.getChunkModulesIterableBySourceType( const modules = chunkGraph.getChunkModulesIterableBySourceType(
@ -37,19 +38,21 @@ class RemoteRuntimeModule extends RuntimeModule {
"remote" "remote"
); );
if (!modules) continue; if (!modules) continue;
/** @type {(string | number)[]} */ /** @type {ModuleId[]} */
const remotes = (chunkToRemotesMapping[ const remotes = (chunkToRemotesMapping[
/** @type {ChunkId} */ (chunk.id) /** @type {ChunkId} */
(chunk.id)
] = []); ] = []);
for (const m of modules) { for (const m of modules) {
const module = /** @type {RemoteModule} */ (m); const module = /** @type {RemoteModule} */ (m);
const name = module.internalRequest; const name = module.internalRequest;
const id = chunkGraph.getModuleId(module); const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
const shareScope = module.shareScope; const shareScope = module.shareScope;
const dep = module.dependencies[0]; const dep = module.dependencies[0];
const externalModule = moduleGraph.getModule(dep); const externalModule = moduleGraph.getModule(dep);
const externalModuleId = const externalModuleId =
externalModule && chunkGraph.getModuleId(externalModule); /** @type {ModuleId} */
(externalModule && chunkGraph.getModuleId(externalModule));
remotes.push(id); remotes.push(id);
idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId]; idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId];
} }

View File

@ -5,7 +5,15 @@
"use strict"; "use strict";
/** @template T @typedef {(string | Record<string, string | string[] | T>)[] | Record<string, string | string[] | T>} ContainerOptionsFormat */ /**
* @template T
* @typedef {Record<string, string | string[] | T>} Item
*/
/**
* @template T
* @typedef {(string | Item<T>)[] | Item<T>} ContainerOptionsFormat
*/
/** /**
* @template T * @template T
@ -17,6 +25,9 @@
* @returns {void} * @returns {void}
*/ */
const process = (options, normalizeSimple, normalizeOptions, fn) => { const process = (options, normalizeSimple, normalizeOptions, fn) => {
/**
* @param {(string | Item<T>)[]} items items
*/
const array = items => { const array = items => {
for (const item of items) { for (const item of items) {
if (typeof item === "string") { if (typeof item === "string") {
@ -28,6 +39,9 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
} }
} }
}; };
/**
* @param {Item<T>} obj an object
*/
const object = obj => { const object = obj => {
for (const [key, value] of Object.entries(obj)) { for (const [key, value] of Object.entries(obj)) {
if (typeof value === "string" || Array.isArray(value)) { if (typeof value === "string" || Array.isArray(value)) {

View File

@ -111,7 +111,7 @@ class AMDDefineDependency extends NullDependency {
* @param {Range | null} arrayRange array range * @param {Range | null} arrayRange array range
* @param {Range | null} functionRange function range * @param {Range | null} functionRange function range
* @param {Range | null} objectRange object range * @param {Range | null} objectRange object range
* @param {boolean | null} namedModule true, when define is called with a name * @param {string | null} namedModule true, when define is called with a name
*/ */
constructor(range, arrayRange, functionRange, objectRange, namedModule) { constructor(range, arrayRange, functionRange, objectRange, namedModule) {
super(); super();

View File

@ -20,7 +20,11 @@ const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers");
/** @typedef {import("estree").CallExpression} CallExpression */ /** @typedef {import("estree").CallExpression} CallExpression */
/** @typedef {import("estree").Expression} Expression */ /** @typedef {import("estree").Expression} Expression */
/** @typedef {import("estree").FunctionExpression} FunctionExpression */ /** @typedef {import("estree").FunctionExpression} FunctionExpression */
/** @typedef {import("estree").Identifier} Identifier */
/** @typedef {import("estree").Literal} Literal */ /** @typedef {import("estree").Literal} Literal */
/** @typedef {import("estree").MemberExpression} MemberExpression */
/** @typedef {import("estree").ObjectExpression} ObjectExpression */
/** @typedef {import("estree").SimpleCallExpression} SimpleCallExpression */
/** @typedef {import("estree").SpreadElement} SpreadElement */ /** @typedef {import("estree").SpreadElement} SpreadElement */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
@ -30,7 +34,7 @@ const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers");
/** /**
* @param {Expression | SpreadElement} expr expression * @param {Expression | SpreadElement} expr expression
* @returns {boolean} true if it's a bound function expression * @returns {expr is CallExpression} true if it's a bound function expression
*/ */
const isBoundFunctionExpression = expr => { const isBoundFunctionExpression = expr => {
if (expr.type !== "CallExpression") return false; if (expr.type !== "CallExpression") return false;
@ -46,7 +50,7 @@ const isBoundFunctionExpression = expr => {
/** /**
* @param {Expression | SpreadElement} expr expression * @param {Expression | SpreadElement} expr expression
* @returns {boolean} true when unbound function expression * @returns {expr is FunctionExpression | ArrowFunctionExpression} true when unbound function expression
*/ */
const isUnboundFunctionExpression = expr => { const isUnboundFunctionExpression = expr => {
if (expr.type === "FunctionExpression") return true; if (expr.type === "FunctionExpression") return true;
@ -56,7 +60,7 @@ const isUnboundFunctionExpression = expr => {
/** /**
* @param {Expression | SpreadElement} expr expression * @param {Expression | SpreadElement} expr expression
* @returns {boolean} true when callable * @returns {expr is FunctionExpression | ArrowFunctionExpression | CallExpression} true when callable
*/ */
const isCallable = expr => { const isCallable = expr => {
if (isUnboundFunctionExpression(expr)) return true; if (isUnboundFunctionExpression(expr)) return true;
@ -103,7 +107,9 @@ class AMDDefineDependencyParserPlugin {
/** @type {string} */ (item.string) /** @type {string} */ (item.string)
) )
) )
identifiers[/** @type {number} */ (idx)] = item.string; identifiers[/** @type {number} */ (idx)] = /** @type {string} */ (
item.string
);
const result = this.processItem(parser, expr, item, namedModule); const result = this.processItem(parser, expr, item, namedModule);
if (result === undefined) { if (result === undefined) {
this.processContext(parser, expr, item); this.processContext(parser, expr, item);
@ -113,8 +119,8 @@ class AMDDefineDependencyParserPlugin {
} else if (param.isConstArray()) { } else if (param.isConstArray()) {
/** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */ /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
const deps = []; const deps = [];
/** @type {string[]} */ const array = /** @type {string[]} */ (param.array);
for (const [idx, request] of param.array.entries()) { for (const [idx, request] of array.entries()) {
let dep; let dep;
let localModule; let localModule;
if (request === "require") { if (request === "require") {
@ -242,9 +248,13 @@ class AMDDefineDependencyParserPlugin {
* @returns {boolean | undefined} result * @returns {boolean | undefined} result
*/ */
processCallDefine(parser, expr) { processCallDefine(parser, expr) {
/** @type {TODO} */
let array; let array;
/** @type {FunctionExpression | ArrowFunctionExpression | CallExpression | Identifier | undefined} */
let fn; let fn;
/** @type {ObjectExpression | Identifier | undefined} */
let obj; let obj;
/** @type {string | undefined} */
let namedModule; let namedModule;
switch (expr.arguments.length) { switch (expr.arguments.length) {
case 1: case 1:
@ -257,12 +267,12 @@ class AMDDefineDependencyParserPlugin {
} else { } else {
// define(expr) // define(expr)
// unclear if function or object // unclear if function or object
obj = fn = expr.arguments[0]; obj = fn = /** @type {Identifier} */ (expr.arguments[0]);
} }
break; break;
case 2: case 2:
if (expr.arguments[0].type === "Literal") { if (expr.arguments[0].type === "Literal") {
namedModule = expr.arguments[0].value; namedModule = /** @type {string} */ (expr.arguments[0].value);
// define("…", …) // define("…", …)
if (isCallable(expr.arguments[1])) { if (isCallable(expr.arguments[1])) {
// define("…", f() {…}) // define("…", f() {…})
@ -273,7 +283,7 @@ class AMDDefineDependencyParserPlugin {
} else { } else {
// define("…", expr) // define("…", expr)
// unclear if function or object // unclear if function or object
obj = fn = expr.arguments[1]; obj = fn = /** @type {Identifier} */ (expr.arguments[1]);
} }
} else { } else {
array = expr.arguments[0]; array = expr.arguments[0];
@ -286,13 +296,18 @@ class AMDDefineDependencyParserPlugin {
} else { } else {
// define([…], expr) // define([…], expr)
// unclear if function or object // unclear if function or object
obj = fn = expr.arguments[1]; obj = fn = /** @type {Identifier} */ (expr.arguments[1]);
} }
} }
break; break;
case 3: case 3:
// define("…", […], f() {…}) // define("…", […], f() {…})
namedModule = /** @type {TODO} */ (expr).arguments[0].value; namedModule =
/** @type {string} */
(
/** @type {Literal} */
(expr.arguments[0]).value
);
array = expr.arguments[1]; array = expr.arguments[1];
if (isCallable(expr.arguments[2])) { if (isCallable(expr.arguments[2])) {
// define("…", […], f() {}) // define("…", […], f() {})
@ -303,21 +318,30 @@ class AMDDefineDependencyParserPlugin {
} else { } else {
// define("…", […], expr) // define("…", […], expr)
// unclear if function or object // unclear if function or object
obj = fn = expr.arguments[2]; obj = fn = /** @type {Identifier} */ (expr.arguments[2]);
} }
break; break;
default: default:
return; return;
} }
DynamicExports.bailout(parser.state); DynamicExports.bailout(parser.state);
/** @type {Identifier[] | null} */
let fnParams = null; let fnParams = null;
let fnParamsOffset = 0; let fnParamsOffset = 0;
if (fn) { if (fn) {
if (isUnboundFunctionExpression(fn)) { if (isUnboundFunctionExpression(fn)) {
fnParams = /** @type {UnboundFunctionExpression} */ (fn).params; fnParams =
/** @type {Identifier[]} */
(fn.params);
} else if (isBoundFunctionExpression(fn)) { } else if (isBoundFunctionExpression(fn)) {
fnParams = /** @type {TODO} */ (fn).callee.object.params; const object =
fnParamsOffset = /** @type {TODO} */ (fn).arguments.length - 1; /** @type {FunctionExpression} */
(/** @type {MemberExpression} */ (fn.callee).object);
fnParams =
/** @type {Identifier[]} */
(object.params);
fnParamsOffset = fn.arguments.length - 1;
if (fnParamsOffset < 0) { if (fnParamsOffset < 0) {
fnParamsOffset = 0; fnParamsOffset = 0;
} }
@ -378,9 +402,14 @@ class AMDDefineDependencyParserPlugin {
}); });
} else if (fn && isBoundFunctionExpression(fn)) { } else if (fn && isBoundFunctionExpression(fn)) {
inTry = parser.scope.inTry; inTry = parser.scope.inTry;
const object =
/** @type {FunctionExpression} */
(/** @type {MemberExpression} */ (fn.callee).object);
parser.inScope( parser.inScope(
/** @type {TODO} */ /** @type {Identifier[]} */
(fn).callee.object.params.filter( (object.params).filter(
i => !["require", "module", "exports"].includes(i.name) i => !["require", "module", "exports"].includes(i.name)
), ),
() => { () => {
@ -388,19 +417,20 @@ class AMDDefineDependencyParserPlugin {
parser.setVariable(name, varInfo); parser.setVariable(name, varInfo);
} }
parser.scope.inTry = /** @type {boolean} */ (inTry); parser.scope.inTry = /** @type {boolean} */ (inTry);
if (fn.callee.object.body.type === "BlockStatement") {
parser.detectMode(fn.callee.object.body.body); if (object.body.type === "BlockStatement") {
parser.detectMode(object.body.body);
const prev = parser.prevStatement; const prev = parser.prevStatement;
parser.preWalkStatement(fn.callee.object.body); parser.preWalkStatement(object.body);
parser.prevStatement = prev; parser.prevStatement = prev;
parser.walkStatement(fn.callee.object.body); parser.walkStatement(object.body);
} else { } else {
parser.walkExpression(fn.callee.object.body); parser.walkExpression(object.body);
} }
} }
); );
if (/** @type {TODO} */ (fn).arguments) { if (fn.arguments) {
parser.walkExpressions(/** @type {TODO} */ (fn).arguments); parser.walkExpressions(fn.arguments);
} }
} else if (fn || obj) { } else if (fn || obj) {
parser.walkExpression(fn || obj); parser.walkExpression(fn || obj);
@ -426,7 +456,7 @@ class AMDDefineDependencyParserPlugin {
* @param {Range | null} arrayRange array range * @param {Range | null} arrayRange array range
* @param {Range | null} functionRange function range * @param {Range | null} functionRange function range
* @param {Range | null} objectRange object range * @param {Range | null} objectRange object range
* @param {boolean | null} namedModule true, when define is called with a name * @param {string | null} namedModule true, when define is called with a name
* @returns {AMDDefineDependency} AMDDefineDependency * @returns {AMDDefineDependency} AMDDefineDependency
*/ */
newDefineDependency( newDefineDependency(
@ -446,7 +476,7 @@ class AMDDefineDependencyParserPlugin {
} }
/** /**
* @param {TODO[]} depsArray deps array * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
* @param {Range} range range * @param {Range} range range
* @returns {AMDRequireArrayDependency} AMDRequireArrayDependency * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
*/ */

View File

@ -272,10 +272,12 @@ class AMDRequireDependenciesBlockParserPlugin {
const old = parser.state.current; const old = parser.state.current;
if (expr.arguments.length >= 1) { if (expr.arguments.length >= 1) {
param = parser.evaluateExpression(expr.arguments[0]); param = parser.evaluateExpression(
/** @type {Expression} */ (expr.arguments[0])
);
depBlock = this.newRequireDependenciesBlock( depBlock = this.newRequireDependenciesBlock(
/** @type {DependencyLocation} */ (expr.loc), /** @type {DependencyLocation} */ (expr.loc),
/** @type {string} */ (this.processArrayForRequestString(param)) this.processArrayForRequestString(param)
); );
dep = this.newRequireDependency( dep = this.newRequireDependency(
/** @type {Range} */ (expr.range), /** @type {Range} */ (expr.range),
@ -359,7 +361,7 @@ class AMDRequireDependenciesBlockParserPlugin {
/** /**
* @param {DependencyLocation} loc location * @param {DependencyLocation} loc location
* @param {string} request request * @param {string=} request request
* @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock
*/ */
newRequireDependenciesBlock(loc, request) { newRequireDependenciesBlock(loc, request) {

View File

@ -20,9 +20,9 @@ class ContextElementDependency extends ModuleDependency {
/** /**
* @param {string} request request * @param {string} request request
* @param {string|undefined} userRequest user request * @param {string|undefined} userRequest user request
* @param {string} typePrefix type prefix * @param {string | undefined} typePrefix type prefix
* @param {string} category category * @param {string} category category
* @param {string[][]=} referencedExports referenced exports * @param {(string[][] | null)=} referencedExports referenced exports
* @param {string=} context context * @param {string=} context context
* @param {ImportAttributes=} attributes import assertions * @param {ImportAttributes=} attributes import assertions
*/ */

View File

@ -58,9 +58,9 @@ class CssExportDependency extends NullDependency {
*/ */
getExports(moduleGraph) { getExports(moduleGraph) {
const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this)); const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( const convention =
module.generator /** @type {CssGenerator | CssExportsGenerator} */
).convention; (module.generator).convention;
const names = this.getExportsConventionNames(this.name, convention); const names = this.getExportsConventionNames(this.name, convention);
return { return {
exports: names.map(name => ({ exports: names.map(name => ({
@ -81,9 +81,9 @@ class CssExportDependency extends NullDependency {
const module = /** @type {CssModule} */ ( const module = /** @type {CssModule} */ (
chunkGraph.moduleGraph.getParentModule(this) chunkGraph.moduleGraph.getParentModule(this)
); );
const generator = /** @type {CssGenerator | CssExportsGenerator} */ ( const generator =
module.generator /** @type {CssGenerator | CssExportsGenerator} */
); (module.generator);
const names = this.getExportsConventionNames( const names = this.getExportsConventionNames(
this.name, this.name,
generator.convention generator.convention

View File

@ -1178,6 +1178,15 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
} }
} }
/**
* @param {Module} module the current module
* @param {string} comment comment
* @param {string | string[] | false} key key
* @param {string} name name
* @param {string | string[] | false} valueKey value key
* @param {RuntimeRequirements} runtimeRequirements runtime requirements
* @returns {HarmonyExportInitFragment} harmony export init fragment
*/
getReexportFragment( getReexportFragment(
module, module,
comment, comment,

View File

@ -50,7 +50,7 @@ const harmonySpecifierTag = Symbol("harmony import");
/** /**
* @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | (ImportExpression & { arguments?: ObjectExpression[] })} node node with assertions * @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | (ImportExpression & { arguments?: ObjectExpression[] })} node node with assertions
* @returns {ImportAttributes} import attributes * @returns {ImportAttributes | undefined} import attributes
*/ */
function getAttributes(node) { function getAttributes(node) {
if ( if (
@ -138,12 +138,22 @@ module.exports = class HarmonyImportDependencyParserPlugin {
apply(parser) { apply(parser) {
const { exportPresenceMode } = this; const { exportPresenceMode } = this;
/**
* @param {string[]} members members
* @param {boolean[]} membersOptionals members Optionals
* @returns {string[]} a non optional part
*/
function getNonOptionalPart(members, membersOptionals) { function getNonOptionalPart(members, membersOptionals) {
let i = 0; let i = 0;
while (i < members.length && membersOptionals[i] === false) i++; while (i < members.length && membersOptionals[i] === false) i++;
return i !== members.length ? members.slice(0, i) : members; return i !== members.length ? members.slice(0, i) : members;
} }
/**
* @param {TODO} node member expression
* @param {number} count count
* @returns {TODO} member expression
*/
function getNonOptionalMemberChain(node, count) { function getNonOptionalMemberChain(node, count) {
while (count--) node = node.object; while (count--) node = node.object;
return node; return node;
@ -221,7 +231,9 @@ module.exports = class HarmonyImportDependencyParserPlugin {
) )
return; return;
const settings = rootInfo.tagInfo.data; const settings = rootInfo.tagInfo.data;
const members = rightPart.getMembers(); const members =
/** @type {(() => string[])} */
(rightPart.getMembers)();
const dep = new HarmonyEvaluatedImportSpecifierDependency( const dep = new HarmonyEvaluatedImportSpecifierDependency(
settings.source, settings.source,
settings.sourceOrder, settings.sourceOrder,
@ -280,6 +292,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
members, members,
membersOptionals membersOptionals
); );
/** @type {Range[]} */
const ranges = memberRanges.slice( const ranges = memberRanges.slice(
0, 0,
memberRanges.length - (members.length - nonOptionalMembers.length) memberRanges.length - (members.length - nonOptionalMembers.length)
@ -326,6 +339,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
members, members,
membersOptionals membersOptionals
); );
/** @type {Range[]} */
const ranges = memberRanges.slice( const ranges = memberRanges.slice(
0, 0,
memberRanges.length - (members.length - nonOptionalMembers.length) memberRanges.length - (members.length - nonOptionalMembers.length)

View File

@ -39,7 +39,7 @@ const { registerNotSerializable } = require("../util/serialization");
/** /**
* @typedef {object} BackendApi * @typedef {object} BackendApi
* @property {function(Error=): void} dispose * @property {function(function((Error | null)=) : void): void} dispose
* @property {function(Module): { client: string, data: string, active: boolean }} module * @property {function(Module): { client: string, data: string, active: boolean }} module
*/ */
@ -320,10 +320,10 @@ class LazyCompilationDependencyFactory extends ModuleFactory {
class LazyCompilationPlugin { class LazyCompilationPlugin {
/** /**
* @param {object} options options * @param {object} options options
* @param {(function(Compiler, function(Error?, BackendApi?): void): void) | function(Compiler): Promise<BackendApi>} options.backend the backend * @param {(function(Compiler, function(Error=, BackendApi?): void): void) | function(Compiler): Promise<BackendApi>} options.backend the backend
* @param {boolean} options.entries true, when entries are lazy compiled * @param {boolean} options.entries true, when entries are lazy compiled
* @param {boolean} options.imports true, when import() modules are lazy compiled * @param {boolean} options.imports true, when import() modules are lazy compiled
* @param {RegExp | string | (function(Module): boolean)} options.test additional filter for lazy compiled entrypoint modules * @param {RegExp | string | (function(Module): boolean) | undefined} options.test additional filter for lazy compiled entrypoint modules
*/ */
constructor({ backend, entries, imports, test }) { constructor({ backend, entries, imports, test }) {
this.backend = backend; this.backend = backend;
@ -338,6 +338,7 @@ class LazyCompilationPlugin {
* @returns {void} * @returns {void}
*/ */
apply(compiler) { apply(compiler) {
/** @type {BackendApi} */
let backend; let backend;
compiler.hooks.beforeCompile.tapAsync( compiler.hooks.beforeCompile.tapAsync(
"LazyCompilationPlugin", "LazyCompilationPlugin",

View File

@ -5,15 +5,22 @@
"use strict"; "use strict";
/** @typedef {import("http").IncomingMessage} IncomingMessage */
/** @typedef {import("http").RequestListener} RequestListener */
/** @typedef {import("http").ServerOptions} HttpServerOptions */ /** @typedef {import("http").ServerOptions} HttpServerOptions */
/** @typedef {import("http").ServerResponse} ServerResponse */
/** @typedef {import("https").ServerOptions} HttpsServerOptions */ /** @typedef {import("https").ServerOptions} HttpsServerOptions */
/** @typedef {import("net").AddressInfo} AddressInfo */
/** @typedef {import("net").Server} Server */
/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */ /** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("./LazyCompilationPlugin").BackendApi} BackendApi */
/** /**
* @callback BackendHandler * @callback BackendHandler
* @param {Compiler} compiler compiler * @param {Compiler} compiler compiler
* @param {function((Error | null)=, any=): void} callback callback * @param {function(Error | null, BackendApi=): void} callback callback
* @returns {void} * @returns {void}
*/ */
@ -36,8 +43,13 @@ module.exports = options => (compiler, callback) => {
? options.server ? options.server
: (() => { : (() => {
const http = isHttps ? require("https") : require("http"); const http = isHttps ? require("https") : require("http");
return http.createServer.bind(http, options.server); return http.createServer.bind(
http,
/** @type {HttpServerOptions | HttpsServerOptions} */
(options.server)
);
})(); })();
/** @type {function(Server): void} */
const listen = const listen =
typeof options.listen === "function" typeof options.listen === "function"
? options.listen ? options.listen
@ -50,7 +62,9 @@ module.exports = options => (compiler, callback) => {
const protocol = options.protocol || (isHttps ? "https" : "http"); const protocol = options.protocol || (isHttps ? "https" : "http");
/** @type {RequestListener} */
const requestListener = (req, res) => { const requestListener = (req, res) => {
if (req.url === undefined) return;
const keys = req.url.slice(prefix.length).split("@"); const keys = req.url.slice(prefix.length).split("@");
req.socket.on("close", () => { req.socket.on("close", () => {
setTimeout(() => { setTimeout(() => {
@ -85,7 +99,7 @@ module.exports = options => (compiler, callback) => {
if (moduleActivated && compiler.watching) compiler.watching.invalidate(); if (moduleActivated && compiler.watching) compiler.watching.invalidate();
}; };
const server = /** @type {import("net").Server} */ (createServer()); const server = /** @type {Server} */ (createServer());
server.on("request", requestListener); server.on("request", requestListener);
let isClosing = false; let isClosing = false;
@ -101,10 +115,19 @@ module.exports = options => (compiler, callback) => {
server.on("clientError", e => { server.on("clientError", e => {
if (e.message !== "Server is disposing") logger.warn(e); if (e.message !== "Server is disposing") logger.warn(e);
}); });
server.on("listening", err => {
server.on(
"listening",
/**
* @param {Error} err error
* @returns {void}
*/
err => {
if (err) return callback(err); if (err) return callback(err);
const addr = server.address(); const _addr = server.address();
if (typeof addr === "string") throw new Error("addr must not be a string"); if (typeof _addr === "string")
throw new Error("addr must not be a string");
const addr = /** @type {AddressInfo} */ (_addr);
const urlBase = const urlBase =
addr.address === "::" || addr.address === "0.0.0.0" addr.address === "::" || addr.address === "0.0.0.0"
? `${protocol}://localhost:${addr.port}` ? `${protocol}://localhost:${addr.port}`
@ -129,7 +152,7 @@ module.exports = options => (compiler, callback) => {
module(originalModule) { module(originalModule) {
const key = `${encodeURIComponent( const key = `${encodeURIComponent(
originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_") originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_")
).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`; ).replace(/%(2F|3A|24|26|2B|2C|3B|3D)/g, decodeURIComponent)}`;
const active = activeModules.get(key) > 0; const active = activeModules.get(key) > 0;
return { return {
client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`, client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
@ -138,6 +161,7 @@ module.exports = options => (compiler, callback) => {
}; };
} }
}); });
}); }
);
listen(server); listen(server);
}; };

View File

@ -204,7 +204,7 @@ const objectAndMembersToName = (object, membersReversed) => {
* [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and * [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
* [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is * [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
* specifically for handling the `new.target` meta property. * specifically for handling the `new.target` meta property.
* @param {Expression | Super} expression expression * @param {Expression | SpreadElement | Super} expression expression
* @returns {string | "this" | undefined} name or variable info * @returns {string | "this" | undefined} name or variable info
*/ */
const getRootName = expression => { const getRootName = expression => {
@ -248,7 +248,7 @@ class JavascriptParser extends Parser {
this.hooks = Object.freeze({ this.hooks = Object.freeze({
/** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | undefined | null>>} */ /** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | undefined | null>>} */
evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])), evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
/** @type {HookMap<SyncBailHook<[Expression], BasicEvaluatedExpression | undefined | null>>} */ /** @type {HookMap<SyncBailHook<[Expression | SpreadElement], BasicEvaluatedExpression | undefined | null>>} */
evaluate: new HookMap(() => new SyncBailHook(["expression"])), evaluate: new HookMap(() => new SyncBailHook(["expression"])),
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | undefined | null>>} */ /** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | undefined | null>>} */
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])), evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
@ -1212,7 +1212,7 @@ class JavascriptParser extends Parser {
}); });
/** /**
* @param {string} exprType expression type name * @param {string} exprType expression type name
* @param {function(Expression): GetInfoResult | undefined} getInfo get info * @param {function(Expression | SpreadElement): GetInfoResult | undefined} getInfo get info
* @returns {void} * @returns {void}
*/ */
const tapEvaluateWithVariableInfo = (exprType, getInfo) => { const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
@ -4031,7 +4031,7 @@ class JavascriptParser extends Parser {
} }
/** /**
* @param {TODO} expression expression node * @param {Expression | SpreadElement} expression expression node
* @returns {BasicEvaluatedExpression} evaluation result * @returns {BasicEvaluatedExpression} evaluation result
*/ */
evaluateExpression(expression) { evaluateExpression(expression) {

View File

@ -45,26 +45,45 @@ class WebpackLogger {
this.getChildLogger = getChildLogger; this.getChildLogger = getChildLogger;
} }
/**
* @param {...any} args args
*/
error(...args) { error(...args) {
this[LOG_SYMBOL](LogType.error, args); this[LOG_SYMBOL](LogType.error, args);
} }
/**
* @param {...any} args args
*/
warn(...args) { warn(...args) {
this[LOG_SYMBOL](LogType.warn, args); this[LOG_SYMBOL](LogType.warn, args);
} }
/**
* @param {...any} args args
*/
info(...args) { info(...args) {
this[LOG_SYMBOL](LogType.info, args); this[LOG_SYMBOL](LogType.info, args);
} }
/**
* @param {...any} args args
*/
log(...args) { log(...args) {
this[LOG_SYMBOL](LogType.log, args); this[LOG_SYMBOL](LogType.log, args);
} }
/**
* @param {...any} args args
*/
debug(...args) { debug(...args) {
this[LOG_SYMBOL](LogType.debug, args); this[LOG_SYMBOL](LogType.debug, args);
} }
/**
* @param {any} assertion assertion
* @param {...any} args args
*/
assert(assertion, ...args) { assert(assertion, ...args) {
if (!assertion) { if (!assertion) {
this[LOG_SYMBOL](LogType.error, args); this[LOG_SYMBOL](LogType.error, args);
@ -79,20 +98,29 @@ class WebpackLogger {
this[LOG_SYMBOL](LogType.clear); this[LOG_SYMBOL](LogType.clear);
} }
/**
* @param {...any} args args
*/
status(...args) { status(...args) {
this[LOG_SYMBOL](LogType.status, args); this[LOG_SYMBOL](LogType.status, args);
} }
/**
* @param {...any} args args
*/
group(...args) { group(...args) {
this[LOG_SYMBOL](LogType.group, args); this[LOG_SYMBOL](LogType.group, args);
} }
/**
* @param {...any} args args
*/
groupCollapsed(...args) { groupCollapsed(...args) {
this[LOG_SYMBOL](LogType.groupCollapsed, args); this[LOG_SYMBOL](LogType.groupCollapsed, args);
} }
groupEnd(...args) { groupEnd() {
this[LOG_SYMBOL](LogType.groupEnd, args); this[LOG_SYMBOL](LogType.groupEnd);
} }
/** /**

View File

@ -12,7 +12,7 @@ const { LogType } = require("./Logger");
/** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */ /** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */
/** @typedef {function(string): boolean} FilterFunction */ /** @typedef {function(string): boolean} FilterFunction */
/** @typedef {function(string, LogTypeEnum, any[]): void} LoggingFunction */ /** @typedef {function(string, LogTypeEnum, any[]=): void} LoggingFunction */
/** /**
* @typedef {object} LoggerConsole * @typedef {object} LoggerConsole
@ -95,7 +95,7 @@ module.exports = ({ level = "info", debug = false, console }) => {
/** /**
* @param {string} name name of the logger * @param {string} name name of the logger
* @param {LogTypeEnum} type type of the log entry * @param {LogTypeEnum} type type of the log entry
* @param {any[]} args arguments of the log entry * @param {any[]=} args arguments of the log entry
* @returns {void} * @returns {void}
*/ */
const logger = (name, type, args) => { const logger = (name, type, args) => {
@ -165,8 +165,11 @@ module.exports = ({ level = "info", debug = false, console }) => {
break; break;
case LogType.time: { case LogType.time: {
if (!debug && loglevel > LogLevel.log) return; if (!debug && loglevel > LogLevel.log) return;
const ms = args[1] * 1000 + args[2] / 1000000; const [label, start, end] =
const msg = `[${name}] ${args[0]}: ${ms} ms`; /** @type {[string, number, number]} */
(args);
const ms = start * 1000 + end / 1000000;
const msg = `[${name}] ${label}: ${ms} ms`;
if (typeof console.logTime === "function") { if (typeof console.logTime === "function") {
console.logTime(msg); console.logTime(msg);
} else { } else {
@ -193,12 +196,12 @@ module.exports = ({ level = "info", debug = false, console }) => {
case LogType.status: case LogType.status:
if (!debug && loglevel > LogLevel.info) return; if (!debug && loglevel > LogLevel.info) return;
if (typeof console.status === "function") { if (typeof console.status === "function") {
if (args.length === 0) { if (!args || args.length === 0) {
console.status(); console.status();
} else { } else {
console.status(...labeledArgs()); console.status(...labeledArgs());
} }
} else if (args.length !== 0) { } else if (args && args.length !== 0) {
console.info(...labeledArgs()); console.info(...labeledArgs());
} }
break; break;

View File

@ -48,14 +48,6 @@ const ConcatenatedModule = require("./ConcatenatedModule");
const formatBailoutReason = msg => `ModuleConcatenation bailout: ${msg}`; const formatBailoutReason = msg => `ModuleConcatenation bailout: ${msg}`;
class ModuleConcatenationPlugin { class ModuleConcatenationPlugin {
/**
* @param {TODO} options options
*/
constructor(options) {
if (typeof options !== "object") options = {};
this.options = options;
}
/** /**
* Apply the plugin * Apply the plugin
* @param {Compiler} compiler the compiler instance * @param {Compiler} compiler the compiler instance

View File

@ -15,7 +15,7 @@ const URIRegEx = /^data:([^;,]+)?((?:;[^;,]+)*?)(?:;(base64))?,(.*)$/i;
/** /**
* @param {string} uri data URI * @param {string} uri data URI
* @returns {Buffer|null} decoded data * @returns {Buffer | null} decoded data
*/ */
const decodeDataURI = uri => { const decodeDataURI = uri => {
const match = URIRegEx.exec(uri); const match = URIRegEx.exec(uri);

View File

@ -9,7 +9,11 @@
* @template {any[]} T * @template {any[]} T
*/ */
class TupleSet { class TupleSet {
/**
* @param {Iterable<T>=} init init
*/
constructor(init) { constructor(init) {
/** @type {Map<T, TODO>} */
this._map = new Map(); this._map = new Map();
this.size = 0; this.size = 0;
if (init) { if (init) {
@ -101,10 +105,17 @@ class TupleSet {
* @returns {Iterator<T>} iterator * @returns {Iterator<T>} iterator
*/ */
[Symbol.iterator]() { [Symbol.iterator]() {
/** @type {TODO[]} */
const iteratorStack = []; const iteratorStack = [];
/** @type {T[]} */
const tuple = []; const tuple = [];
/** @type {Iterator<T> | undefined} */
let currentSetIterator; let currentSetIterator;
/**
* @param {TODO} it iterator
* @returns {boolean} result
*/
const next = it => { const next = it => {
const result = it.next(); const result = it.next();
if (result.done) { if (result.done) {

View File

@ -15,7 +15,10 @@ const deprecationCache = new Map();
* @property {true} _fakeHook it's a fake hook * @property {true} _fakeHook it's a fake hook
*/ */
/** @template T @typedef {T & FakeHookMarker} FakeHook<T> */ /**
* @template T
* @typedef {T & FakeHookMarker} FakeHook<T>
*/
/** /**
* @param {string} message deprecation message * @param {string} message deprecation message
@ -84,8 +87,11 @@ module.exports.arrayToSetDeprecation = (set, name) => {
set[method] = function () { set[method] = function () {
d(); d();
const array = Array.from(this); const array = Array.from(this);
return Array.prototype[/** @type {keyof COPY_METHODS} */ (method)].apply(
array,
// eslint-disable-next-line prefer-rest-params // eslint-disable-next-line prefer-rest-params
return Array.prototype[method].apply(array, arguments); arguments
);
}; };
} }
const dPush = createDeprecation( const dPush = createDeprecation(
@ -191,12 +197,11 @@ module.exports.createArrayToSetDeprecationSet = name => {
}; };
/** /**
* @template T
* @param {object} obj object * @param {object} obj object
* @param {string} name property name * @param {string} name property name
* @param {string} code deprecation code * @param {string} code deprecation code
* @param {string} note additional note * @param {string} note additional note
* @returns {object} frozen object with deprecation when modifying * @returns {Proxy<object>} frozen object with deprecation when modifying
*/ */
module.exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => { module.exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => {
const message = `${name} will be frozen in future, all modifications are deprecated.${ const message = `${name} will be frozen in future, all modifications are deprecated.${

121
types.d.ts vendored
View File

@ -452,7 +452,7 @@ declare class AutomaticPrefetchPlugin {
} }
type AuxiliaryComment = string | LibraryCustomUmdCommentObject; type AuxiliaryComment = string | LibraryCustomUmdCommentObject;
declare interface BackendApi { declare interface BackendApi {
dispose: (arg0?: Error) => void; dispose: (arg0: (arg0?: null | Error) => void) => void;
module: (arg0: Module) => { client: string; data: string; active: boolean }; module: (arg0: Module) => { client: string; data: string; active: boolean };
} }
declare class BannerPlugin { declare class BannerPlugin {
@ -578,6 +578,7 @@ declare abstract class BasicEvaluatedExpression {
| ThisExpression | ThisExpression
| UpdateExpression | UpdateExpression
| YieldExpression | YieldExpression
| SpreadElement
| FunctionDeclaration | FunctionDeclaration
| VariableDeclaration | VariableDeclaration
| ClassDeclaration | ClassDeclaration
@ -615,7 +616,6 @@ declare abstract class BasicEvaluatedExpression {
| ArrayPattern | ArrayPattern
| RestElement | RestElement
| AssignmentPattern | AssignmentPattern
| SpreadElement
| Property | Property
| AssignmentProperty | AssignmentProperty
| ClassBody | ClassBody
@ -801,6 +801,7 @@ declare abstract class BasicEvaluatedExpression {
| ThisExpression | ThisExpression
| UpdateExpression | UpdateExpression
| YieldExpression | YieldExpression
| SpreadElement
| FunctionDeclaration | FunctionDeclaration
| VariableDeclaration | VariableDeclaration
| ClassDeclaration | ClassDeclaration
@ -838,7 +839,6 @@ declare abstract class BasicEvaluatedExpression {
| ArrayPattern | ArrayPattern
| RestElement | RestElement
| AssignmentPattern | AssignmentPattern
| SpreadElement
| Property | Property
| AssignmentProperty | AssignmentProperty
| ClassBody | ClassBody
@ -1334,7 +1334,11 @@ declare abstract class ChunkGroup {
hasBlock(block: AsyncDependenciesBlock): boolean; hasBlock(block: AsyncDependenciesBlock): boolean;
get blocksIterable(): Iterable<AsyncDependenciesBlock>; get blocksIterable(): Iterable<AsyncDependenciesBlock>;
addBlock(block: AsyncDependenciesBlock): boolean; addBlock(block: AsyncDependenciesBlock): boolean;
addOrigin(module: Module, loc: DependencyLocation, request: string): void; addOrigin(
module: null | Module,
loc: DependencyLocation,
request: string
): void;
getFiles(): string[]; getFiles(): string[];
remove(): void; remove(): void;
sortItems(): void; sortItems(): void;
@ -2118,7 +2122,7 @@ declare class Compilation {
executeModule( executeModule(
module: Module, module: Module,
options: ExecuteModuleOptions, options: ExecuteModuleOptions,
callback: (err?: null | WebpackError, result?: ExecuteModuleResult) => void callback: (err: null | WebpackError, result?: ExecuteModuleResult) => void
): void; ): void;
checkConstraints(): void; checkConstraints(): void;
factorizeModule: { factorizeModule: {
@ -2281,7 +2285,7 @@ declare class Compiler {
invalid: SyncHook<[null | string, number]>; invalid: SyncHook<[null | string, number]>;
watchClose: SyncHook<[]>; watchClose: SyncHook<[]>;
shutdown: AsyncSeriesHook<[]>; shutdown: AsyncSeriesHook<[]>;
infrastructureLog: SyncBailHook<[string, string, any[]], true>; infrastructureLog: SyncBailHook<[string, string, undefined | any[]], true>;
environment: SyncHook<[]>; environment: SyncHook<[]>;
afterEnvironment: SyncHook<[]>; afterEnvironment: SyncHook<[]>;
afterPlugins: SyncHook<[Compiler]>; afterPlugins: SyncHook<[Compiler]>;
@ -2313,7 +2317,11 @@ declare class Compiler {
>; >;
fsStartTime?: number; fsStartTime?: number;
resolverFactory: ResolverFactory; resolverFactory: ResolverFactory;
infrastructureLogger?: (arg0: string, arg1: LogTypeEnum, arg2: any[]) => void; infrastructureLogger?: (
arg0: string,
arg1: LogTypeEnum,
arg2?: any[]
) => void;
platform: Readonly<PlatformTargetProperties>; platform: Readonly<PlatformTargetProperties>;
options: WebpackOptionsNormalized; options: WebpackOptionsNormalized;
context: string; context: string;
@ -2773,9 +2781,7 @@ declare interface ConsumesConfig {
declare interface ConsumesObject { declare interface ConsumesObject {
[index: string]: string | ConsumesConfig; [index: string]: string | ConsumesConfig;
} }
type ContainerOptionsFormat<T> = type ContainerOptionsFormat<T> = Item<T> | (string | Item<T>)[];
| Record<string, string | string[] | T>
| (string | Record<string, string | string[] | T>)[];
declare class ContainerPlugin { declare class ContainerPlugin {
constructor(options: ContainerPluginOptions); constructor(options: ContainerPluginOptions);
@ -2839,8 +2845,12 @@ declare interface ContainerReferencePluginOptions {
*/ */
shareScope?: string; shareScope?: string;
} }
declare interface ContextAlternativeRequest {
context: string;
request: string;
}
declare abstract class ContextElementDependency extends ModuleDependency { declare abstract class ContextElementDependency extends ModuleDependency {
referencedExports?: string[][]; referencedExports?: null | string[][];
} }
declare class ContextExclusionPlugin { declare class ContextExclusionPlugin {
constructor(negativeMatcher: RegExp); constructor(negativeMatcher: RegExp);
@ -2876,12 +2886,12 @@ declare abstract class ContextModuleFactory extends ModuleFactory {
contextModuleFiles: SyncWaterfallHook<[string[]]>; contextModuleFiles: SyncWaterfallHook<[string[]]>;
alternatives: FakeHook< alternatives: FakeHook<
Pick< Pick<
AsyncSeriesWaterfallHook<[any[]]>, AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>,
"name" | "tap" | "tapAsync" | "tapPromise" "name" | "tap" | "tapAsync" | "tapPromise"
> >
>; >;
alternativeRequests: AsyncSeriesWaterfallHook< alternativeRequests: AsyncSeriesWaterfallHook<
[any[], ContextModuleOptions] [ContextAlternativeRequest[], ContextModuleOptions]
>; >;
}>; }>;
resolverFactory: ResolverFactory; resolverFactory: ResolverFactory;
@ -2889,7 +2899,7 @@ declare abstract class ContextModuleFactory extends ModuleFactory {
fs: InputFileSystem, fs: InputFileSystem,
options: ContextModuleOptions, options: ContextModuleOptions,
callback: ( callback: (
err?: null | Error, err: null | Error,
dependencies?: ContextElementDependency[] dependencies?: ContextElementDependency[]
) => any ) => any
): void; ): void;
@ -5509,6 +5519,9 @@ declare interface IntermediateFileSystemExtras {
) => void; ) => void;
} }
type InternalCell<T> = T | typeof TOMBSTONE | typeof UNDEFINED_MARKER; type InternalCell<T> = T | typeof TOMBSTONE | typeof UNDEFINED_MARKER;
declare interface Item<T> {
[index: string]: string | string[] | T;
}
declare abstract class ItemCacheFacade { declare abstract class ItemCacheFacade {
get<T>(callback: CallbackCacheCacheFacade<T>): void; get<T>(callback: CallbackCacheCacheFacade<T>): void;
getPromise<T>(): Promise<T>; getPromise<T>(): Promise<T>;
@ -5590,7 +5603,39 @@ declare class JavascriptParser extends Parser {
> >
>; >;
evaluate: HookMap< evaluate: HookMap<
SyncBailHook<[Expression], undefined | null | BasicEvaluatedExpression> SyncBailHook<
[
| UnaryExpression
| ArrayExpression
| ArrowFunctionExpression
| AssignmentExpression
| AwaitExpression
| BinaryExpression
| SimpleCallExpression
| NewExpression
| ChainExpression
| ClassExpression
| ConditionalExpression
| FunctionExpression
| Identifier
| ImportExpression
| SimpleLiteral
| RegExpLiteral
| BigIntLiteral
| LogicalExpression
| MemberExpression
| MetaProperty
| ObjectExpression
| SequenceExpression
| TaggedTemplateExpression
| TemplateLiteral
| ThisExpression
| UpdateExpression
| YieldExpression
| SpreadElement
],
undefined | null | BasicEvaluatedExpression
>
>; >;
evaluateIdentifier: HookMap< evaluateIdentifier: HookMap<
SyncBailHook< SyncBailHook<
@ -6426,7 +6471,37 @@ declare class JavascriptParser extends Parser {
enterArrayPattern(pattern: ArrayPattern, onIdent?: any): void; enterArrayPattern(pattern: ArrayPattern, onIdent?: any): void;
enterRestElement(pattern: RestElement, onIdent?: any): void; enterRestElement(pattern: RestElement, onIdent?: any): void;
enterAssignmentPattern(pattern: AssignmentPattern, onIdent?: any): void; enterAssignmentPattern(pattern: AssignmentPattern, onIdent?: any): void;
evaluateExpression(expression?: any): BasicEvaluatedExpression; evaluateExpression(
expression:
| UnaryExpression
| ArrayExpression
| ArrowFunctionExpression
| AssignmentExpression
| AwaitExpression
| BinaryExpression
| SimpleCallExpression
| NewExpression
| ChainExpression
| ClassExpression
| ConditionalExpression
| FunctionExpression
| Identifier
| ImportExpression
| SimpleLiteral
| RegExpLiteral
| BigIntLiteral
| LogicalExpression
| MemberExpression
| MetaProperty
| ObjectExpression
| SequenceExpression
| TaggedTemplateExpression
| TemplateLiteral
| ThisExpression
| UpdateExpression
| YieldExpression
| SpreadElement
): BasicEvaluatedExpression;
parseString(expression: Expression): string; parseString(expression: Expression): string;
parseCalculatedString(expression: Expression): any; parseCalculatedString(expression: Expression): any;
evaluate(source: string): BasicEvaluatedExpression; evaluate(source: string): BasicEvaluatedExpression;
@ -8178,8 +8253,7 @@ declare class Module extends DependenciesBlock {
used: any; used: any;
} }
declare class ModuleConcatenationPlugin { declare class ModuleConcatenationPlugin {
constructor(options?: any); constructor();
options: any;
/** /**
* Apply the plugin * Apply the plugin
@ -8948,10 +9022,15 @@ declare interface NormalModuleCompilationHooks {
beforeParse: SyncHook<[NormalModule]>; beforeParse: SyncHook<[NormalModule]>;
beforeSnapshot: SyncHook<[NormalModule]>; beforeSnapshot: SyncHook<[NormalModule]>;
readResourceForScheme: HookMap< readResourceForScheme: HookMap<
FakeHook<
AsyncSeriesBailHook<[string, NormalModule], null | string | Buffer> AsyncSeriesBailHook<[string, NormalModule], null | string | Buffer>
>
>; >;
readResource: HookMap< readResource: HookMap<
AsyncSeriesBailHook<[LoaderContextNormalModule<any>], string | Buffer> AsyncSeriesBailHook<
[LoaderContextNormalModule<any>],
null | string | Buffer
>
>; >;
needBuild: AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>; needBuild: AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>;
} }
@ -9743,7 +9822,7 @@ declare abstract class OptionsApply {
process(options?: any, compiler?: any): void; process(options?: any, compiler?: any): void;
} }
declare interface OriginRecord { declare interface OriginRecord {
module: Module; module: null | Module;
loc: DependencyLocation; loc: DependencyLocation;
request: string; request: string;
} }
@ -14667,7 +14746,7 @@ declare abstract class WebpackLogger {
status(...args: any[]): void; status(...args: any[]): void;
group(...args: any[]): void; group(...args: any[]): void;
groupCollapsed(...args: any[]): void; groupCollapsed(...args: any[]): void;
groupEnd(...args: any[]): void; groupEnd(): void;
profile(label?: string): void; profile(label?: string): void;
profileEnd(label?: string): void; profileEnd(label?: string): void;
time(label: string): void; time(label: string): void;