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
*/
function Message() {
/** @type {string} */
/** @type {string | undefined} */
this.stack = undefined;
Error.captureStackTrace(this);
/** @type {RegExpMatchArray} */
const match = this.stack.split("\n")[3].match(CURRENT_METHOD_REGEXP);
/** @type {RegExpMatchArray | null} */
const match =
/** @type {string} */
(/** @type {unknown} */ (this.stack))
.split("\n")[3]
.match(CURRENT_METHOD_REGEXP);
this.message = match && match[1] ? createMessage(match[1]) : createMessage();
}

View File

@ -22,7 +22,7 @@ const {
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {{id: number}} HasId */
/** @typedef {{module: Module, loc: DependencyLocation, request: string}} OriginRecord */
/** @typedef {{module: Module | null, loc: DependencyLocation, request: string}} OriginRecord */
/**
* @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 {string} request request name of the reference
* @returns {void}

View File

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

View File

@ -201,7 +201,7 @@ class Compiler {
/** @type {AsyncSeriesHook<[]>} */
shutdown: new AsyncSeriesHook([]),
/** @type {SyncBailHook<[string, string, any[]], true>} */
/** @type {SyncBailHook<[string, string, any[] | undefined], true>} */
infrastructureLog: new SyncBailHook(["origin", "type", "args"]),
// TODO the following hooks are weirdly located here
@ -1227,9 +1227,16 @@ ${other}`);
"done",
"thisCompilation"
].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("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Chunk").ChunkId} ChunkId */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
@ -86,7 +87,7 @@ const makeSerializable = require("./util/makeSerializable");
/**
* @callback ResolveDependenciesCallback
* @param {(Error | null)=} err
* @param {Error | null} err
* @param {ContextElementDependency[]=} dependencies
*/
@ -99,7 +100,7 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {1 | 3 | 7 | 9} FakeMapType */
/** @typedef {Map<string, string | number> | FakeMapType} FakeMap */
/** @typedef {Record<ModuleId, FakeMapType>} FakeMap */
const SNAPSHOT_OPTIONS = { timestamp: true };
@ -602,7 +603,7 @@ class ContextModule extends Module {
/**
* @param {Dependency[]} dependencies all dependencies
* @param {ChunkGraph} chunkGraph chunk graph
* @returns {FakeMap} fake map
* @returns {FakeMap | FakeMapType} fake map
*/
getFakeMap(dependencies, chunkGraph) {
if (!this.options.namespaceObject) {
@ -621,13 +622,14 @@ class ContextModule extends Module {
)
.filter(Boolean)
.sort(comparator);
/** @type {FakeMap} */
const fakeMap = Object.create(null);
for (const module of sortedModules) {
const exportsType = module.getExportsType(
moduleGraph,
this.options.namespaceObject === "strict"
);
const id = chunkGraph.getModuleId(module);
const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
switch (exportsType) {
case "namespace":
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
*/
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 {string=} fakeMapDataExpression fake map data expression
* @returns {string} module object source
@ -944,6 +946,10 @@ module.exports = webpackAsyncContext;`;
chunkGraph
);
const hasFakeMap = typeof fakeMap === "object";
/** @typedef {{userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock}} Item */
/**
* @type {Item[]}
*/
const items = blocks
.map(block => {
const dependency =
@ -974,18 +980,23 @@ module.exports = webpackAsyncContext;`;
if (a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1;
});
/** @type {Record<string, ModuleId | (ModuleId[] | ChunkId[])>} */
const map = Object.create(null);
for (const item of sortedItems) {
const moduleId = chunkGraph.getModuleId(item.module);
const moduleId =
/** @type {ModuleId} */
(chunkGraph.getModuleId(item.module));
if (shortMode) {
map[item.userRequest] = moduleId;
} else {
/** @type {(ModuleId | ChunkId)[]} */
const arrayStart = [moduleId];
if (hasFakeMap) {
arrayStart.push(fakeMap[moduleId]);
}
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
*/
getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) {
const id = chunkGraph.getModuleId(this);
const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this));
if (asyncMode === "lazy") {
if (this.blocks && this.blocks.length > 0) {
return this.getLazySource(this.blocks, id, {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,15 @@
"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
@ -17,6 +25,9 @@
* @returns {void}
*/
const process = (options, normalizeSimple, normalizeOptions, fn) => {
/**
* @param {(string | Item<T>)[]} items items
*/
const array = items => {
for (const item of items) {
if (typeof item === "string") {
@ -28,6 +39,9 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
}
}
};
/**
* @param {Item<T>} obj an object
*/
const object = obj => {
for (const [key, value] of Object.entries(obj)) {
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} functionRange function 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) {
super();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -39,7 +39,7 @@ const { registerNotSerializable } = require("../util/serialization");
/**
* @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
*/
@ -320,10 +320,10 @@ class LazyCompilationDependencyFactory extends ModuleFactory {
class LazyCompilationPlugin {
/**
* @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.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 }) {
this.backend = backend;
@ -338,6 +338,7 @@ class LazyCompilationPlugin {
* @returns {void}
*/
apply(compiler) {
/** @type {BackendApi} */
let backend;
compiler.hooks.beforeCompile.tapAsync(
"LazyCompilationPlugin",

View File

@ -5,15 +5,22 @@
"use strict";
/** @typedef {import("http").IncomingMessage} IncomingMessage */
/** @typedef {import("http").RequestListener} RequestListener */
/** @typedef {import("http").ServerOptions} HttpServerOptions */
/** @typedef {import("http").ServerResponse} ServerResponse */
/** @typedef {import("https").ServerOptions} HttpsServerOptions */
/** @typedef {import("net").AddressInfo} AddressInfo */
/** @typedef {import("net").Server} Server */
/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("./LazyCompilationPlugin").BackendApi} BackendApi */
/**
* @callback BackendHandler
* @param {Compiler} compiler compiler
* @param {function((Error | null)=, any=): void} callback callback
* @param {function(Error | null, BackendApi=): void} callback callback
* @returns {void}
*/
@ -36,8 +43,13 @@ module.exports = options => (compiler, callback) => {
? options.server
: (() => {
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 =
typeof options.listen === "function"
? options.listen
@ -50,7 +62,9 @@ module.exports = options => (compiler, callback) => {
const protocol = options.protocol || (isHttps ? "https" : "http");
/** @type {RequestListener} */
const requestListener = (req, res) => {
if (req.url === undefined) return;
const keys = req.url.slice(prefix.length).split("@");
req.socket.on("close", () => {
setTimeout(() => {
@ -85,7 +99,7 @@ module.exports = options => (compiler, callback) => {
if (moduleActivated && compiler.watching) compiler.watching.invalidate();
};
const server = /** @type {import("net").Server} */ (createServer());
const server = /** @type {Server} */ (createServer());
server.on("request", requestListener);
let isClosing = false;
@ -101,10 +115,19 @@ module.exports = options => (compiler, callback) => {
server.on("clientError", 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);
const addr = server.address();
if (typeof addr === "string") throw new Error("addr must not be a string");
const _addr = server.address();
if (typeof _addr === "string")
throw new Error("addr must not be a string");
const addr = /** @type {AddressInfo} */ (_addr);
const urlBase =
addr.address === "::" || addr.address === "0.0.0.0"
? `${protocol}://localhost:${addr.port}`
@ -129,7 +152,7 @@ module.exports = options => (compiler, callback) => {
module(originalModule) {
const key = `${encodeURIComponent(
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;
return {
client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
@ -138,6 +161,7 @@ module.exports = options => (compiler, callback) => {
};
}
});
});
}
);
listen(server);
};

View File

@ -204,7 +204,7 @@ const objectAndMembersToName = (object, membersReversed) => {
* [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
* 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
*/
const getRootName = expression => {
@ -248,7 +248,7 @@ class JavascriptParser extends Parser {
this.hooks = Object.freeze({
/** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | undefined | null>>} */
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"])),
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | undefined | null>>} */
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
@ -1212,7 +1212,7 @@ class JavascriptParser extends Parser {
});
/**
* @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}
*/
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
*/
evaluateExpression(expression) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,10 @@ const deprecationCache = new Map();
* @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
@ -84,8 +87,11 @@ module.exports.arrayToSetDeprecation = (set, name) => {
set[method] = function () {
d();
const array = Array.from(this);
return Array.prototype[/** @type {keyof COPY_METHODS} */ (method)].apply(
array,
// eslint-disable-next-line prefer-rest-params
return Array.prototype[method].apply(array, arguments);
arguments
);
};
}
const dPush = createDeprecation(
@ -191,12 +197,11 @@ module.exports.createArrayToSetDeprecationSet = name => {
};
/**
* @template T
* @param {object} obj object
* @param {string} name property name
* @param {string} code deprecation code
* @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 = "") => {
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;
declare interface BackendApi {
dispose: (arg0?: Error) => void;
dispose: (arg0: (arg0?: null | Error) => void) => void;
module: (arg0: Module) => { client: string; data: string; active: boolean };
}
declare class BannerPlugin {
@ -578,6 +578,7 @@ declare abstract class BasicEvaluatedExpression {
| ThisExpression
| UpdateExpression
| YieldExpression
| SpreadElement
| FunctionDeclaration
| VariableDeclaration
| ClassDeclaration
@ -615,7 +616,6 @@ declare abstract class BasicEvaluatedExpression {
| ArrayPattern
| RestElement
| AssignmentPattern
| SpreadElement
| Property
| AssignmentProperty
| ClassBody
@ -801,6 +801,7 @@ declare abstract class BasicEvaluatedExpression {
| ThisExpression
| UpdateExpression
| YieldExpression
| SpreadElement
| FunctionDeclaration
| VariableDeclaration
| ClassDeclaration
@ -838,7 +839,6 @@ declare abstract class BasicEvaluatedExpression {
| ArrayPattern
| RestElement
| AssignmentPattern
| SpreadElement
| Property
| AssignmentProperty
| ClassBody
@ -1334,7 +1334,11 @@ declare abstract class ChunkGroup {
hasBlock(block: AsyncDependenciesBlock): boolean;
get blocksIterable(): Iterable<AsyncDependenciesBlock>;
addBlock(block: AsyncDependenciesBlock): boolean;
addOrigin(module: Module, loc: DependencyLocation, request: string): void;
addOrigin(
module: null | Module,
loc: DependencyLocation,
request: string
): void;
getFiles(): string[];
remove(): void;
sortItems(): void;
@ -2118,7 +2122,7 @@ declare class Compilation {
executeModule(
module: Module,
options: ExecuteModuleOptions,
callback: (err?: null | WebpackError, result?: ExecuteModuleResult) => void
callback: (err: null | WebpackError, result?: ExecuteModuleResult) => void
): void;
checkConstraints(): void;
factorizeModule: {
@ -2281,7 +2285,7 @@ declare class Compiler {
invalid: SyncHook<[null | string, number]>;
watchClose: SyncHook<[]>;
shutdown: AsyncSeriesHook<[]>;
infrastructureLog: SyncBailHook<[string, string, any[]], true>;
infrastructureLog: SyncBailHook<[string, string, undefined | any[]], true>;
environment: SyncHook<[]>;
afterEnvironment: SyncHook<[]>;
afterPlugins: SyncHook<[Compiler]>;
@ -2313,7 +2317,11 @@ declare class Compiler {
>;
fsStartTime?: number;
resolverFactory: ResolverFactory;
infrastructureLogger?: (arg0: string, arg1: LogTypeEnum, arg2: any[]) => void;
infrastructureLogger?: (
arg0: string,
arg1: LogTypeEnum,
arg2?: any[]
) => void;
platform: Readonly<PlatformTargetProperties>;
options: WebpackOptionsNormalized;
context: string;
@ -2773,9 +2781,7 @@ declare interface ConsumesConfig {
declare interface ConsumesObject {
[index: string]: string | ConsumesConfig;
}
type ContainerOptionsFormat<T> =
| Record<string, string | string[] | T>
| (string | Record<string, string | string[] | T>)[];
type ContainerOptionsFormat<T> = Item<T> | (string | Item<T>)[];
declare class ContainerPlugin {
constructor(options: ContainerPluginOptions);
@ -2839,8 +2845,12 @@ declare interface ContainerReferencePluginOptions {
*/
shareScope?: string;
}
declare interface ContextAlternativeRequest {
context: string;
request: string;
}
declare abstract class ContextElementDependency extends ModuleDependency {
referencedExports?: string[][];
referencedExports?: null | string[][];
}
declare class ContextExclusionPlugin {
constructor(negativeMatcher: RegExp);
@ -2876,12 +2886,12 @@ declare abstract class ContextModuleFactory extends ModuleFactory {
contextModuleFiles: SyncWaterfallHook<[string[]]>;
alternatives: FakeHook<
Pick<
AsyncSeriesWaterfallHook<[any[]]>,
AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>,
"name" | "tap" | "tapAsync" | "tapPromise"
>
>;
alternativeRequests: AsyncSeriesWaterfallHook<
[any[], ContextModuleOptions]
[ContextAlternativeRequest[], ContextModuleOptions]
>;
}>;
resolverFactory: ResolverFactory;
@ -2889,7 +2899,7 @@ declare abstract class ContextModuleFactory extends ModuleFactory {
fs: InputFileSystem,
options: ContextModuleOptions,
callback: (
err?: null | Error,
err: null | Error,
dependencies?: ContextElementDependency[]
) => any
): void;
@ -5509,6 +5519,9 @@ declare interface IntermediateFileSystemExtras {
) => void;
}
type InternalCell<T> = T | typeof TOMBSTONE | typeof UNDEFINED_MARKER;
declare interface Item<T> {
[index: string]: string | string[] | T;
}
declare abstract class ItemCacheFacade {
get<T>(callback: CallbackCacheCacheFacade<T>): void;
getPromise<T>(): Promise<T>;
@ -5590,7 +5603,39 @@ declare class JavascriptParser extends Parser {
>
>;
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<
SyncBailHook<
@ -6426,7 +6471,37 @@ declare class JavascriptParser extends Parser {
enterArrayPattern(pattern: ArrayPattern, onIdent?: any): void;
enterRestElement(pattern: RestElement, 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;
parseCalculatedString(expression: Expression): any;
evaluate(source: string): BasicEvaluatedExpression;
@ -8178,8 +8253,7 @@ declare class Module extends DependenciesBlock {
used: any;
}
declare class ModuleConcatenationPlugin {
constructor(options?: any);
options: any;
constructor();
/**
* Apply the plugin
@ -8948,10 +9022,15 @@ declare interface NormalModuleCompilationHooks {
beforeParse: SyncHook<[NormalModule]>;
beforeSnapshot: SyncHook<[NormalModule]>;
readResourceForScheme: HookMap<
FakeHook<
AsyncSeriesBailHook<[string, NormalModule], null | string | Buffer>
>
>;
readResource: HookMap<
AsyncSeriesBailHook<[LoaderContextNormalModule<any>], string | Buffer>
AsyncSeriesBailHook<
[LoaderContextNormalModule<any>],
null | string | Buffer
>
>;
needBuild: AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>;
}
@ -9743,7 +9822,7 @@ declare abstract class OptionsApply {
process(options?: any, compiler?: any): void;
}
declare interface OriginRecord {
module: Module;
module: null | Module;
loc: DependencyLocation;
request: string;
}
@ -14667,7 +14746,7 @@ declare abstract class WebpackLogger {
status(...args: any[]): void;
group(...args: any[]): void;
groupCollapsed(...args: any[]): void;
groupEnd(...args: any[]): void;
groupEnd(): void;
profile(label?: string): void;
profileEnd(label?: string): void;
time(label: string): void;