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

View File

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

View File

@ -103,6 +103,7 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./ModuleFactory")} ModuleFactory */
/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */
/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
/** @typedef {import("./RequestShortener")} RequestShortener */
@ -113,9 +114,13 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */
/** @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 {WeakMap<Dependency, Module>} References */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/**
* @callback Callback
* @param {(WebpackError | null)=} err
@ -824,7 +829,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
/** @type {AsyncSeriesHook<[CompilationAssets]>} */
processAdditionalAssets: new AsyncSeriesHook(["assets"]),
/** @type {SyncBailHook<[], boolean>} */
/** @type {SyncBailHook<[], boolean | undefined>} */
needAdditionalSeal: new SyncBailHook([]),
/** @type {AsyncSeriesHook<[]>} */
afterSeal: new AsyncSeriesHook([]),
@ -878,7 +883,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
});
/** @type {string=} */
this.name = undefined;
/** @type {number | undefined} */
this.startTime = undefined;
/** @type {number | undefined} */
this.endTime = undefined;
/** @type {Compiler} */
this.compiler = compiler;
@ -1345,6 +1352,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @returns {void}
*/
_buildModule(module, callback) {
/** @type {ModuleProfile | undefined} */
const currentProfile = this.profile
? this.moduleGraph.getProfile(module)
: undefined;
@ -1375,7 +1383,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.options,
this,
this.resolverFactory.get("normal", module.resolveOptions),
this.inputFileSystem,
/** @type {InputFileSystem} */ (this.inputFileSystem),
err => {
if (currentProfile !== undefined) {
currentProfile.markBuildingEnd();
@ -1418,6 +1426,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @returns {void}
*/
processModuleDependenciesNonRecursive(module) {
/**
* @param {DependenciesBlock} block block
*/
const processDependenciesBlock = block => {
if (block.dependencies) {
let i = 0;
@ -1494,6 +1505,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
if (--inProgressTransitive === 0) onTransitiveTasksFinished();
};
/**
* @param {WebpackError=} err error
* @returns {void}
*/
const onTransitiveTasksFinished = err => {
if (err) return callback(err);
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) {
const moduleMemCacheCache = this.compiler.moduleMemCaches;
if (!moduleMemCacheCache) return;
@ -2280,8 +2299,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
let statReferencesChanged = 0;
let statWithoutBuild = 0;
/**
* @param {Module} module module
* @returns {References | undefined} references
*/
const computeReferences = module => {
/** @type {WeakMap<Dependency, Module>} */
/** @type {References | undefined} */
let references = undefined;
for (const connection of moduleGraph.getOutgoingConnections(module)) {
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 {WeakMap<Dependency, Module>} references references
* @param {References | undefined} references references
* @returns {boolean} true, when the references differ
*/
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 => {
let affected = false;
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.
They will use the runtime(s) from referenced entrypoints instead.
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();
this.errors.push(err);
}
if (dependOn) {
const entry = this.entrypoints.get(name);
const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
const referencedChunks = entry
.getEntrypointChunk()
.getAllReferencedChunks();
@ -2930,7 +2957,7 @@ Remove the 'runtime' option from the entrypoint.`);
connectChunkGroupParentAndChild(dependency, entry);
}
} else if (runtime) {
const entry = this.entrypoints.get(name);
const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name));
let chunk = this.namedChunks.get(runtime);
if (chunk) {
if (!runtimeChunks.has(chunk)) {
@ -2941,7 +2968,9 @@ Did you mean to use 'dependOn: ${JSON.stringify(
runtime
)}' 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.`);
const entryChunk = entry.getEntrypointChunk();
const entryChunk =
/** @type {Chunk} */
(entry.getEntrypointChunk());
err.chunk = entryChunk;
this.errors.push(err);
entry.setRuntimeChunk(entryChunk);
@ -4589,6 +4618,10 @@ This prevents using hashes of each other and should be avoided.`);
let assetInfo;
let inTry = true;
/**
* @param {Error} err error
* @returns {void}
*/
const errorAndCallback = err => {
const filename =
file ||
@ -5101,7 +5134,8 @@ This prevents using hashes of each other and should be avoided.`);
chunk
)) {
__webpack_require_module__(
moduleArgumentsMap.get(runtimeModule)
/** @type {ExecuteModuleArgument} */
(moduleArgumentsMap.get(runtimeModule))
);
}
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").WebpackPluginInstance} WebpackPluginInstance */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Compilation").References} References */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */
/** @typedef {import("./util/WeakTupleMap")} WeakTupleMap */
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
@ -86,6 +88,9 @@ const { isSourceEqual } = require("./util/source");
* @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
* @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
* @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) => {
/** @type {Object<string, any>} */
const o = {};
for (const k of keys.sort()) {
o[k] = obj[k];
@ -208,9 +214,9 @@ class Compiler {
this.webpack = webpack;
/** @type {string=} */
/** @type {string | undefined} */
this.name = undefined;
/** @type {Compilation=} */
/** @type {Compilation | undefined} */
this.parentCompilation = undefined;
/** @type {Compiler} */
this.root = this;
@ -219,19 +225,20 @@ class Compiler {
/** @type {Watching | undefined} */
this.watching = undefined;
/** @type {OutputFileSystem} */
/** @type {OutputFileSystem | null} */
this.outputFileSystem = null;
/** @type {IntermediateFileSystem} */
/** @type {IntermediateFileSystem | null} */
this.intermediateFileSystem = null;
/** @type {InputFileSystem} */
/** @type {InputFileSystem | null} */
this.inputFileSystem = null;
/** @type {WatchFileSystem} */
/** @type {WatchFileSystem | null} */
this.watchFileSystem = null;
/** @type {string|null} */
this.recordsInputPath = null;
/** @type {string|null} */
this.recordsOutputPath = null;
/** @type {Record<string, Record<number, TODO>>} */
this.records = {};
/** @type {Set<string | RegExp>} */
this.managedPaths = new Set();
@ -265,7 +272,7 @@ class Compiler {
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.compilerPath = "";
@ -286,7 +293,7 @@ class Compiler {
/** @type {NormalModuleFactory | undefined} */
this._lastNormalModuleFactory = undefined;
/** @private @type {WeakMap<Source, { sizeOnlySource: SizeOnlySource, writtenTo: Map<string, number> }>} */
/** @private @type {WeakMap<Source, CacheEntry>} */
this._assetEmittingSourceCache = new WeakMap();
/** @private @type {Map<string, number>} */
this._assetEmittingWrittenFiles = new Map();
@ -645,8 +652,13 @@ class Compiler {
* @returns {void}
*/
emitAssets(compilation, callback) {
/** @type {string} */
let outputPath;
/**
* @param {Error=} err error
* @returns {void}
*/
const emitFiles = err => {
if (err) return callback(err);
@ -676,10 +688,15 @@ class Compiler {
includesHash(targetFile, info.fullhash));
}
/**
* @param {Error=} err error
* @returns {void}
*/
const writeOut = err => {
if (err) return callback(err);
const targetPath = join(
this.outputFileSystem,
/** @type {OutputFileSystem} */
(this.outputFileSystem),
outputPath,
targetFile
);
@ -699,6 +716,7 @@ class Compiler {
this._assetEmittingSourceCache.set(source, cacheEntry);
}
/** @type {SimilarEntry | undefined} */
let similarEntry;
const checkSimilarFile = () => {
@ -762,9 +780,11 @@ ${other}`);
if (targetFileGeneration === undefined) {
const newGeneration = 1;
this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
cacheEntry.writtenTo.set(targetPath, newGeneration);
/** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, newGeneration);
} else {
cacheEntry.writtenTo.set(targetPath, targetFileGeneration);
/** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, targetFileGeneration);
}
callback();
};
@ -775,7 +795,8 @@ ${other}`);
* @returns {void}
*/
const doWrite = content => {
this.outputFileSystem.writeFile(targetPath, content, err => {
/** @type {OutputFileSystem} */
(this.outputFileSystem).writeFile(targetPath, content, err => {
if (err) return callback(err);
// information marker that the asset has been emitted
@ -786,7 +807,8 @@ ${other}`);
targetFileGeneration === undefined
? 1
: targetFileGeneration + 1;
cacheEntry.writtenTo.set(targetPath, newGeneration);
/** @type {CacheEntry} */
(cacheEntry).writtenTo.set(targetPath, newGeneration);
this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
this.hooks.assetEmitted.callAsync(
file,
@ -802,16 +824,33 @@ ${other}`);
});
};
/**
* @param {number} size size
*/
const updateWithReplacementSource = size => {
updateFileWithReplacementSource(file, cacheEntry, size);
similarEntry.size = size;
if (similarEntry.waiting !== undefined) {
for (const { file, cacheEntry } of similarEntry.waiting) {
updateFileWithReplacementSource(
file,
/** @type {CacheEntry} */ (cacheEntry),
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);
}
}
};
/**
* @param {string} file file
* @param {CacheEntry} cacheEntry cache entry
* @param {number} size size
*/
const updateFileWithReplacementSource = (
file,
cacheEntry,
@ -828,6 +867,10 @@ ${other}`);
});
};
/**
* @param {IStats} stats stats
* @returns {void}
*/
const processExistingFile = stats => {
// skip emitting if it's already there and an immutable file
if (immutable) {
@ -874,7 +917,9 @@ ${other}`);
// if the target file has already been written
if (targetFileGeneration !== undefined) {
// 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 yes, we may skip writing the file
// if it's already there
@ -882,9 +927,15 @@ ${other}`);
if (this._assetEmittingPreviousFiles.has(targetPath)) {
// We assume that assets from the last compilation say intact on disk (they are not removed)
compilation.updateAsset(file, cacheEntry.sizeOnlySource, {
size: cacheEntry.sizeOnlySource.size()
});
compilation.updateAsset(
file,
/** @type {CacheEntry} */ (cacheEntry).sizeOnlySource,
{
size:
/** @type {CacheEntry} */
(cacheEntry).sizeOnlySource.size()
}
);
return callback();
} else {
@ -903,10 +954,10 @@ ${other}`);
if (checkSimilarFile()) return;
if (this.options.output.compareBeforeEmit) {
this.outputFileSystem.stat(targetPath, (err, stats) => {
const exists = !err && stats.isFile();
const exists = !err && /** @type {IStats} */ (stats).isFile();
if (exists) {
processExistingFile(stats);
processExistingFile(/** @type {IStats} */ (stats));
} else {
processMissingFile();
}
@ -917,7 +968,7 @@ ${other}`);
};
if (targetFile.match(/\/|\\/)) {
const fs = this.outputFileSystem;
const fs = /** @type {OutputFileSystem} */ (this.outputFileSystem);
const dir = dirname(fs, join(fs, outputPath, targetFile));
mkdirp(fs, dir, writeOut);
} else {
@ -946,7 +997,11 @@ ${other}`);
this.hooks.emit.callAsync(compilation, err => {
if (err) return callback(err);
outputPath = compilation.getPath(this.outputPath, {});
mkdirp(this.outputFileSystem, outputPath, emitFiles);
mkdirp(
/** @type {OutputFileSystem} */ (this.outputFileSystem),
outputPath,
emitFiles
);
});
}
@ -982,7 +1037,8 @@ ${other}`);
*/
_emitRecords(callback) {
const writeFile = () => {
this.outputFileSystem.writeFile(
/** @type {OutputFileSystem} */
(this.outputFileSystem).writeFile(
/** @type {string} */ (this.recordsOutputPath),
JSON.stringify(
this.records,
@ -1006,16 +1062,20 @@ ${other}`);
};
const recordsOutputPathDirectory = dirname(
this.outputFileSystem,
/** @type {OutputFileSystem} */ (this.outputFileSystem),
/** @type {string} */ (this.recordsOutputPath)
);
if (!recordsOutputPathDirectory) {
return writeFile();
}
mkdirp(this.outputFileSystem, recordsOutputPathDirectory, err => {
if (err) return callback(err);
writeFile();
});
mkdirp(
/** @type {OutputFileSystem} */ (this.outputFileSystem),
recordsOutputPathDirectory,
err => {
if (err) return callback(err);
writeFile();
}
);
}
/**
@ -1055,12 +1115,14 @@ ${other}`);
this.records = {};
return callback();
}
this.inputFileSystem.stat(this.recordsInputPath, err => {
/** @type {InputFileSystem} */
(this.inputFileSystem).stat(this.recordsInputPath, err => {
// It doesn't exist
// We can ignore this.
if (err) return callback();
this.inputFileSystem.readFile(
/** @type {InputFileSystem} */
(this.inputFileSystem).readFile(
/** @type {string} */ (this.recordsInputPath),
(err, content) => {
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
*/
/** @typedef {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} GetConditionFn */
const TRANSITIVE = Symbol("transitive");
const getIgnoredModule = memoize(() => {
@ -235,7 +237,7 @@ class Dependency {
/**
* @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) {
return null;

View File

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

View File

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

View File

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

View File

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

View File

@ -497,7 +497,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
/**
* @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) {
return (connection, runtime) => {

View File

@ -35,7 +35,7 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
/**
* @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) {
return connection => {

View File

@ -117,7 +117,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
/**
* @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) {
return getDependencyUsedByExportsCondition(

View File

@ -30,7 +30,7 @@ class LoaderDependency extends ModuleDependency {
/**
* @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) {
return false;

View File

@ -31,7 +31,7 @@ class LoaderImportDependency extends ModuleDependency {
/**
* @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) {
return false;

View File

@ -56,7 +56,7 @@ class URLDependency extends ModuleDependency {
/**
* @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) {
return getDependencyUsedByExportsCondition(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

71
types.d.ts vendored
View File

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

View File

@ -1107,6 +1107,11 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
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":
version "4.1.6"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae"