fix: types

This commit is contained in:
alexander.akait 2024-02-22 17:20:17 +03:00
parent a1f46a9ac3
commit 6ab9bdaa73
29 changed files with 650 additions and 233 deletions

9
declarations.d.ts vendored
View File

@ -135,6 +135,7 @@ declare module "@webassemblyjs/ast" {
): void; ): void;
export class NodePath<T> { export class NodePath<T> {
node: T; node: T;
remove(): void;
} }
export class Node {} export class Node {}
export class Identifier extends Node { export class Identifier extends Node {
@ -148,6 +149,7 @@ declare module "@webassemblyjs/ast" {
valtype?: string; valtype?: string;
id?: Identifier; id?: Identifier;
signature?: Signature; signature?: Signature;
mutability: string;
} }
export class ModuleImport extends Node { export class ModuleImport extends Node {
module: string; module: string;
@ -171,6 +173,7 @@ declare module "@webassemblyjs/ast" {
export class FloatLiteral extends Node {} export class FloatLiteral extends Node {}
export class GlobalType extends Node { export class GlobalType extends Node {
valtype: string; valtype: string;
mutability: string;
} }
export class Global extends Node { export class Global extends Node {
init: Instruction[]; init: Instruction[];
@ -214,9 +217,9 @@ declare module "@webassemblyjs/ast" {
init: Node[] init: Node[]
): ObjectInstruction; ): ObjectInstruction;
export function signature(params: FuncParam[], results: string[]): Signature; export function signature(params: FuncParam[], results: string[]): Signature;
export function func(initFuncId, signature: Signature, funcBody): Func; export function func(initFuncId: Identifier, signature: Signature, funcBody: Instruction[]): Func;
export function typeInstruction( export function typeInstruction(
id: Identifier, id: Identifier | undefined,
functype: Signature functype: Signature
): TypeInstruction; ): TypeInstruction;
export function indexInFuncSection(index: Index): IndexInFuncSection; export function indexInFuncSection(index: Index): IndexInFuncSection;
@ -229,7 +232,7 @@ declare module "@webassemblyjs/ast" {
index: Index index: Index
): ModuleExportDescr; ): ModuleExportDescr;
export function getSectionMetadata(ast: any, section: string); export function getSectionMetadata(ast: any, section: string): { vectorOfSize: { value: number } };
export class FuncSignature { export class FuncSignature {
args: string[]; args: string[];
result: string[]; result: string[];

View File

@ -33,6 +33,11 @@ const {
* @returns {void} * @returns {void}
*/ */
/**
* @param {number} times times
* @param {function(Error=): void} callback callback
* @returns {function(Error=): void} callback
*/
const needCalls = (times, callback) => { const needCalls = (times, callback) => {
return err => { return err => {
if (--times === 0) { if (--times === 0) {
@ -71,6 +76,7 @@ class Cache {
* @returns {void} * @returns {void}
*/ */
get(identifier, etag, callback) { get(identifier, etag, callback) {
/** @type {GotHandler[]} */
const gotHandlers = []; const gotHandlers = [];
this.hooks.get.callAsync(identifier, etag, gotHandlers, (err, result) => { this.hooks.get.callAsync(identifier, etag, gotHandlers, (err, result) => {
if (err) { if (err) {

View File

@ -103,6 +103,7 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ /** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./ModuleFactory")} ModuleFactory */ /** @typedef {import("./ModuleFactory")} ModuleFactory */
/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */
/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */ /** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
/** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./RequestShortener")} RequestShortener */
@ -113,9 +114,13 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */
/** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/Hash")} Hash */
/** @template T @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T> */ /**
* @template T
* @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T>
*/
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
/** @typedef {WeakMap<Dependency, Module>} References */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** /**
* @callback Callback * @callback Callback
* @param {(WebpackError | null)=} err * @param {(WebpackError | null)=} err
@ -824,7 +829,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
/** @type {AsyncSeriesHook<[CompilationAssets]>} */ /** @type {AsyncSeriesHook<[CompilationAssets]>} */
processAdditionalAssets: new AsyncSeriesHook(["assets"]), processAdditionalAssets: new AsyncSeriesHook(["assets"]),
/** @type {SyncBailHook<[], boolean>} */ /** @type {SyncBailHook<[], boolean | undefined>} */
needAdditionalSeal: new SyncBailHook([]), needAdditionalSeal: new SyncBailHook([]),
/** @type {AsyncSeriesHook<[]>} */ /** @type {AsyncSeriesHook<[]>} */
afterSeal: new AsyncSeriesHook([]), afterSeal: new AsyncSeriesHook([]),
@ -878,7 +883,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
}); });
/** @type {string=} */ /** @type {string=} */
this.name = undefined; this.name = undefined;
/** @type {number | undefined} */
this.startTime = undefined; this.startTime = undefined;
/** @type {number | undefined} */
this.endTime = undefined; this.endTime = undefined;
/** @type {Compiler} */ /** @type {Compiler} */
this.compiler = compiler; this.compiler = compiler;
@ -1345,6 +1352,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @returns {void} * @returns {void}
*/ */
_buildModule(module, callback) { _buildModule(module, callback) {
/** @type {ModuleProfile | undefined} */
const currentProfile = this.profile const currentProfile = this.profile
? this.moduleGraph.getProfile(module) ? this.moduleGraph.getProfile(module)
: undefined; : undefined;
@ -1375,7 +1383,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.options, this.options,
this, this,
this.resolverFactory.get("normal", module.resolveOptions), this.resolverFactory.get("normal", module.resolveOptions),
this.inputFileSystem, /** @type {InputFileSystem} */ (this.inputFileSystem),
err => { err => {
if (currentProfile !== undefined) { if (currentProfile !== undefined) {
currentProfile.markBuildingEnd(); currentProfile.markBuildingEnd();
@ -1418,6 +1426,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @returns {void} * @returns {void}
*/ */
processModuleDependenciesNonRecursive(module) { processModuleDependenciesNonRecursive(module) {
/**
* @param {DependenciesBlock} block block
*/
const processDependenciesBlock = block => { const processDependenciesBlock = block => {
if (block.dependencies) { if (block.dependencies) {
let i = 0; let i = 0;
@ -1494,6 +1505,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
if (--inProgressTransitive === 0) onTransitiveTasksFinished(); if (--inProgressTransitive === 0) onTransitiveTasksFinished();
}; };
/**
* @param {WebpackError=} err error
* @returns {void}
*/
const onTransitiveTasksFinished = err => { const onTransitiveTasksFinished = err => {
if (err) return callback(err); if (err) return callback(err);
this.processDependenciesQueue.decreaseParallelism(); this.processDependenciesQueue.decreaseParallelism();
@ -2264,6 +2279,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
}); });
} }
/**
* @private
* @param {Module[]} modules modules
*/
_computeAffectedModules(modules) { _computeAffectedModules(modules) {
const moduleMemCacheCache = this.compiler.moduleMemCaches; const moduleMemCacheCache = this.compiler.moduleMemCaches;
if (!moduleMemCacheCache) return; if (!moduleMemCacheCache) return;
@ -2280,8 +2299,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
let statReferencesChanged = 0; let statReferencesChanged = 0;
let statWithoutBuild = 0; let statWithoutBuild = 0;
/**
* @param {Module} module module
* @returns {References | undefined} references
*/
const computeReferences = module => { const computeReferences = module => {
/** @type {WeakMap<Dependency, Module>} */ /** @type {References | undefined} */
let references = undefined; let references = undefined;
for (const connection of moduleGraph.getOutgoingConnections(module)) { for (const connection of moduleGraph.getOutgoingConnections(module)) {
const d = connection.dependency; const d = connection.dependency;
@ -2295,7 +2318,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
/** /**
* @param {Module} module the module * @param {Module} module the module
* @param {WeakMap<Dependency, Module>} references references * @param {References | undefined} references references
* @returns {boolean} true, when the references differ * @returns {boolean} true, when the references differ
*/ */
const compareReferences = (module, references) => { const compareReferences = (module, references) => {
@ -2367,6 +2390,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
} }
} }
/**
* @param {readonly ModuleGraphConnection[]} connections connections
* @returns {symbol|boolean} result
*/
const reduceAffectType = connections => { const reduceAffectType = connections => {
let affected = false; let affected = false;
for (const { dependency } of connections) { for (const { dependency } of connections) {
@ -2897,12 +2924,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
Entrypoints that depend on other entrypoints do not have their own runtime. Entrypoints that depend on other entrypoints do not have their own runtime.
They will use the runtime(s) from referenced entrypoints instead. They will use the runtime(s) from referenced entrypoints instead.
Remove the 'runtime' option from the entrypoint.`); Remove the 'runtime' option from the entrypoint.`);
const entry = this.entrypoints.get(name); const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
err.chunk = entry.getEntrypointChunk(); err.chunk = entry.getEntrypointChunk();
this.errors.push(err); this.errors.push(err);
} }
if (dependOn) { if (dependOn) {
const entry = this.entrypoints.get(name); const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
const referencedChunks = entry const referencedChunks = entry
.getEntrypointChunk() .getEntrypointChunk()
.getAllReferencedChunks(); .getAllReferencedChunks();
@ -2930,7 +2957,7 @@ Remove the 'runtime' option from the entrypoint.`);
connectChunkGroupParentAndChild(dependency, entry); connectChunkGroupParentAndChild(dependency, entry);
} }
} else if (runtime) { } else if (runtime) {
const entry = this.entrypoints.get(name); const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
let chunk = this.namedChunks.get(runtime); let chunk = this.namedChunks.get(runtime);
if (chunk) { if (chunk) {
if (!runtimeChunks.has(chunk)) { if (!runtimeChunks.has(chunk)) {
@ -2941,7 +2968,9 @@ Did you mean to use 'dependOn: ${JSON.stringify(
runtime runtime
)}' instead to allow using entrypoint '${name}' within the runtime of entrypoint '${runtime}'? For this '${runtime}' must always be loaded when '${name}' is used. )}' instead to allow using entrypoint '${name}' within the runtime of entrypoint '${runtime}'? For this '${runtime}' must always be loaded when '${name}' is used.
Or do you want to use the entrypoints '${name}' and '${runtime}' independently on the same page with a shared runtime? In this case give them both the same value for the 'runtime' option. It must be a name not already used by an entrypoint.`); Or do you want to use the entrypoints '${name}' and '${runtime}' independently on the same page with a shared runtime? In this case give them both the same value for the 'runtime' option. It must be a name not already used by an entrypoint.`);
const entryChunk = entry.getEntrypointChunk(); const entryChunk =
/** @type {Chunk} */
(entry.getEntrypointChunk());
err.chunk = entryChunk; err.chunk = entryChunk;
this.errors.push(err); this.errors.push(err);
entry.setRuntimeChunk(entryChunk); entry.setRuntimeChunk(entryChunk);
@ -4589,6 +4618,10 @@ This prevents using hashes of each other and should be avoided.`);
let assetInfo; let assetInfo;
let inTry = true; let inTry = true;
/**
* @param {Error} err error
* @returns {void}
*/
const errorAndCallback = err => { const errorAndCallback = err => {
const filename = const filename =
file || file ||
@ -5101,7 +5134,8 @@ This prevents using hashes of each other and should be avoided.`);
chunk chunk
)) { )) {
__webpack_require_module__( __webpack_require_module__(
moduleArgumentsMap.get(runtimeModule) /** @type {ExecuteModuleArgument} */
(moduleArgumentsMap.get(runtimeModule))
); );
} }
exports = __webpack_require__(module.identifier()); exports = __webpack_require__(module.identifier());

View File

@ -40,11 +40,13 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */
/** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Compilation").References} References */
/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ /** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
/** @typedef {import("./Module")} Module */ /** @typedef {import("./Module")} Module */
/** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */ /** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */
/** @typedef {import("./util/WeakTupleMap")} WeakTupleMap */ /** @typedef {import("./util/WeakTupleMap")} WeakTupleMap */
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */ /** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
@ -86,6 +88,9 @@ const { isSourceEqual } = require("./util/source");
* @property {string} targetPath * @property {string} targetPath
*/ */
/** @typedef {{ sizeOnlySource: SizeOnlySource | undefined, writtenTo: Map<string, number> }} CacheEntry */
/** @typedef {{ path: string, source: Source, size: number | undefined, waiting: ({ cacheEntry: any, file: string }[] | undefined) }} SimilarEntry */
/** /**
* @param {string[]} array an array * @param {string[]} array an array
* @returns {boolean} true, if the array is sorted * @returns {boolean} true, if the array is sorted
@ -98,11 +103,12 @@ const isSorted = array => {
}; };
/** /**
* @param {Object} obj an object * @param {Object<string, any>} obj an object
* @param {string[]} keys the keys of the object * @param {string[]} keys the keys of the object
* @returns {Object} the object with properties sorted by property name * @returns {Object<string, any>} the object with properties sorted by property name
*/ */
const sortObject = (obj, keys) => { const sortObject = (obj, keys) => {
/** @type {Object<string, any>} */
const o = {}; const o = {};
for (const k of keys.sort()) { for (const k of keys.sort()) {
o[k] = obj[k]; o[k] = obj[k];
@ -208,9 +214,9 @@ class Compiler {
this.webpack = webpack; this.webpack = webpack;
/** @type {string=} */ /** @type {string | undefined} */
this.name = undefined; this.name = undefined;
/** @type {Compilation=} */ /** @type {Compilation | undefined} */
this.parentCompilation = undefined; this.parentCompilation = undefined;
/** @type {Compiler} */ /** @type {Compiler} */
this.root = this; this.root = this;
@ -219,19 +225,20 @@ class Compiler {
/** @type {Watching | undefined} */ /** @type {Watching | undefined} */
this.watching = undefined; this.watching = undefined;
/** @type {OutputFileSystem} */ /** @type {OutputFileSystem | null} */
this.outputFileSystem = null; this.outputFileSystem = null;
/** @type {IntermediateFileSystem} */ /** @type {IntermediateFileSystem | null} */
this.intermediateFileSystem = null; this.intermediateFileSystem = null;
/** @type {InputFileSystem} */ /** @type {InputFileSystem | null} */
this.inputFileSystem = null; this.inputFileSystem = null;
/** @type {WatchFileSystem} */ /** @type {WatchFileSystem | null} */
this.watchFileSystem = null; this.watchFileSystem = null;
/** @type {string|null} */ /** @type {string|null} */
this.recordsInputPath = null; this.recordsInputPath = null;
/** @type {string|null} */ /** @type {string|null} */
this.recordsOutputPath = null; this.recordsOutputPath = null;
/** @type {Record<string, Record<number, TODO>>} */
this.records = {}; this.records = {};
/** @type {Set<string | RegExp>} */ /** @type {Set<string | RegExp>} */
this.managedPaths = new Set(); this.managedPaths = new Set();
@ -265,7 +272,7 @@ class Compiler {
this.cache = new Cache(); this.cache = new Cache();
/** @type {Map<Module, { buildInfo: object, references: WeakMap<Dependency, Module>, memCache: WeakTupleMap }> | undefined} */ /** @type {Map<Module, { buildInfo: object, references: References | undefined, memCache: WeakTupleMap }> | undefined} */
this.moduleMemCaches = undefined; this.moduleMemCaches = undefined;
this.compilerPath = ""; this.compilerPath = "";
@ -286,7 +293,7 @@ class Compiler {
/** @type {NormalModuleFactory | undefined} */ /** @type {NormalModuleFactory | undefined} */
this._lastNormalModuleFactory = undefined; this._lastNormalModuleFactory = undefined;
/** @private @type {WeakMap<Source, { sizeOnlySource: SizeOnlySource, writtenTo: Map<string, number> }>} */ /** @private @type {WeakMap<Source, CacheEntry>} */
this._assetEmittingSourceCache = new WeakMap(); this._assetEmittingSourceCache = new WeakMap();
/** @private @type {Map<string, number>} */ /** @private @type {Map<string, number>} */
this._assetEmittingWrittenFiles = new Map(); this._assetEmittingWrittenFiles = new Map();
@ -645,8 +652,13 @@ class Compiler {
* @returns {void} * @returns {void}
*/ */
emitAssets(compilation, callback) { emitAssets(compilation, callback) {
/** @type {string} */
let outputPath; let outputPath;
/**
* @param {Error=} err error
* @returns {void}
*/
const emitFiles = err => { const emitFiles = err => {
if (err) return callback(err); if (err) return callback(err);
@ -676,10 +688,15 @@ class Compiler {
includesHash(targetFile, info.fullhash)); includesHash(targetFile, info.fullhash));
} }
/**
* @param {Error=} err error
* @returns {void}
*/
const writeOut = err => { const writeOut = err => {
if (err) return callback(err); if (err) return callback(err);
const targetPath = join( const targetPath = join(
this.outputFileSystem, /** @type {OutputFileSystem} */
(this.outputFileSystem),
outputPath, outputPath,
targetFile targetFile
); );
@ -699,6 +716,7 @@ class Compiler {
this._assetEmittingSourceCache.set(source, cacheEntry); this._assetEmittingSourceCache.set(source, cacheEntry);
} }
/** @type {SimilarEntry | undefined} */
let similarEntry; let similarEntry;
const checkSimilarFile = () => { const checkSimilarFile = () => {
@ -762,9 +780,11 @@ ${other}`);
if (targetFileGeneration === undefined) { if (targetFileGeneration === undefined) {
const newGeneration = 1; const newGeneration = 1;
this._assetEmittingWrittenFiles.set(targetPath, newGeneration); this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
cacheEntry.writtenTo.set(targetPath, newGeneration); /** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, newGeneration);
} else { } else {
cacheEntry.writtenTo.set(targetPath, targetFileGeneration); /** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, targetFileGeneration);
} }
callback(); callback();
}; };
@ -775,7 +795,8 @@ ${other}`);
* @returns {void} * @returns {void}
*/ */
const doWrite = content => { const doWrite = content => {
this.outputFileSystem.writeFile(targetPath, content, err => { /** @type {OutputFileSystem} */
(this.outputFileSystem).writeFile(targetPath, content, err => {
if (err) return callback(err); if (err) return callback(err);
// information marker that the asset has been emitted // information marker that the asset has been emitted
@ -786,7 +807,8 @@ ${other}`);
targetFileGeneration === undefined targetFileGeneration === undefined
? 1 ? 1
: targetFileGeneration + 1; : targetFileGeneration + 1;
cacheEntry.writtenTo.set(targetPath, newGeneration); /** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, newGeneration);
this._assetEmittingWrittenFiles.set(targetPath, newGeneration); this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
this.hooks.assetEmitted.callAsync( this.hooks.assetEmitted.callAsync(
file, file,
@ -802,16 +824,33 @@ ${other}`);
}); });
}; };
/**
* @param {number} size size
*/
const updateWithReplacementSource = size => { const updateWithReplacementSource = size => {
updateFileWithReplacementSource(file, cacheEntry, size); updateFileWithReplacementSource(
similarEntry.size = size; file,
if (similarEntry.waiting !== undefined) { /** @type {CacheEntry} */ (cacheEntry),
for (const { file, cacheEntry } of similarEntry.waiting) { size
);
/** @type {SimilarEntry} */
(similarEntry).size = size;
if (
/** @type {SimilarEntry} */ (similarEntry).waiting !== undefined
) {
for (const { file, cacheEntry } of /** @type {SimilarEntry} */ (
similarEntry
).waiting) {
updateFileWithReplacementSource(file, cacheEntry, size); updateFileWithReplacementSource(file, cacheEntry, size);
} }
} }
}; };
/**
* @param {string} file file
* @param {CacheEntry} cacheEntry cache entry
* @param {number} size size
*/
const updateFileWithReplacementSource = ( const updateFileWithReplacementSource = (
file, file,
cacheEntry, cacheEntry,
@ -828,6 +867,10 @@ ${other}`);
}); });
}; };
/**
* @param {IStats} stats stats
* @returns {void}
*/
const processExistingFile = stats => { const processExistingFile = stats => {
// skip emitting if it's already there and an immutable file // skip emitting if it's already there and an immutable file
if (immutable) { if (immutable) {
@ -874,7 +917,9 @@ ${other}`);
// if the target file has already been written // if the target file has already been written
if (targetFileGeneration !== undefined) { if (targetFileGeneration !== undefined) {
// check if the Source has been written to this target file // check if the Source has been written to this target file
const writtenGeneration = cacheEntry.writtenTo.get(targetPath); const writtenGeneration = /** @type {CacheEntry} */ (
cacheEntry
).writtenTo.get(targetPath);
if (writtenGeneration === targetFileGeneration) { if (writtenGeneration === targetFileGeneration) {
// if yes, we may skip writing the file // if yes, we may skip writing the file
// if it's already there // if it's already there
@ -882,9 +927,15 @@ ${other}`);
if (this._assetEmittingPreviousFiles.has(targetPath)) { if (this._assetEmittingPreviousFiles.has(targetPath)) {
// We assume that assets from the last compilation say intact on disk (they are not removed) // We assume that assets from the last compilation say intact on disk (they are not removed)
compilation.updateAsset(file, cacheEntry.sizeOnlySource, { compilation.updateAsset(
size: cacheEntry.sizeOnlySource.size() file,
}); /** @type {CacheEntry} */ (cacheEntry).sizeOnlySource,
{
size:
/** @type {CacheEntry} */
(cacheEntry).sizeOnlySource.size()
}
);
return callback(); return callback();
} else { } else {
@ -903,10 +954,10 @@ ${other}`);
if (checkSimilarFile()) return; if (checkSimilarFile()) return;
if (this.options.output.compareBeforeEmit) { if (this.options.output.compareBeforeEmit) {
this.outputFileSystem.stat(targetPath, (err, stats) => { this.outputFileSystem.stat(targetPath, (err, stats) => {
const exists = !err && stats.isFile(); const exists = !err && /** @type {IStats} */ (stats).isFile();
if (exists) { if (exists) {
processExistingFile(stats); processExistingFile(/** @type {IStats} */ (stats));
} else { } else {
processMissingFile(); processMissingFile();
} }
@ -917,7 +968,7 @@ ${other}`);
}; };
if (targetFile.match(/\/|\\/)) { if (targetFile.match(/\/|\\/)) {
const fs = this.outputFileSystem; const fs = /** @type {OutputFileSystem} */ (this.outputFileSystem);
const dir = dirname(fs, join(fs, outputPath, targetFile)); const dir = dirname(fs, join(fs, outputPath, targetFile));
mkdirp(fs, dir, writeOut); mkdirp(fs, dir, writeOut);
} else { } else {
@ -946,7 +997,11 @@ ${other}`);
this.hooks.emit.callAsync(compilation, err => { this.hooks.emit.callAsync(compilation, err => {
if (err) return callback(err); if (err) return callback(err);
outputPath = compilation.getPath(this.outputPath, {}); outputPath = compilation.getPath(this.outputPath, {});
mkdirp(this.outputFileSystem, outputPath, emitFiles); mkdirp(
/** @type {OutputFileSystem} */ (this.outputFileSystem),
outputPath,
emitFiles
);
}); });
} }
@ -982,7 +1037,8 @@ ${other}`);
*/ */
_emitRecords(callback) { _emitRecords(callback) {
const writeFile = () => { const writeFile = () => {
this.outputFileSystem.writeFile( /** @type {OutputFileSystem} */
(this.outputFileSystem).writeFile(
/** @type {string} */ (this.recordsOutputPath), /** @type {string} */ (this.recordsOutputPath),
JSON.stringify( JSON.stringify(
this.records, this.records,
@ -1006,16 +1062,20 @@ ${other}`);
}; };
const recordsOutputPathDirectory = dirname( const recordsOutputPathDirectory = dirname(
this.outputFileSystem, /** @type {OutputFileSystem} */ (this.outputFileSystem),
/** @type {string} */ (this.recordsOutputPath) /** @type {string} */ (this.recordsOutputPath)
); );
if (!recordsOutputPathDirectory) { if (!recordsOutputPathDirectory) {
return writeFile(); return writeFile();
} }
mkdirp(this.outputFileSystem, recordsOutputPathDirectory, err => { mkdirp(
if (err) return callback(err); /** @type {OutputFileSystem} */ (this.outputFileSystem),
writeFile(); recordsOutputPathDirectory,
}); err => {
if (err) return callback(err);
writeFile();
}
);
} }
/** /**
@ -1055,12 +1115,14 @@ ${other}`);
this.records = {}; this.records = {};
return callback(); return callback();
} }
this.inputFileSystem.stat(this.recordsInputPath, err => { /** @type {InputFileSystem} */
(this.inputFileSystem).stat(this.recordsInputPath, err => {
// It doesn't exist // It doesn't exist
// We can ignore this. // We can ignore this.
if (err) return callback(); if (err) return callback();
this.inputFileSystem.readFile( /** @type {InputFileSystem} */
(this.inputFileSystem).readFile(
/** @type {string} */ (this.recordsInputPath), /** @type {string} */ (this.recordsInputPath),
(err, content) => { (err, content) => {
if (err) return callback(err); if (err) return callback(err);

View File

@ -80,6 +80,8 @@ const memoize = require("./util/memoize");
* @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true * @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true
*/ */
/** @typedef {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} GetConditionFn */
const TRANSITIVE = Symbol("transitive"); const TRANSITIVE = Symbol("transitive");
const getIgnoredModule = memoize(() => { const getIgnoredModule = memoize(() => {
@ -235,7 +237,7 @@ class Dependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return null; return null;

View File

@ -48,6 +48,7 @@ class DllModule extends Module {
super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, context); super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, context);
// Info from Factory // Info from Factory
/** @type {Dependency[]} */
this.dependencies = dependencies; this.dependencies = dependencies;
this.name = name; this.name = name;
} }

View File

@ -89,13 +89,16 @@ const getConnectionsByModule = set => {
return map; return map;
}; };
/** @typedef {SortableSet<ModuleGraphConnection>} IncomingConnections */
/** @typedef {SortableSet<ModuleGraphConnection>} OutgoingConnections */
class ModuleGraphModule { class ModuleGraphModule {
constructor() { constructor() {
/** @type {SortableSet<ModuleGraphConnection>} */ /** @type {IncomingConnections} */
this.incomingConnections = new SortableSet(); this.incomingConnections = new SortableSet();
/** @type {SortableSet<ModuleGraphConnection> | undefined} */ /** @type {OutgoingConnections | undefined} */
this.outgoingConnections = undefined; this.outgoingConnections = undefined;
/** @type {Module | null} */ /** @type {Module | null | undefined} */
this.issuer = undefined; this.issuer = undefined;
/** @type {(string | OptimizationBailoutFunction)[]} */ /** @type {(string | OptimizationBailoutFunction)[]} */
this.optimizationBailout = []; this.optimizationBailout = [];
@ -111,27 +114,43 @@ class ModuleGraphModule {
this.profile = undefined; this.profile = undefined;
/** @type {boolean} */ /** @type {boolean} */
this.async = false; this.async = false;
/** @type {ModuleGraphConnection[]} */ /** @type {ModuleGraphConnection[] | undefined} */
this._unassignedConnections = undefined; this._unassignedConnections = undefined;
} }
} }
class ModuleGraph { class ModuleGraph {
constructor() { constructor() {
/** @type {WeakMap<Dependency, ModuleGraphConnection | null>} */ /**
* @type {WeakMap<Dependency, ModuleGraphConnection | null>}
* @private
*/
this._dependencyMap = new WeakMap(); this._dependencyMap = new WeakMap();
/** @type {Map<Module, ModuleGraphModule>} */ /**
* @type {Map<Module, ModuleGraphModule>}
* @private
*/
this._moduleMap = new Map(); this._moduleMap = new Map();
/** @type {WeakMap<any, Object>} */ /**
* @type {WeakMap<any, Object>}
* @private
*/
this._metaMap = new WeakMap(); this._metaMap = new WeakMap();
/**
/** @type {WeakTupleMap<any[], any> | undefined} */ * @type {WeakTupleMap<any[], any> | undefined}
* @private
*/
this._cache = undefined; this._cache = undefined;
/**
/** @type {Map<Module, WeakTupleMap<any, any>>} */ * @type {Map<Module, WeakTupleMap<any, any>> | undefined}
* @private
*/
this._moduleMemCaches = undefined; this._moduleMemCaches = undefined;
/** @type {string | undefined} */ /**
* @type {string | undefined}
* @private
*/
this._cacheStage = undefined; this._cacheStage = undefined;
} }
@ -163,7 +182,7 @@ class ModuleGraph {
/** /**
* @param {Dependency} dependency the dependency * @param {Dependency} dependency the dependency
* @returns {Module} parent module * @returns {Module | undefined} parent module
*/ */
getParentModule(dependency) { getParentModule(dependency) {
return dependency._parentModule; return dependency._parentModule;
@ -171,7 +190,7 @@ class ModuleGraph {
/** /**
* @param {Dependency} dependency the dependency * @param {Dependency} dependency the dependency
* @returns {DependenciesBlock} parent block * @returns {DependenciesBlock | undefined} parent block
*/ */
getParentBlock(dependency) { getParentBlock(dependency) {
return dependency._parentDependenciesBlock; return dependency._parentDependenciesBlock;
@ -231,8 +250,11 @@ class ModuleGraph {
newConnection.module = module; newConnection.module = module;
this._dependencyMap.set(dependency, newConnection); this._dependencyMap.set(dependency, newConnection);
connection.setActive(false); connection.setActive(false);
const originMgm = this._getModuleGraphModule(connection.originModule); const originMgm = this._getModuleGraphModule(
originMgm.outgoingConnections.add(newConnection); /** @type {Module} */ (connection.originModule)
);
/** @type {OutgoingConnections} */
(originMgm.outgoingConnections).add(newConnection);
const targetMgm = this._getModuleGraphModule(module); const targetMgm = this._getModuleGraphModule(module);
targetMgm.incomingConnections.add(newConnection); targetMgm.incomingConnections.add(newConnection);
} }
@ -242,11 +264,16 @@ class ModuleGraph {
* @returns {void} * @returns {void}
*/ */
removeConnection(dependency) { removeConnection(dependency) {
const connection = this.getConnection(dependency); const connection =
/** @type {ModuleGraphConnection} */
(this.getConnection(dependency));
const targetMgm = this._getModuleGraphModule(connection.module); const targetMgm = this._getModuleGraphModule(connection.module);
targetMgm.incomingConnections.delete(connection); targetMgm.incomingConnections.delete(connection);
const originMgm = this._getModuleGraphModule(connection.originModule); const originMgm = this._getModuleGraphModule(
originMgm.outgoingConnections.delete(connection); /** @type {Module} */ (connection.originModule)
);
/** @type {OutgoingConnections} */
(originMgm.outgoingConnections).delete(connection);
this._dependencyMap.set(dependency, null); this._dependencyMap.set(dependency, null);
} }
@ -256,7 +283,9 @@ class ModuleGraph {
* @returns {void} * @returns {void}
*/ */
addExplanation(dependency, explanation) { addExplanation(dependency, explanation) {
const connection = this.getConnection(dependency); const connection =
/** @type {ModuleGraphConnection} */
(this.getConnection(dependency));
connection.addExplanation(explanation); connection.addExplanation(explanation);
} }
@ -468,7 +497,7 @@ class ModuleGraph {
/** /**
* @param {Module} module the module * @param {Module} module the module
* @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module * @returns {readonly Map<Module | undefined | null, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module
*/ */
getIncomingConnectionsByOriginModule(module) { getIncomingConnectionsByOriginModule(module) {
const connections = this._getModuleGraphModule(module).incomingConnections; const connections = this._getModuleGraphModule(module).incomingConnections;
@ -507,7 +536,7 @@ class ModuleGraph {
/** /**
* @param {Module} module the module * @param {Module} module the module
* @returns {Module | null} the issuer module * @returns {Module | null | undefined} the issuer module
*/ */
getIssuer(module) { getIssuer(module) {
const mgm = this._getModuleGraphModule(module); const mgm = this._getModuleGraphModule(module);

View File

@ -6,6 +6,7 @@
"use strict"; "use strict";
/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Dependency").GetConditionFn} GetConditionFn */
/** @typedef {import("./Module")} Module */ /** @typedef {import("./Module")} Module */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
@ -56,7 +57,7 @@ class ModuleGraphConnection {
* @param {Module} module the referenced module * @param {Module} module the referenced module
* @param {string=} explanation some extra detail * @param {string=} explanation some extra detail
* @param {boolean=} weak the reference is weak * @param {boolean=} weak the reference is weak
* @param {false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState=} condition condition for the connection * @param {false | null | GetConditionFn | undefined} condition condition for the connection
*/ */
constructor( constructor(
originModule, originModule,

View File

@ -13,13 +13,17 @@ const compileBooleanMatcher = require("./util/compileBooleanMatcher");
const propertyAccess = require("./util/propertyAccess"); const propertyAccess = require("./util/propertyAccess");
const { forEachRuntime, subtractRuntime } = require("./util/runtime"); const { forEachRuntime, subtractRuntime } = require("./util/runtime");
/** @typedef {import("../declarations/WebpackOptions").Environment} Environment */
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */ /** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("./CodeGenerationResults").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Module")} Module */ /** @typedef {import("./Module")} Module */
/** @typedef {import("./Module").BuildMeta} BuildMeta */
/** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
@ -52,8 +56,8 @@ Module has these incoming connections: ${Array.from(
}; };
/** /**
* @param {string|undefined} definition global object definition * @param {string | undefined} definition global object definition
* @returns {string} save to use global object * @returns {string | undefined} save to use global object
*/ */
function getGlobalObject(definition) { function getGlobalObject(definition) {
if (!definition) return definition; if (!definition) return definition;
@ -83,7 +87,10 @@ class RuntimeTemplate {
this.outputOptions = outputOptions || {}; this.outputOptions = outputOptions || {};
this.requestShortener = requestShortener; this.requestShortener = requestShortener;
this.globalObject = getGlobalObject(outputOptions.globalObject); this.globalObject = getGlobalObject(outputOptions.globalObject);
this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength); this.contentHashReplacement = "X".repeat(
/** @type {NonNullable<OutputOptions["hashDigestLength"]>} */
(outputOptions.hashDigestLength)
);
} }
isIIFE() { isIIFE() {
@ -95,51 +102,68 @@ class RuntimeTemplate {
} }
supportsConst() { supportsConst() {
return this.outputOptions.environment.const; return /** @type {Environment} */ (this.outputOptions.environment).const;
} }
supportsArrowFunction() { supportsArrowFunction() {
return this.outputOptions.environment.arrowFunction; return /** @type {Environment} */ (this.outputOptions.environment)
.arrowFunction;
} }
supportsAsyncFunction() { supportsAsyncFunction() {
return this.outputOptions.environment.asyncFunction; return /** @type {Environment} */ (this.outputOptions.environment)
.asyncFunction;
} }
supportsOptionalChaining() { supportsOptionalChaining() {
return this.outputOptions.environment.optionalChaining; return /** @type {Environment} */ (this.outputOptions.environment)
.optionalChaining;
} }
supportsForOf() { supportsForOf() {
return this.outputOptions.environment.forOf; return /** @type {Environment} */ (this.outputOptions.environment).forOf;
} }
supportsDestructuring() { supportsDestructuring() {
return this.outputOptions.environment.destructuring; return /** @type {Environment} */ (this.outputOptions.environment)
.destructuring;
} }
supportsBigIntLiteral() { supportsBigIntLiteral() {
return this.outputOptions.environment.bigIntLiteral; return /** @type {Environment} */ (this.outputOptions.environment)
.bigIntLiteral;
} }
supportsDynamicImport() { supportsDynamicImport() {
return this.outputOptions.environment.dynamicImport; return /** @type {Environment} */ (this.outputOptions.environment)
.dynamicImport;
} }
supportsEcmaScriptModuleSyntax() { supportsEcmaScriptModuleSyntax() {
return this.outputOptions.environment.module; return /** @type {Environment} */ (this.outputOptions.environment).module;
} }
supportTemplateLiteral() { supportTemplateLiteral() {
return this.outputOptions.environment.templateLiteral; return /** @type {Environment} */ (this.outputOptions.environment)
.templateLiteral;
} }
/**
* @param {string} returnValue return value
* @param {string} args arguments
* @returns {string} returning function
*/
returningFunction(returnValue, args = "") { returningFunction(returnValue, args = "") {
return this.supportsArrowFunction() return this.supportsArrowFunction()
? `(${args}) => (${returnValue})` ? `(${args}) => (${returnValue})`
: `function(${args}) { return ${returnValue}; }`; : `function(${args}) { return ${returnValue}; }`;
} }
/**
* @param {string} args arguments
* @param {string | string[]} body body
* @returns {string} basic function
*/
basicFunction(args, body) { basicFunction(args, body) {
return this.supportsArrowFunction() return this.supportsArrowFunction()
? `(${args}) => {\n${Template.indent(body)}\n}` ? `(${args}) => {\n${Template.indent(body)}\n}`
@ -211,16 +235,29 @@ class RuntimeTemplate {
: str; : str;
} }
/**
* @param {string} expression expression
* @param {string} args arguments
* @returns {string} expression function code
*/
expressionFunction(expression, args = "") { expressionFunction(expression, args = "") {
return this.supportsArrowFunction() return this.supportsArrowFunction()
? `(${args}) => (${expression})` ? `(${args}) => (${expression})`
: `function(${args}) { ${expression}; }`; : `function(${args}) { ${expression}; }`;
} }
/**
* @returns {string} empty function code
*/
emptyFunction() { emptyFunction() {
return this.supportsArrowFunction() ? "x => {}" : "function() {}"; return this.supportsArrowFunction() ? "x => {}" : "function() {}";
} }
/**
* @param {string[]} items items
* @param {string} value value
* @returns {string} destructure array code
*/
destructureArray(items, value) { destructureArray(items, value) {
return this.supportsDestructuring() return this.supportsDestructuring()
? `var [${items.join(", ")}] = ${value};` ? `var [${items.join(", ")}] = ${value};`
@ -229,6 +266,11 @@ class RuntimeTemplate {
); );
} }
/**
* @param {string[]} items items
* @param {string} value value
* @returns {string} destructure object code
*/
destructureObject(items, value) { destructureObject(items, value) {
return this.supportsDestructuring() return this.supportsDestructuring()
? `var {${items.join(", ")}} = ${value};` ? `var {${items.join(", ")}} = ${value};`
@ -237,10 +279,21 @@ class RuntimeTemplate {
); );
} }
/**
* @param {string} args arguments
* @param {string} body body
* @returns {string} IIFE code
*/
iife(args, body) { iife(args, body) {
return `(${this.basicFunction(args, body)})()`; return `(${this.basicFunction(args, body)})()`;
} }
/**
* @param {string} variable variable
* @param {string} array array
* @param {string | string[]} body body
* @returns {string} for each code
*/
forEach(variable, array, body) { forEach(variable, array, body) {
return this.supportsForOf() return this.supportsForOf()
? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}` ? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
@ -336,7 +389,7 @@ class RuntimeTemplate {
* @param {Object} options options object * @param {Object} options options object
* @param {ChunkGraph} options.chunkGraph the chunk graph * @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Module} options.module the module * @param {Module} options.module the module
* @param {string} options.request the request that should be printed as comment * @param {string=} options.request the request that should be printed as comment
* @param {string=} options.idExpr expression to use as id expression * @param {string=} options.idExpr expression to use as id expression
* @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned * @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned
* @returns {string} the code * @returns {string} the code
@ -373,7 +426,7 @@ class RuntimeTemplate {
* @param {Object} options options object * @param {Object} options options object
* @param {Module} options.module the module * @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph * @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment * @param {string=} options.request the request that should be printed as comment
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message) * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @returns {string} the expression * @returns {string} the expression
*/ */
@ -402,7 +455,7 @@ class RuntimeTemplate {
* @param {Object} options options object * @param {Object} options options object
* @param {Module | null} options.module the module * @param {Module | null} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph * @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment * @param {string=} options.request the request that should be printed as comment
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message) * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} the expression * @returns {string} the expression
@ -698,12 +751,16 @@ class RuntimeTemplate {
/** @type {Set<string>} */ /** @type {Set<string>} */
const positiveRuntimeIds = new Set(); const positiveRuntimeIds = new Set();
forEachRuntime(runtimeCondition, runtime => forEachRuntime(runtimeCondition, runtime =>
positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`) positiveRuntimeIds.add(
`${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}`
)
); );
/** @type {Set<string>} */ /** @type {Set<string>} */
const negativeRuntimeIds = new Set(); const negativeRuntimeIds = new Set();
forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime => forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime =>
negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`) negativeRuntimeIds.add(
`${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}`
)
); );
runtimeRequirements.add(RuntimeGlobals.runtimeId); runtimeRequirements.add(RuntimeGlobals.runtimeId);
return compileBooleanMatcher.fromLists( return compileBooleanMatcher.fromLists(
@ -774,7 +831,8 @@ class RuntimeTemplate {
const exportsType = module.getExportsType( const exportsType = module.getExportsType(
chunkGraph.moduleGraph, chunkGraph.moduleGraph,
originModule.buildMeta.strictHarmonyModule /** @type {BuildMeta} */
(originModule.buildMeta).strictHarmonyModule
); );
runtimeRequirements.add(RuntimeGlobals.require); runtimeRequirements.add(RuntimeGlobals.require);
const importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`; const importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`;
@ -831,7 +889,8 @@ class RuntimeTemplate {
} }
const exportsType = module.getExportsType( const exportsType = module.getExportsType(
moduleGraph, moduleGraph,
originModule.buildMeta.strictHarmonyModule /** @type {BuildMeta} */
(originModule.buildMeta).strictHarmonyModule
); );
if (defaultInterop) { if (defaultInterop) {
@ -913,7 +972,7 @@ class RuntimeTemplate {
/** /**
* @param {Object} options options * @param {Object} options options
* @param {AsyncDependenciesBlock} options.block the async block * @param {AsyncDependenciesBlock | undefined} options.block the async block
* @param {string} options.message the message * @param {string} options.message the message
* @param {ChunkGraph} options.chunkGraph the chunk graph * @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
@ -962,6 +1021,10 @@ class RuntimeTemplate {
runtimeRequirements.add(RuntimeGlobals.hasFetchPriority); runtimeRequirements.add(RuntimeGlobals.hasFetchPriority);
} }
/**
* @param {Chunk} chunk chunk
* @returns {string} require chunk id code
*/
const requireChunkId = chunk => const requireChunkId = chunk =>
`${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${ `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${
fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : "" fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : ""
@ -1052,7 +1115,9 @@ class RuntimeTemplate {
return "data:,"; return "data:,";
} }
const codeGen = codeGenerationResults.get(module, runtime); const codeGen = codeGenerationResults.get(module, runtime);
const { data } = codeGen; const data = /** @type {NonNullable<CodeGenerationResult["data"]>} */ (
codeGen.data
);
const url = data.get("url"); const url = data.get("url");
if (url) return url.toString(); if (url) return url.toString();
const filename = data.get("filename"); const filename = data.get("filename");

View File

@ -497,7 +497,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return (connection, runtime) => { return (connection, runtime) => {

View File

@ -35,7 +35,7 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return connection => { return connection => {

View File

@ -117,7 +117,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return getDependencyUsedByExportsCondition( return getDependencyUsedByExportsCondition(

View File

@ -30,7 +30,7 @@ class LoaderDependency extends ModuleDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return false; return false;

View File

@ -31,7 +31,7 @@ class LoaderImportDependency extends ModuleDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return false; return false;

View File

@ -56,7 +56,7 @@ class URLDependency extends ModuleDependency {
/** /**
* @param {ModuleGraph} moduleGraph module graph * @param {ModuleGraph} moduleGraph module graph
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active * @returns {null | false | GetConditionFn} function to determine if the connection is active
*/ */
getCondition(moduleGraph) { getCondition(moduleGraph) {
return getDependencyUsedByExportsCondition( return getDependencyUsedByExportsCondition(

View File

@ -100,6 +100,7 @@ class AggressiveSplittingPlugin {
let newSplits; let newSplits;
/** @type {Set<Chunk>} */ /** @type {Set<Chunk>} */
let fromAggressiveSplittingSet; let fromAggressiveSplittingSet;
/** @type {Map<Chunk, TODO>} */
let chunkSplitDataMap; let chunkSplitDataMap;
compilation.hooks.optimize.tap("AggressiveSplittingPlugin", () => { compilation.hooks.optimize.tap("AggressiveSplittingPlugin", () => {
newSplits = []; newSplits = [];

View File

@ -38,6 +38,8 @@ const {
} = require("../util/runtime"); } = require("../util/runtime");
/** @typedef {import("eslint-scope").Scope} Scope */ /** @typedef {import("eslint-scope").Scope} Scope */
/** @typedef {import("eslint-scope").Variable} Variable */
/** @typedef {import("eslint-scope").Reference} Reference */
/** @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("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../ChunkGraph")} ChunkGraph */
@ -53,6 +55,8 @@ const {
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../Module").SourceTypes} SourceTypes */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
@ -61,10 +65,15 @@ const {
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../WebpackError")} WebpackError */ /** @typedef {import("../WebpackError")} WebpackError */
/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ /** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/Hash")} Hash */
/** @typedef {typeof import("../util/Hash")} HashConstructor */ /** @typedef {typeof import("../util/Hash")} HashConstructor */
/** @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/comparators").Comparator<T>} Comparator
*/
// fix eslint-scope to support class properties correctly // fix eslint-scope to support class properties correctly
// cspell:word Referencer // cspell:word Referencer
@ -190,6 +199,12 @@ const RESERVED_NAMES = new Set(
const createComparator = (property, comparator) => (a, b) => const createComparator = (property, comparator) => (a, b) =>
comparator(a[property], b[property]); comparator(a[property], b[property]);
/**
* @param {number} a a
* @param {number} b b
* @returns {0 | 1 | -1} result
*/
const compareNumbers = (a, b) => { const compareNumbers = (a, b) => {
if (isNaN(a)) { if (isNaN(a)) {
if (!isNaN(b)) { if (!isNaN(b)) {
@ -208,6 +223,10 @@ const compareNumbers = (a, b) => {
const bySourceOrder = createComparator("sourceOrder", compareNumbers); const bySourceOrder = createComparator("sourceOrder", compareNumbers);
const byRangeStart = createComparator("rangeStart", compareNumbers); const byRangeStart = createComparator("rangeStart", compareNumbers);
/**
* @param {Iterable<string>} iterable iterable object
* @returns {string} joined iterable object
*/
const joinIterableWithComma = iterable => { const joinIterableWithComma = iterable => {
// This is more performant than Array.from().join(", ") // This is more performant than Array.from().join(", ")
// as it doesn't create an array // as it doesn't create an array
@ -241,7 +260,7 @@ const joinIterableWithComma = iterable => {
* @param {RuntimeTemplate} runtimeTemplate the runtime template * @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated
* @param {boolean} asCall asCall * @param {boolean} asCall asCall
* @param {boolean} strictHarmonyModule strictHarmonyModule * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule
* @param {boolean | undefined} asiSafe asiSafe * @param {boolean | undefined} asiSafe asiSafe
* @param {Set<ExportInfo>} alreadyVisited alreadyVisited * @param {Set<ExportInfo>} alreadyVisited alreadyVisited
* @returns {Binding} the final variable * @returns {Binding} the final variable
@ -445,7 +464,7 @@ const getFinalBinding = (
const refInfo = moduleToInfoMap.get(reexport.module); const refInfo = moduleToInfoMap.get(reexport.module);
return getFinalBinding( return getFinalBinding(
moduleGraph, moduleGraph,
refInfo, /** @type {ModuleInfo} */ (refInfo),
reexport.export reexport.export
? [...reexport.export, ...exportName.slice(1)] ? [...reexport.export, ...exportName.slice(1)]
: exportName.slice(1), : exportName.slice(1),
@ -455,7 +474,8 @@ const getFinalBinding = (
runtimeTemplate, runtimeTemplate,
neededNamespaceObjects, neededNamespaceObjects,
asCall, asCall,
info.module.buildMeta.strictHarmonyModule, /** @type {BuildMeta} */
(info.module.buildMeta).strictHarmonyModule,
asiSafe, asiSafe,
alreadyVisited alreadyVisited
); );
@ -508,8 +528,8 @@ const getFinalBinding = (
* @param {RuntimeTemplate} runtimeTemplate the runtime template * @param {RuntimeTemplate} runtimeTemplate the runtime template
* @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated * @param {Set<ConcatenatedModuleInfo>} neededNamespaceObjects modules for which a namespace object should be generated
* @param {boolean} asCall asCall * @param {boolean} asCall asCall
* @param {boolean} callContext callContext * @param {boolean | undefined} callContext callContext
* @param {boolean} strictHarmonyModule strictHarmonyModule * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule
* @param {boolean | undefined} asiSafe asiSafe * @param {boolean | undefined} asiSafe asiSafe
* @returns {string} the final name * @returns {string} the final name
*/ */
@ -576,6 +596,12 @@ const getFinalName = (
} }
}; };
/**
* @param {Scope | null} s scope
* @param {Set<string>} nameSet name set
* @param {TODO} scopeSet1 scope set 1
* @param {TODO} scopeSet2 scope set 2
*/
const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => { const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => {
let scope = s; let scope = s;
while (scope) { while (scope) {
@ -589,6 +615,10 @@ const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => {
} }
}; };
/**
* @param {Variable} variable variable
* @returns {Reference[]} references
*/
const getAllReferences = variable => { const getAllReferences = variable => {
let set = variable.references; let set = variable.references;
// Look for inner scope variables too (like in class Foo { t() { Foo } }) // Look for inner scope variables too (like in class Foo { t() { Foo } })
@ -772,11 +802,14 @@ class ConcatenatedModule extends Module {
*/ */
build(options, compilation, resolver, fs, callback) { build(options, compilation, resolver, fs, callback) {
const { rootModule } = this; const { rootModule } = this;
const { moduleArgument, exportsArgument } =
/** @type {BuildInfo} */
(rootModule.buildInfo);
this.buildInfo = { this.buildInfo = {
strict: true, strict: true,
cacheable: true, cacheable: true,
moduleArgument: rootModule.buildInfo.moduleArgument, moduleArgument,
exportsArgument: rootModule.buildInfo.exportsArgument, exportsArgument,
fileDependencies: new LazySet(), fileDependencies: new LazySet(),
contextDependencies: new LazySet(), contextDependencies: new LazySet(),
missingDependencies: new LazySet(), missingDependencies: new LazySet(),
@ -789,7 +822,7 @@ class ConcatenatedModule extends Module {
for (const m of this._modules) { for (const m of this._modules) {
// populate cacheable // populate cacheable
if (!m.buildInfo.cacheable) { if (!(/** @type {BuildInfo} */ (m.buildInfo).cacheable)) {
this.buildInfo.cacheable = false; this.buildInfo.cacheable = false;
} }
@ -797,7 +830,9 @@ class ConcatenatedModule extends Module {
for (const d of m.dependencies.filter( for (const d of m.dependencies.filter(
dep => dep =>
!(dep instanceof HarmonyImportDependency) || !(dep instanceof HarmonyImportDependency) ||
!this._modules.has(compilation.moduleGraph.getModule(dep)) !this._modules.has(
/** @type {Module} */ (compilation.moduleGraph.getModule(dep))
)
)) { )) {
this.dependencies.push(d); this.dependencies.push(d);
} }
@ -822,11 +857,14 @@ class ConcatenatedModule extends Module {
} }
} }
const { assets, assetsInfo, topLevelDeclarations } =
/** @type {BuildInfo} */ (m.buildInfo);
// populate topLevelDeclarations // populate topLevelDeclarations
if (m.buildInfo.topLevelDeclarations) { if (topLevelDeclarations) {
const topLevelDeclarations = this.buildInfo.topLevelDeclarations; const topLevelDeclarations = this.buildInfo.topLevelDeclarations;
if (topLevelDeclarations !== undefined) { if (topLevelDeclarations !== undefined) {
for (const decl of m.buildInfo.topLevelDeclarations) { for (const decl of topLevelDeclarations) {
topLevelDeclarations.add(decl); topLevelDeclarations.add(decl);
} }
} }
@ -835,17 +873,17 @@ class ConcatenatedModule extends Module {
} }
// populate assets // populate assets
if (m.buildInfo.assets) { if (assets) {
if (this.buildInfo.assets === undefined) { if (this.buildInfo.assets === undefined) {
this.buildInfo.assets = Object.create(null); this.buildInfo.assets = Object.create(null);
} }
Object.assign(this.buildInfo.assets, m.buildInfo.assets); Object.assign(this.buildInfo.assets, assets);
} }
if (m.buildInfo.assetsInfo) { if (assetsInfo) {
if (this.buildInfo.assetsInfo === undefined) { if (this.buildInfo.assetsInfo === undefined) {
this.buildInfo.assetsInfo = new Map(); this.buildInfo.assetsInfo = new Map();
} }
for (const [key, value] of m.buildInfo.assetsInfo) { for (const [key, value] of assetsInfo) {
this.buildInfo.assetsInfo.set(key, value); this.buildInfo.assetsInfo.set(key, value);
} }
} }
@ -1056,7 +1094,7 @@ class ConcatenatedModule extends Module {
hashFunction = "md4" hashFunction = "md4"
) { ) {
const cachedMakePathsRelative = makePathsRelative.bindContextCache( const cachedMakePathsRelative = makePathsRelative.bindContextCache(
rootModule.context, /** @type {string} */ (rootModule.context),
associatedObjectForCache associatedObjectForCache
); );
let identifiers = []; let identifiers = [];
@ -1174,6 +1212,10 @@ class ConcatenatedModule extends Module {
// We get ranges of all super class expressions to make // We get ranges of all super class expressions to make
// renaming to work correctly // renaming to work correctly
const superClassCache = new WeakMap(); const superClassCache = new WeakMap();
/**
* @param {Scope} scope scope
* @returns {TODO} result
*/
const getSuperClassExpressions = scope => { const getSuperClassExpressions = scope => {
const cacheEntry = superClassCache.get(scope); const cacheEntry = superClassCache.get(scope);
if (cacheEntry !== undefined) return cacheEntry; if (cacheEntry !== undefined) return cacheEntry;
@ -1216,7 +1258,8 @@ class ConcatenatedModule extends Module {
runtimeTemplate, runtimeTemplate,
neededNamespaceObjects, neededNamespaceObjects,
false, false,
info.module.buildMeta.strictHarmonyModule, /** @type {BuildMeta} */
(info.module.buildMeta).strictHarmonyModule,
true true
); );
if (!binding.ids) continue; if (!binding.ids) continue;
@ -1227,8 +1270,10 @@ class ConcatenatedModule extends Module {
); );
for (const expr of getSuperClassExpressions(reference.from)) { for (const expr of getSuperClassExpressions(reference.from)) {
if ( if (
expr.range[0] <= reference.identifier.range[0] && expr.range[0] <=
expr.range[1] >= reference.identifier.range[1] /** @type {Range} */ (reference.identifier.range)[0] &&
expr.range[1] >=
/** @type {Range} */ (reference.identifier.range)[1]
) { ) {
for (const variable of expr.variables) { for (const variable of expr.variables) {
usedNames.add(variable.name); usedNames.add(variable.name);
@ -1287,7 +1332,7 @@ class ConcatenatedModule extends Module {
references.map(r => r.identifier).concat(variable.identifiers) references.map(r => r.identifier).concat(variable.identifiers)
); );
for (const identifier of allIdentifiers) { for (const identifier of allIdentifiers) {
const r = identifier.range; const r = /** @type {Range} */ (identifier.range);
const path = getPathInAst(info.ast, identifier); const path = getPathInAst(info.ast, identifier);
if (path && path.length > 1) { if (path && path.length > 1) {
const maybeProperty = const maybeProperty =
@ -1342,7 +1387,8 @@ class ConcatenatedModule extends Module {
break; break;
} }
} }
if (info.module.buildMeta.exportsType !== "namespace") { const buildMeta = /** @type {BuildMeta} */ (info.module.buildMeta);
if (buildMeta.exportsType !== "namespace") {
const externalNameInterop = this.findNewName( const externalNameInterop = this.findNewName(
"namespaceObject", "namespaceObject",
allUsedNames, allUsedNames,
@ -1354,8 +1400,8 @@ class ConcatenatedModule extends Module {
topLevelDeclarations.add(externalNameInterop); topLevelDeclarations.add(externalNameInterop);
} }
if ( if (
info.module.buildMeta.exportsType === "default" && buildMeta.exportsType === "default" &&
info.module.buildMeta.defaultObject !== "redirect" buildMeta.defaultObject !== "redirect"
) { ) {
const externalNameInterop = this.findNewName( const externalNameInterop = this.findNewName(
"namespaceObject2", "namespaceObject2",
@ -1367,10 +1413,7 @@ class ConcatenatedModule extends Module {
info.interopNamespaceObject2Name = externalNameInterop; info.interopNamespaceObject2Name = externalNameInterop;
topLevelDeclarations.add(externalNameInterop); topLevelDeclarations.add(externalNameInterop);
} }
if ( if (buildMeta.exportsType === "dynamic" || !buildMeta.exportsType) {
info.module.buildMeta.exportsType === "dynamic" ||
!info.module.buildMeta.exportsType
) {
const externalNameInterop = this.findNewName( const externalNameInterop = this.findNewName(
"default", "default",
allUsedNames, allUsedNames,
@ -1404,10 +1447,11 @@ class ConcatenatedModule extends Module {
neededNamespaceObjects, neededNamespaceObjects,
match.call, match.call,
!match.directImport, !match.directImport,
info.module.buildMeta.strictHarmonyModule, /** @type {BuildMeta} */
(info.module.buildMeta).strictHarmonyModule,
match.asiSafe match.asiSafe
); );
const r = reference.identifier.range; const r = /** @type {Range} */ (reference.identifier.range);
const source = info.source; const source = info.source;
// range is extended by 2 chars to cover the appended "._" // range is extended by 2 chars to cover the appended "._"
source.replace(r[0], r[1] + 1, finalName); source.replace(r[0], r[1] + 1, finalName);
@ -1427,7 +1471,9 @@ class ConcatenatedModule extends Module {
const rootInfo = /** @type {ConcatenatedModuleInfo} */ ( const rootInfo = /** @type {ConcatenatedModuleInfo} */ (
moduleToInfoMap.get(this.rootModule) moduleToInfoMap.get(this.rootModule)
); );
const strictHarmonyModule = rootInfo.module.buildMeta.strictHarmonyModule; const strictHarmonyModule =
/** @type {BuildMeta} */
(rootInfo.module.buildMeta).strictHarmonyModule;
const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module); const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module);
for (const exportInfo of exportsInfo.orderedExports) { for (const exportInfo of exportsInfo.orderedExports) {
const name = exportInfo.name; const name = exportInfo.name;
@ -1457,7 +1503,9 @@ class ConcatenatedModule extends Module {
exportInfo.isReexport() ? "reexport" : "binding" exportInfo.isReexport() ? "reexport" : "binding"
} */ ${finalName}`; } */ ${finalName}`;
} catch (e) { } catch (e) {
e.message += `\nwhile generating the root export '${name}' (used name: '${used}')`; /** @type {Error} */
(e).message +=
`\nwhile generating the root export '${name}' (used name: '${used}')`;
throw e; throw e;
} }
}); });
@ -1527,7 +1575,8 @@ class ConcatenatedModule extends Module {
neededNamespaceObjects, neededNamespaceObjects,
false, false,
undefined, undefined,
info.module.buildMeta.strictHarmonyModule, /** @type {BuildMeta} */
(info.module.buildMeta).strictHarmonyModule,
true true
); );
nsObj.push( nsObj.push(
@ -1698,7 +1747,9 @@ ${defineGetters}`
codeGenerationResults, codeGenerationResults,
sourceTypes: TYPES sourceTypes: TYPES
}); });
const source = codeGenResult.sources.get("javascript"); const source = /** @type {Source} */ (
codeGenResult.sources.get("javascript")
);
const data = codeGenResult.data; const data = codeGenResult.data;
const chunkInitFragments = data && data.get("chunkInitFragments"); const chunkInitFragments = data && data.get("chunkInitFragments");
const code = source.source().toString(); const code = source.source().toString();
@ -1730,7 +1781,7 @@ ${defineGetters}`
ignoreEval: true, ignoreEval: true,
impliedStrict: true impliedStrict: true
}); });
const globalScope = scopeManager.acquire(ast); const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast));
const moduleScope = globalScope.childScopes[0]; const moduleScope = globalScope.childScopes[0];
const resultSource = new ReplaceSource(source); const resultSource = new ReplaceSource(source);
info.runtimeRequirements = codeGenResult.runtimeRequirements; info.runtimeRequirements = codeGenResult.runtimeRequirements;
@ -1741,7 +1792,9 @@ ${defineGetters}`
info.globalScope = globalScope; info.globalScope = globalScope;
info.moduleScope = moduleScope; info.moduleScope = moduleScope;
} catch (err) { } catch (err) {
err.message += `\nwhile analyzing module ${m.identifier()} for concatenation`; /** @type {Error} */
(err).message +=
`\nwhile analyzing module ${m.identifier()} for concatenation`;
throw err; throw err;
} }
} }

View File

@ -21,6 +21,7 @@ const InnerGraph = require("./InnerGraph");
/** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */ /** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("./InnerGraph").InnerGraph} InnerGraph */ /** @typedef {import("./InnerGraph").InnerGraph} InnerGraph */
/** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */ /** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */
@ -123,7 +124,10 @@ class InnerGraphPlugin {
if (parser.scope.topLevelScope === true) { if (parser.scope.topLevelScope === true) {
if ( if (
statement.type === "ClassDeclaration" && statement.type === "ClassDeclaration" &&
parser.isPure(statement, statement.range[0]) parser.isPure(
statement,
/** @type {Range} */ (statement.range)[0]
)
) { ) {
const name = statement.id ? statement.id.name : "*default*"; const name = statement.id ? statement.id.name : "*default*";
const fn = InnerGraph.tagTopLevelSymbol(parser, name); const fn = InnerGraph.tagTopLevelSymbol(parser, name);
@ -137,10 +141,12 @@ class InnerGraphPlugin {
if ( if (
(decl.type === "ClassExpression" || (decl.type === "ClassExpression" ||
decl.type === "ClassDeclaration") && decl.type === "ClassDeclaration") &&
parser.isPure(decl, decl.range[0]) parser.isPure(decl, /** @type {Range} */ (decl.range)[0])
) { ) {
classWithTopLevelSymbol.set(decl, fn); classWithTopLevelSymbol.set(decl, fn);
} else if (parser.isPure(decl, statement.range[0])) { } else if (
parser.isPure(decl, /** @type {Range} */ (statement.range)[0])
) {
statementWithTopLevelSymbol.set(statement, fn); statementWithTopLevelSymbol.set(statement, fn);
if ( if (
!decl.type.endsWith("FunctionExpression") && !decl.type.endsWith("FunctionExpression") &&
@ -164,11 +170,19 @@ class InnerGraphPlugin {
const name = decl.id.name; const name = decl.id.name;
if ( if (
decl.init.type === "ClassExpression" && decl.init.type === "ClassExpression" &&
parser.isPure(decl.init, decl.id.range[1]) parser.isPure(
decl.init,
/** @type {Range} */ (decl.id.range)[1]
)
) { ) {
const fn = InnerGraph.tagTopLevelSymbol(parser, name); const fn = InnerGraph.tagTopLevelSymbol(parser, name);
classWithTopLevelSymbol.set(decl.init, fn); classWithTopLevelSymbol.set(decl.init, fn);
} else if (parser.isPure(decl.init, decl.id.range[1])) { } else if (
parser.isPure(
decl.init,
/** @type {Range} */ (decl.id.range)[1]
)
) {
const fn = InnerGraph.tagTopLevelSymbol(parser, name); const fn = InnerGraph.tagTopLevelSymbol(parser, name);
declWithTopLevelSymbol.set(decl, fn); declWithTopLevelSymbol.set(decl, fn);
if ( if (
@ -214,7 +228,7 @@ class InnerGraphPlugin {
return; return;
default: { default: {
const dep = new PureExpressionDependency( const dep = new PureExpressionDependency(
purePart.range /** @type {Range} */ (purePart.range)
); );
dep.loc = statement.loc; dep.loc = statement.loc;
dep.usedByExports = usedByExports; dep.usedByExports = usedByExports;
@ -238,7 +252,9 @@ class InnerGraphPlugin {
fn && fn &&
parser.isPure( parser.isPure(
expr, expr,
statement.id ? statement.id.range[1] : statement.range[0] statement.id
? /** @type {Range} */ (statement.id.range)[1]
: /** @type {Range} */ (statement.range)[0]
) )
) { ) {
InnerGraph.setTopLevelSymbol(parser.state, fn); InnerGraph.setTopLevelSymbol(parser.state, fn);
@ -272,7 +288,9 @@ class InnerGraphPlugin {
!element.static || !element.static ||
parser.isPure( parser.isPure(
expression, expression,
element.key ? element.key.range[1] : element.range[0] element.key
? /** @type {Range} */ (element.key.range)[1]
: /** @type {Range} */ (element.range)[0]
) )
) { ) {
InnerGraph.setTopLevelSymbol(parser.state, fn); InnerGraph.setTopLevelSymbol(parser.state, fn);
@ -284,7 +302,7 @@ class InnerGraphPlugin {
return; return;
default: { default: {
const dep = new PureExpressionDependency( const dep = new PureExpressionDependency(
expression.range /** @type {Range} */ (expression.range)
); );
dep.loc = expression.loc; dep.loc = expression.loc;
dep.usedByExports = usedByExports; dep.usedByExports = usedByExports;
@ -321,7 +339,7 @@ class InnerGraphPlugin {
return; return;
default: { default: {
const dep = new PureExpressionDependency( const dep = new PureExpressionDependency(
decl.init.range /** @type {Range} */ (decl.init.range)
); );
dep.loc = decl.loc; dep.loc = decl.loc;
dep.usedByExports = usedByExports; dep.usedByExports = usedByExports;

View File

@ -23,6 +23,7 @@ const ConcatenatedModule = require("./ConcatenatedModule");
/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */ /** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../RequestShortener")} RequestShortener */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@ -49,6 +50,9 @@ const formatBailoutReason = msg => {
}; };
class ModuleConcatenationPlugin { class ModuleConcatenationPlugin {
/**
* @param {TODO} options options
*/
constructor(options) { constructor(options) {
if (typeof options !== "object") options = {}; if (typeof options !== "object") options = {};
this.options = options; this.options = options;
@ -171,7 +175,7 @@ class ModuleConcatenationPlugin {
} }
// Must be in strict mode // Must be in strict mode
if (!module.buildInfo.strict) { if (!(/** @type {BuildInfo} */ (module.buildInfo).strict)) {
setBailoutReason(module, `Module is not in strict mode`); setBailoutReason(module, `Module is not in strict mode`);
continue; continue;
} }
@ -242,7 +246,10 @@ class ModuleConcatenationPlugin {
// this improves performance, because modules already selected as inner are skipped // this improves performance, because modules already selected as inner are skipped
logger.time("sort relevant modules"); logger.time("sort relevant modules");
relevantModules.sort((a, b) => { relevantModules.sort((a, b) => {
return moduleGraph.getDepth(a) - moduleGraph.getDepth(b); return (
/** @type {number} */ (moduleGraph.getDepth(a)) -
/** @type {number} */ (moduleGraph.getDepth(b))
);
}); });
logger.timeEnd("sort relevant modules"); logger.timeEnd("sort relevant modules");
@ -927,6 +934,9 @@ class ConcatConfiguration {
return this.modules.size; return this.modules.size;
} }
/**
* @param {number} snapshot snapshot
*/
rollback(snapshot) { rollback(snapshot) {
const modules = this.modules; const modules = this.modules;
for (const m of modules) { for (const m of modules) {

View File

@ -77,6 +77,7 @@ class RemoveParentModulesPlugin {
let nextModuleMask = ONE_BIGINT; let nextModuleMask = ONE_BIGINT;
const maskByModule = new WeakMap(); const maskByModule = new WeakMap();
/** @type {Module[]} */
const ordinalModules = []; const ordinalModules = [];
/** /**

View File

@ -10,6 +10,9 @@
/** @typedef {import("../Entrypoint")} Entrypoint */ /** @typedef {import("../Entrypoint")} Entrypoint */
class RuntimeChunkPlugin { class RuntimeChunkPlugin {
/**
* @param {{ name?: (entrypoint: { name: string }) => string }} options options
*/
constructor(options) { constructor(options) {
this.options = { this.options = {
/** /**
@ -37,6 +40,7 @@ class RuntimeChunkPlugin {
(compilation.entries.get(entryName)); (compilation.entries.get(entryName));
if (data.options.runtime === undefined && !data.options.dependOn) { if (data.options.runtime === undefined && !data.options.dependOn) {
// Determine runtime chunk name // Determine runtime chunk name
/** @type {string | ((entrypoint: { name: string }) => string)} */
let name = this.options.name; let name = this.options.name;
if (typeof name === "function") { if (typeof name === "function") {
name = name({ name: entryName }); name = name({ name: entryName });

View File

@ -20,8 +20,11 @@ const formatLocation = require("../formatLocation");
/** @typedef {import("estree").Statement} Statement */ /** @typedef {import("estree").Statement} Statement */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../Module")} Module */ /** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** /**
* @typedef {Object} ExportInModule * @typedef {Object} ExportInModule
@ -36,7 +39,9 @@ const formatLocation = require("../formatLocation");
* @property {Map<Module, Set<string>>} dynamic * @property {Map<Module, Set<string>>} dynamic
*/ */
/** @type {WeakMap<any, Map<string, RegExp>>} */ /** @typedef {Map<string, RegExp>} CacheItem */
/** @type {WeakMap<any, CacheItem>} */
const globToRegexpCache = new WeakMap(); const globToRegexpCache = new WeakMap();
/** /**
@ -96,7 +101,7 @@ class SideEffectsFlagPlugin {
const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects( const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(
resolveData.relativePath, resolveData.relativePath,
sideEffects, sideEffects,
cache /** @type {CacheItem} */ (cache)
); );
module.factoryMeta.sideEffectFree = !hasSideEffects; module.factoryMeta.sideEffectFree = !hasSideEffects;
} }
@ -132,7 +137,10 @@ class SideEffectsFlagPlugin {
switch (statement.type) { switch (statement.type) {
case "ExpressionStatement": case "ExpressionStatement":
if ( if (
!parser.isPure(statement.expression, statement.range[0]) !parser.isPure(
statement.expression,
/** @type {Range} */ (statement.range)[0]
)
) { ) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
} }
@ -140,27 +148,35 @@ class SideEffectsFlagPlugin {
case "IfStatement": case "IfStatement":
case "WhileStatement": case "WhileStatement":
case "DoWhileStatement": case "DoWhileStatement":
if (!parser.isPure(statement.test, statement.range[0])) { if (
!parser.isPure(
statement.test,
/** @type {Range} */ (statement.range)[0]
)
) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
} }
// statement hook will be called for child statements too // statement hook will be called for child statements too
break; break;
case "ForStatement": case "ForStatement":
if ( if (
!parser.isPure(statement.init, statement.range[0]) || !parser.isPure(
statement.init,
/** @type {Range} */ (statement.range)[0]
) ||
!parser.isPure( !parser.isPure(
statement.test, statement.test,
statement.init statement.init
? statement.init.range[1] ? /** @type {Range} */ (statement.init.range)[1]
: statement.range[0] : /** @type {Range} */ (statement.range)[0]
) || ) ||
!parser.isPure( !parser.isPure(
statement.update, statement.update,
statement.test statement.test
? statement.test.range[1] ? /** @type {Range} */ (statement.test.range)[1]
: statement.init : statement.init
? statement.init.range[1] ? /** @type {Range} */ (statement.init.range)[1]
: statement.range[0] : /** @type {Range} */ (statement.range)[0]
) )
) { ) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
@ -169,7 +185,10 @@ class SideEffectsFlagPlugin {
break; break;
case "SwitchStatement": case "SwitchStatement":
if ( if (
!parser.isPure(statement.discriminant, statement.range[0]) !parser.isPure(
statement.discriminant,
/** @type {Range} */ (statement.range)[0]
)
) { ) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
} }
@ -178,14 +197,22 @@ class SideEffectsFlagPlugin {
case "VariableDeclaration": case "VariableDeclaration":
case "ClassDeclaration": case "ClassDeclaration":
case "FunctionDeclaration": case "FunctionDeclaration":
if (!parser.isPure(statement, statement.range[0])) { if (
!parser.isPure(
statement,
/** @type {Range} */ (statement.range)[0]
)
) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
} }
break; break;
case "ExportNamedDeclaration": case "ExportNamedDeclaration":
case "ExportDefaultDeclaration": case "ExportDefaultDeclaration":
if ( if (
!parser.isPure(statement.declaration, statement.range[0]) !parser.isPure(
statement.declaration,
/** @type {Range} */ (statement.range)[0]
)
) { ) {
sideEffectsStatement = statement; sideEffectsStatement = statement;
} }
@ -208,7 +235,8 @@ class SideEffectsFlagPlugin {
); );
parser.hooks.finish.tap(PLUGIN_NAME, () => { parser.hooks.finish.tap(PLUGIN_NAME, () => {
if (sideEffectsStatement === undefined) { if (sideEffectsStatement === undefined) {
parser.state.module.buildMeta.sideEffectFree = true; /** @type {BuildMeta} */
(parser.state.module.buildMeta).sideEffectFree = true;
} else { } else {
const { loc, type } = sideEffectsStatement; const { loc, type } = sideEffectsStatement;
moduleGraph moduleGraph
@ -216,7 +244,7 @@ class SideEffectsFlagPlugin {
.push( .push(
() => () =>
`Statement (${type}) with side effects in source code at ${formatLocation( `Statement (${type}) with side effects in source code at ${formatLocation(
loc /** @type {DependencyLocation} */ (loc)
)}` )}`
); );
} }
@ -246,6 +274,9 @@ class SideEffectsFlagPlugin {
const optimizedModules = new Set(); const optimizedModules = new Set();
/**
* @param {Module} module module
*/
const optimizeIncomingConnections = module => { const optimizeIncomingConnections = module => {
if (optimizedModules.has(module)) return; if (optimizedModules.has(module)) return;
optimizedModules.add(module); optimizedModules.add(module);

View File

@ -5,6 +5,21 @@
"use strict"; "use strict";
/**
* @template {any[]} T
* @template V
* @typedef {Map<object, WeakTupleMap<T, V>>} M
*/
/**
* @template {any[]} T
* @template V
* @typedef {WeakMap<object, WeakTupleMap<T, V>>} W
*/
/**
* @param {any} thing thing
* @returns {boolean} true if is weak
*/
const isWeakKey = thing => typeof thing === "object" && thing !== null; const isWeakKey = thing => typeof thing === "object" && thing !== null;
/** /**
@ -15,11 +30,20 @@ class WeakTupleMap {
constructor() { constructor() {
/** @private */ /** @private */
this.f = 0; this.f = 0;
/** @private @type {any} */ /**
* @private
* @type {any}
**/
this.v = undefined; this.v = undefined;
/** @private @type {Map<object, WeakTupleMap<T, V>> | undefined} */ /**
* @private
* @type {M<T, V> | undefined}
**/
this.m = undefined; this.m = undefined;
/** @private @type {WeakMap<object, WeakTupleMap<T, V>> | undefined} */ /**
* @private
* @type {W<T, V> | undefined}
**/
this.w = undefined; this.w = undefined;
} }
@ -41,7 +65,7 @@ class WeakTupleMap {
* @returns {boolean} true, if the tuple is in the Set * @returns {boolean} true, if the tuple is in the Set
*/ */
has(...args) { has(...args) {
/** @type {WeakTupleMap<T, V>} */ /** @type {WeakTupleMap<T, V> | undefined} */
let node = this; let node = this;
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
node = node._peek(args[i]); node = node._peek(args[i]);
@ -52,10 +76,10 @@ class WeakTupleMap {
/** /**
* @param {T} args tuple * @param {T} args tuple
* @returns {V} the value * @returns {V | undefined} the value
*/ */
get(...args) { get(...args) {
/** @type {WeakTupleMap<T, V>} */ /** @type {WeakTupleMap<T, V> | undefined} */
let node = this; let node = this;
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
node = node._peek(args[i]); node = node._peek(args[i]);
@ -86,7 +110,7 @@ class WeakTupleMap {
* @returns {void} * @returns {void}
*/ */
delete(...args) { delete(...args) {
/** @type {WeakTupleMap<T, V>} */ /** @type {WeakTupleMap<T, V> | undefined} */
let node = this; let node = this;
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
node = node._peek(args[i]); node = node._peek(args[i]);
@ -113,6 +137,10 @@ class WeakTupleMap {
return (this.f & 1) === 1; return (this.f & 1) === 1;
} }
/**
* @param {any} v value
* @private
*/
_setValue(v) { _setValue(v) {
this.f |= 1; this.f |= 1;
this.v = v; this.v = v;
@ -123,16 +151,26 @@ class WeakTupleMap {
this.v = undefined; this.v = undefined;
} }
/**
* @param {any} thing thing
* @returns {WeakTupleMap<T, V> | undefined} thing
* @private
*/
_peek(thing) { _peek(thing) {
if (isWeakKey(thing)) { if (isWeakKey(thing)) {
if ((this.f & 4) !== 4) return undefined; if ((this.f & 4) !== 4) return undefined;
return this.w.get(thing); return /** @type {W<T, V>} */ (this.w).get(thing);
} else { } else {
if ((this.f & 2) !== 2) return undefined; if ((this.f & 2) !== 2) return undefined;
return this.m.get(thing); return /** @type {M<T, V>} */ (this.m).get(thing);
} }
} }
/**
* @private
* @param {any} thing thing
* @returns {WeakTupleMap<T, V>} value
*/
_get(thing) { _get(thing) {
if (isWeakKey(thing)) { if (isWeakKey(thing)) {
if ((this.f & 4) !== 4) { if ((this.f & 4) !== 4) {
@ -142,12 +180,15 @@ class WeakTupleMap {
(this.w = newMap).set(thing, newNode); (this.w = newMap).set(thing, newNode);
return newNode; return newNode;
} }
const entry = this.w.get(thing); const entry =
/** @type {W<T, V>} */
(this.w).get(thing);
if (entry !== undefined) { if (entry !== undefined) {
return entry; return entry;
} }
const newNode = new WeakTupleMap(); const newNode = new WeakTupleMap();
this.w.set(thing, newNode); /** @type {W<T, V>} */
(this.w).set(thing, newNode);
return newNode; return newNode;
} else { } else {
if ((this.f & 2) !== 2) { if ((this.f & 2) !== 2) {
@ -157,12 +198,15 @@ class WeakTupleMap {
(this.m = newMap).set(thing, newNode); (this.m = newMap).set(thing, newNode);
return newNode; return newNode;
} }
const entry = this.m.get(thing); const entry =
/** @type {M<T, V>} */
(this.m).get(thing);
if (entry !== undefined) { if (entry !== undefined) {
return entry; return entry;
} }
const newNode = new WeakTupleMap(); const newNode = new WeakTupleMap();
this.m.set(thing, newNode); /** @type {M<T, V>} */
(this.m).set(thing, newNode);
return newNode; return newNode;
} }
} }

View File

@ -8,6 +8,7 @@
const { compareRuntime } = require("./runtime"); const { compareRuntime } = require("./runtime");
/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Chunk").ChunkId} ChunkId */
/** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../ChunkGroup")} ChunkGroup */ /** @typedef {import("../ChunkGroup")} ChunkGroup */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
@ -46,7 +47,10 @@ const createCachedParameterizedComparator = fn => {
* @returns {-1|0|1} compare result * @returns {-1|0|1} compare result
*/ */
exports.compareChunksById = (a, b) => { exports.compareChunksById = (a, b) => {
return compareIds(a.id, b.id); return compareIds(
/** @type {ChunkId} */ (a.id),
/** @type {ChunkId} */ (b.id)
);
}; };
/** /**
@ -166,8 +170,8 @@ exports.compareStringsNumeric = compareStringsNumeric;
*/ */
const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => { const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
const cmp = compareNumbers( const cmp = compareNumbers(
moduleGraph.getPostOrderIndex(a), /** @type {number} */ (moduleGraph.getPostOrderIndex(a)),
moduleGraph.getPostOrderIndex(b) /** @type {number} */ (moduleGraph.getPostOrderIndex(b))
); );
if (cmp !== 0) return cmp; if (cmp !== 0) return cmp;
return compareIds(a.identifier(), b.identifier()); return compareIds(a.identifier(), b.identifier());
@ -186,8 +190,8 @@ exports.compareModulesByPostOrderIndexOrIdentifier =
*/ */
const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => { const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
const cmp = compareNumbers( const cmp = compareNumbers(
moduleGraph.getPreOrderIndex(a), /** @type {number} */ (moduleGraph.getPreOrderIndex(a)),
moduleGraph.getPreOrderIndex(b) /** @type {number} */ (moduleGraph.getPreOrderIndex(b))
); );
if (cmp !== 0) return cmp; if (cmp !== 0) return cmp;
return compareIds(a.identifier(), b.identifier()); return compareIds(a.identifier(), b.identifier());
@ -261,7 +265,9 @@ exports.compareStrings = compareStrings;
* @returns {-1|0|1} compare result * @returns {-1|0|1} compare result
*/ */
const compareChunkGroupsByIndex = (a, b) => { const compareChunkGroupsByIndex = (a, b) => {
return a.index < b.index ? -1 : 1; return /** @type {number} */ (a.index) < /** @type {number} */ (b.index)
? -1
: 1;
}; };
exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex; exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex;
@ -273,7 +279,7 @@ exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex;
*/ */
class TwoKeyWeakMap { class TwoKeyWeakMap {
constructor() { constructor() {
/** @private @type {WeakMap<any, WeakMap<any, T>>} */ /** @private @type {WeakMap<any, WeakMap<any, T | undefined>>} */
this._map = new WeakMap(); this._map = new WeakMap();
} }
@ -431,7 +437,11 @@ exports.keepOriginalOrder = iterable => {
for (const item of iterable) { for (const item of iterable) {
map.set(item, i++); map.set(item, i++);
} }
return (a, b) => compareNumbers(map.get(a), map.get(b)); return (a, b) =>
compareNumbers(
/** @type {number} */ (map.get(a)),
/** @type {number} */ (map.get(b))
);
}; };
/** /**
@ -442,7 +452,10 @@ exports.compareChunksNatural = chunkGraph => {
const cmpFn = exports.compareModulesById(chunkGraph); const cmpFn = exports.compareModulesById(chunkGraph);
const cmpIterableFn = compareIterables(cmpFn); const cmpIterableFn = compareIterables(cmpFn);
return concatComparators( return concatComparators(
compareSelect(chunk => chunk.name, compareIds), compareSelect(
chunk => /** @type {string|number} */ (chunk.name),
compareIds
),
compareSelect(chunk => chunk.runtime, compareRuntime), compareSelect(chunk => chunk.runtime, compareRuntime),
compareSelect( compareSelect(
/** /**
@ -475,8 +488,10 @@ exports.compareLocations = (a, b) => {
const bp = b.start; const bp = b.start;
if (ap.line < bp.line) return -1; if (ap.line < bp.line) return -1;
if (ap.line > bp.line) return 1; if (ap.line > bp.line) return 1;
if (ap.column < bp.column) return -1; if (/** @type {number} */ (ap.column) < /** @type {number} */ (bp.column))
if (ap.column > bp.column) return 1; return -1;
if (/** @type {number} */ (ap.column) > /** @type {number} */ (bp.column))
return 1;
} else return -1; } else return -1;
} else if ("start" in b) return 1; } else if ("start" in b) return 1;
if ("name" in a) { if ("name" in a) {
@ -487,8 +502,10 @@ exports.compareLocations = (a, b) => {
} else if ("name" in b) return 1; } else if ("name" in b) return 1;
if ("index" in a) { if ("index" in a) {
if ("index" in b) { if ("index" in b) {
if (a.index < b.index) return -1; if (/** @type {number} */ (a.index) < /** @type {number} */ (b.index))
if (a.index > b.index) return 1; return -1;
if (/** @type {number} */ (a.index) > /** @type {number} */ (b.index))
return 1;
} else return -1; } else return -1;
} else if ("index" in b) return 1; } else if ("index" in b) return 1;
return 0; return 0;

View File

@ -284,14 +284,17 @@ exports.mkdirpSync = mkdirpSync;
* @returns {void} * @returns {void}
*/ */
const readJson = (fs, p, callback) => { const readJson = (fs, p, callback) => {
if ("readJson" in fs) return fs.readJson(p, callback); if ("readJson" in fs)
return /** @type {NonNullable<InputFileSystem["readJson"]>} */ (
fs.readJson
)(p, callback);
fs.readFile(p, (err, buf) => { fs.readFile(p, (err, buf) => {
if (err) return callback(err); if (err) return callback(err);
let data; let data;
try { try {
data = JSON.parse(buf.toString("utf-8")); data = JSON.parse(/** @type {Buffer} */ (buf).toString("utf-8"));
} catch (e) { } catch (e) {
return callback(e); return callback(/** @type {Error} */ (e));
} }
return callback(null, data); return callback(null, data);
}); });
@ -320,13 +323,16 @@ const lstatReadlinkAbsolute = (fs, p, callback) => {
}; };
const doStat = () => { const doStat = () => {
if ("lstat" in fs) { if ("lstat" in fs) {
return fs.lstat(p, (err, stats) => { return /** @type {NonNullable<InputFileSystem["lstat"]>} */ (fs.lstat)(
if (err) return callback(err); p,
if (stats.isSymbolicLink()) { (err, stats) => {
return doReadLink(); if (err) return callback(err);
if (/** @type {IStats} */ (stats).isSymbolicLink()) {
return doReadLink();
}
callback(null, stats);
} }
callback(null, stats); );
});
} else { } else {
return fs.stat(p, callback); return fs.stat(p, callback);
} }

View File

@ -25,6 +25,14 @@ const WebAssemblyExportImportedDependency = require("../dependencies/WebAssembly
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
/** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */ /** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */
/** @typedef {import("@webassemblyjs/ast").Instruction} Instruction */
/** @typedef {import("@webassemblyjs/ast").ModuleImport} ModuleImport */
/** @typedef {import("@webassemblyjs/ast").ModuleExport} ModuleExport */
/** @typedef {import("@webassemblyjs/ast").Global} Global */
/**
* @template T
* @typedef {import("@webassemblyjs/ast").NodePath<T>} NodePath
*/
/** /**
* @typedef {(buf: ArrayBuffer) => ArrayBuffer} ArrayBufferTransform * @typedef {(buf: ArrayBuffer) => ArrayBuffer} ArrayBufferTransform
@ -197,6 +205,9 @@ const rewriteImportedGlobals = state => bin => {
// in order to preserve non-imported global's order we need to re-inject // in order to preserve non-imported global's order we need to re-inject
// those as well // those as well
/**
* @param {NodePath<Global>} path path
*/
Global(path) { Global(path) {
const { node } = path; const { node } = path;
const [init] = node.init; const [init] = node.init;
@ -246,6 +257,9 @@ const rewriteExportNames =
({ ast, moduleGraph, module, externalExports, runtime }) => ({ ast, moduleGraph, module, externalExports, runtime }) =>
bin => { bin => {
return editWithAST(ast, bin, { return editWithAST(ast, bin, {
/**
* @param {NodePath<ModuleExport>} path path
*/
ModuleExport(path) { ModuleExport(path) {
const isExternal = externalExports.has(path.node.name); const isExternal = externalExports.has(path.node.name);
if (isExternal) { if (isExternal) {
@ -259,7 +273,7 @@ const rewriteExportNames =
path.remove(); path.remove();
return; return;
} }
path.node.name = usedName; path.node.name = /** @type {string} */ (usedName);
} }
}); });
}; };
@ -275,6 +289,9 @@ const rewriteImports =
({ ast, usedDependencyMap }) => ({ ast, usedDependencyMap }) =>
bin => { bin => {
return editWithAST(ast, bin, { return editWithAST(ast, bin, {
/**
* @param {NodePath<ModuleImport>} path path
*/
ModuleImport(path) { ModuleImport(path) {
const result = usedDependencyMap.get( const result = usedDependencyMap.get(
path.node.module + ":" + path.node.name path.node.module + ":" + path.node.name
@ -326,6 +343,7 @@ const addInitFunction =
); );
}); });
/** @type {Instruction[]} */
const funcBody = []; const funcBody = [];
importedGlobals.forEach((importedGlobal, index) => { importedGlobals.forEach((importedGlobal, index) => {
const args = [t.indexLiteral(index)]; const args = [t.indexLiteral(index)];

View File

@ -38,6 +38,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.23.7", "@babel/core": "^7.23.7",
"@babel/preset-react": "^7.23.3", "@babel/preset-react": "^7.23.3",
"@types/glob-to-regexp": "^0.4.4",
"@types/jest": "^29.5.11", "@types/jest": "^29.5.11",
"@types/mime-types": "^2.1.4", "@types/mime-types": "^2.1.4",
"@types/node": "^20.1.7", "@types/node": "^20.1.7",
@ -84,8 +85,8 @@
"mini-svg-data-uri": "^1.2.3", "mini-svg-data-uri": "^1.2.3",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"open-cli": "^7.2.0", "open-cli": "^7.2.0",
"prettier-2": "npm:prettier@^2",
"prettier": "^3.2.1", "prettier": "^3.2.1",
"prettier-2": "npm:prettier@^2",
"pretty-format": "^29.5.0", "pretty-format": "^29.5.0",
"pug": "^3.0.0", "pug": "^3.0.0",
"pug-loader": "^2.4.0", "pug-loader": "^2.4.0",

71
types.d.ts vendored
View File

@ -1764,7 +1764,7 @@ declare class Compilation {
>; >;
afterProcessAssets: SyncHook<[CompilationAssets]>; afterProcessAssets: SyncHook<[CompilationAssets]>;
processAdditionalAssets: AsyncSeriesHook<[CompilationAssets]>; processAdditionalAssets: AsyncSeriesHook<[CompilationAssets]>;
needAdditionalSeal: SyncBailHook<[], boolean>; needAdditionalSeal: SyncBailHook<[], undefined | boolean>;
afterSeal: AsyncSeriesHook<[]>; afterSeal: AsyncSeriesHook<[]>;
renderManifest: SyncWaterfallHook< renderManifest: SyncWaterfallHook<
[RenderManifestEntry[], RenderManifestOptions] [RenderManifestEntry[], RenderManifestOptions]
@ -1790,11 +1790,11 @@ declare class Compilation {
get normalModuleLoader(): SyncHook<[object, NormalModule]>; get normalModuleLoader(): SyncHook<[object, NormalModule]>;
}>; }>;
name?: string; name?: string;
startTime: any; startTime?: number;
endTime: any; endTime?: number;
compiler: Compiler; compiler: Compiler;
resolverFactory: ResolverFactory; resolverFactory: ResolverFactory;
inputFileSystem: InputFileSystem; inputFileSystem: null | InputFileSystem;
fileSystemInfo: FileSystemInfo; fileSystemInfo: FileSystemInfo;
valueCacheVersions: Map<string, string | Set<string>>; valueCacheVersions: Map<string, string | Set<string>>;
requestShortener: RequestShortener; requestShortener: RequestShortener;
@ -2247,13 +2247,13 @@ declare class Compiler {
root: Compiler; root: Compiler;
outputPath: string; outputPath: string;
watching?: Watching; watching?: Watching;
outputFileSystem: OutputFileSystem; outputFileSystem: null | OutputFileSystem;
intermediateFileSystem: IntermediateFileSystem; intermediateFileSystem: null | IntermediateFileSystem;
inputFileSystem: InputFileSystem; inputFileSystem: null | InputFileSystem;
watchFileSystem: WatchFileSystem; watchFileSystem: null | WatchFileSystem;
recordsInputPath: null | string; recordsInputPath: null | string;
recordsOutputPath: null | string; recordsOutputPath: null | string;
records: object; records: Record<string, Record<number, any>>;
managedPaths: Set<string | RegExp>; managedPaths: Set<string | RegExp>;
unmanagedPaths: Set<string | RegExp>; unmanagedPaths: Set<string | RegExp>;
immutablePaths: Set<string | RegExp>; immutablePaths: Set<string | RegExp>;
@ -2275,7 +2275,7 @@ declare class Compiler {
Module, Module,
{ {
buildInfo: object; buildInfo: object;
references: WeakMap<Dependency, Module>; references?: WeakMap<Dependency, Module>;
memCache: WeakTupleMap<any, any>; memCache: WeakTupleMap<any, any>;
} }
>; >;
@ -7661,7 +7661,7 @@ declare class Module extends DependenciesBlock {
index: null | number; index: null | number;
index2: null | number; index2: null | number;
depth: null | number; depth: null | number;
issuer: null | Module; issuer?: null | Module;
get usedExports(): null | boolean | SortableSet<string>; get usedExports(): null | boolean | SortableSet<string>;
get optimizationBailout(): ( get optimizationBailout(): (
| string | string
@ -7919,8 +7919,8 @@ declare class ModuleGraph {
module: Module, module: Module,
indexInBlock?: number indexInBlock?: number
): void; ): void;
getParentModule(dependency: Dependency): Module; getParentModule(dependency: Dependency): undefined | Module;
getParentBlock(dependency: Dependency): DependenciesBlock; getParentBlock(dependency: Dependency): undefined | DependenciesBlock;
getParentBlockIndex(dependency: Dependency): number; getParentBlockIndex(dependency: Dependency): number;
setResolvedModule( setResolvedModule(
originModule: Module, originModule: Module,
@ -7953,13 +7953,13 @@ declare class ModuleGraph {
getOutgoingConnections(module: Module): Iterable<ModuleGraphConnection>; getOutgoingConnections(module: Module): Iterable<ModuleGraphConnection>;
getIncomingConnectionsByOriginModule( getIncomingConnectionsByOriginModule(
module: Module module: Module
): Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>; ): Map<undefined | null | Module, ReadonlyArray<ModuleGraphConnection>>;
getOutgoingConnectionsByModule( getOutgoingConnectionsByModule(
module: Module module: Module
): undefined | Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>; ): undefined | Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>;
getProfile(module: Module): null | ModuleProfile; getProfile(module: Module): null | ModuleProfile;
setProfile(module: Module, profile: null | ModuleProfile): void; setProfile(module: Module, profile: null | ModuleProfile): void;
getIssuer(module: Module): null | Module; getIssuer(module: Module): undefined | null | Module;
setIssuer(module: Module, issuer: null | Module): void; setIssuer(module: Module, issuer: null | Module): void;
setIssuerIfUnset(module: Module, issuer: null | Module): void; setIssuerIfUnset(module: Module, issuer: null | Module): void;
getOptimizationBailout( getOptimizationBailout(
@ -8020,6 +8020,7 @@ declare class ModuleGraphConnection {
explanation?: string, explanation?: string,
weak?: boolean, weak?: boolean,
condition?: condition?:
| null
| false | false
| ((arg0: ModuleGraphConnection, arg1: RuntimeSpec) => ConnectionState) | ((arg0: ModuleGraphConnection, arg1: RuntimeSpec) => ConnectionState)
); );
@ -11352,8 +11353,12 @@ declare interface RunCallback<T> {
(err: null | Error, result?: T): any; (err: null | Error, result?: T): any;
} }
declare class RuntimeChunkPlugin { declare class RuntimeChunkPlugin {
constructor(options?: any); constructor(options: { name?: (entrypoint: { name: string }) => string });
options: any; options: {
name:
| ((entrypoint: { name: string }) => string)
| ((entrypoint: Entrypoint) => string);
};
/** /**
* Apply the plugin * Apply the plugin
@ -11430,7 +11435,7 @@ declare abstract class RuntimeTemplate {
compilation: Compilation; compilation: Compilation;
outputOptions: OutputNormalized; outputOptions: OutputNormalized;
requestShortener: RequestShortener; requestShortener: RequestShortener;
globalObject: string; globalObject?: string;
contentHashReplacement: string; contentHashReplacement: string;
isIIFE(): undefined | boolean; isIIFE(): undefined | boolean;
isModule(): undefined | boolean; isModule(): undefined | boolean;
@ -11444,15 +11449,15 @@ declare abstract class RuntimeTemplate {
supportsDynamicImport(): undefined | boolean; supportsDynamicImport(): undefined | boolean;
supportsEcmaScriptModuleSyntax(): undefined | boolean; supportsEcmaScriptModuleSyntax(): undefined | boolean;
supportTemplateLiteral(): undefined | boolean; supportTemplateLiteral(): undefined | boolean;
returningFunction(returnValue?: any, args?: string): string; returningFunction(returnValue: string, args?: string): string;
basicFunction(args?: any, body?: any): string; basicFunction(args: string, body: string | string[]): string;
concatenation(...args: (string | { expr: string })[]): string; concatenation(...args: (string | { expr: string })[]): string;
expressionFunction(expression?: any, args?: string): string; expressionFunction(expression: string, args?: string): string;
emptyFunction(): "x => {}" | "function() {}"; emptyFunction(): string;
destructureArray(items?: any, value?: any): string; destructureArray(items: string[], value: string): string;
destructureObject(items?: any, value?: any): string; destructureObject(items: string[], value: string): string;
iife(args?: any, body?: any): string; iife(args: string, body: string): string;
forEach(variable?: any, array?: any, body?: any): string; forEach(variable: string, array: string, body: string | string[]): string;
/** /**
* Add a comment * Add a comment
@ -11521,7 +11526,7 @@ declare abstract class RuntimeTemplate {
/** /**
* the request that should be printed as comment * the request that should be printed as comment
*/ */
request: string; request?: string;
/** /**
* expression to use as id expression * expression to use as id expression
*/ */
@ -11543,7 +11548,7 @@ declare abstract class RuntimeTemplate {
/** /**
* the request that should be printed as comment * the request that should be printed as comment
*/ */
request: string; request?: string;
/** /**
* if the dependency is weak (will create a nice error message) * if the dependency is weak (will create a nice error message)
*/ */
@ -11561,7 +11566,7 @@ declare abstract class RuntimeTemplate {
/** /**
* the request that should be printed as comment * the request that should be printed as comment
*/ */
request: string; request?: string;
/** /**
* if the dependency is weak (will create a nice error message) * if the dependency is weak (will create a nice error message)
*/ */
@ -11763,7 +11768,7 @@ declare abstract class RuntimeTemplate {
/** /**
* the async block * the async block
*/ */
block: AsyncDependenciesBlock; block?: AsyncDependenciesBlock;
/** /**
* the message * the message
*/ */
@ -12418,8 +12423,8 @@ declare class Stats {
constructor(compilation: Compilation); constructor(compilation: Compilation);
compilation: Compilation; compilation: Compilation;
get hash(): string; get hash(): string;
get startTime(): any; get startTime(): number;
get endTime(): any; get endTime(): number;
hasWarnings(): boolean; hasWarnings(): boolean;
hasErrors(): boolean; hasErrors(): boolean;
toJson(options?: string | boolean | StatsOptions): StatsCompilation; toJson(options?: string | boolean | StatsOptions): StatsCompilation;
@ -13398,7 +13403,7 @@ declare abstract class Watching {
declare abstract class WeakTupleMap<T extends any[], V> { declare abstract class WeakTupleMap<T extends any[], V> {
set(...args: [T, ...V[]]): void; set(...args: [T, ...V[]]): void;
has(...args: T): boolean; has(...args: T): boolean;
get(...args: T): V; get(...args: T): undefined | V;
provide(...args: [T, ...(() => V)[]]): V; provide(...args: [T, ...(() => V)[]]): V;
delete(...args: T): void; delete(...args: T): void;
clear(): void; clear(): void;

View File

@ -1107,6 +1107,11 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/glob-to-regexp@^0.4.4":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@types/glob-to-regexp/-/glob-to-regexp-0.4.4.tgz#409e71290253203185b1ea8a3d6ea406a4bdc902"
integrity sha512-nDKoaKJYbnn1MZxUY0cA1bPmmgZbg0cTq7Rh13d0KWYNOiKbqoR+2d89SnRPszGh7ROzSwZ/GOjZ4jPbmmZ6Eg==
"@types/graceful-fs@^4.1.3": "@types/graceful-fs@^4.1.3":
version "4.1.6" version "4.1.6"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae"