mirror of https://github.com/webpack/webpack.git
				
				
				
			fix: a lot of types (#19486)
This commit is contained in:
		
							parent
							
								
									ea3ba3dfcc
								
							
						
					
					
						commit
						bc258291f6
					
				|  | @ -6,6 +6,8 @@ test/**/*.* | |||
| !test/*.cjs | ||||
| !test/*.mjs | ||||
| !test/**/webpack.config.js | ||||
| !test/**/webpack.config.cjs | ||||
| !test/**/webpack.config.mjs | ||||
| !test/**/test.config.js | ||||
| !test/**/test.filter.js | ||||
| !test/**/errors.js | ||||
|  | @ -15,7 +17,6 @@ test/**/*.* | |||
| !test/*.md | ||||
| !test/helpers/*.* | ||||
| !test/benchmarkCases/**/*.mjs | ||||
| !test/_helpers/**/*.mjs | ||||
| test/js/**/*.* | ||||
| 
 | ||||
| # Ignore some folders | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| declare module "*.json"; | ||||
| 
 | ||||
| type Env = Record<string, any>; | ||||
| type TestOptions = { testPath: string, srcPath: string }; | ||||
| 
 | ||||
| declare namespace jest { | ||||
| 	interface Matchers<R> { | ||||
| 		toBeTypeOf: ( | ||||
|  |  | |||
|  | @ -245,9 +245,9 @@ type AdditionalData = { | |||
| }; | ||||
| 
 | ||||
| type WebpackLoaderContextCallback = ( | ||||
| 	err: Error | undefined | null, | ||||
| 	err: undefined | null | Error, | ||||
| 	content?: string | Buffer, | ||||
| 	sourceMap?: string | SourceMap, | ||||
| 	sourceMap?: null | string | SourceMap, | ||||
| 	additionalData?: AdditionalData | ||||
| ) => void; | ||||
| 
 | ||||
|  |  | |||
|  | @ -187,13 +187,26 @@ export type ExternalItem = | |||
| 	| RegExp | ||||
| 	| string | ||||
| 	| (ExternalItemObjectKnown & ExternalItemObjectUnknown) | ||||
| 	| ( | ||||
| 			| (( | ||||
| 					data: ExternalItemFunctionData, | ||||
| 					callback: (err?: Error | null, result?: ExternalItemValue) => void | ||||
| 			  ) => void) | ||||
| 			| ((data: ExternalItemFunctionData) => Promise<ExternalItemValue>) | ||||
| 	  ); | ||||
| 	| ExternalItemFunction; | ||||
| /** | ||||
|  * The function is called on each dependency. | ||||
|  */ | ||||
| export type ExternalItemFunction = | ||||
| 	| ExternalItemFunctionCallback | ||||
| 	| ExternalItemFunctionPromise; | ||||
| /** | ||||
|  * The function is called on each dependency (`function(context, request, callback(err, result))`). | ||||
|  */ | ||||
| export type ExternalItemFunctionCallback = ( | ||||
| 	data: ExternalItemFunctionData, | ||||
| 	callback: (err?: Error | null, result?: ExternalItemValue) => void | ||||
| ) => void; | ||||
| /** | ||||
|  * The function is called on each dependency (`function(context, request)`). | ||||
|  */ | ||||
| export type ExternalItemFunctionPromise = ( | ||||
| 	data: ExternalItemFunctionData | ||||
| ) => Promise<ExternalItemValue>; | ||||
| /** | ||||
|  * Specifies the default type of externals ('amd*', 'umd*', 'system' and 'jsonp' depend on output.libraryTarget set to the same value). | ||||
|  */ | ||||
|  | @ -349,13 +362,7 @@ export type ResolvePluginInstance = | |||
|  */ | ||||
| export type RuleSetUse = | ||||
| 	| (Falsy | RuleSetUseItem)[] | ||||
| 	| ((data: { | ||||
| 			resource: string; | ||||
| 			realResource: string; | ||||
| 			resourceQuery: string; | ||||
| 			issuer: string; | ||||
| 			compiler: string; | ||||
| 	  }) => (Falsy | RuleSetUseItem)[]) | ||||
| 	| RuleSetUseFunction | ||||
| 	| RuleSetUseItem; | ||||
| /** | ||||
|  * A description of an applied loader. | ||||
|  | @ -375,8 +382,14 @@ export type RuleSetUseItem = | |||
| 			 */ | ||||
| 			options?: RuleSetLoaderOptions; | ||||
| 	  } | ||||
| 	| ((data: object) => RuleSetUseItem | (Falsy | RuleSetUseItem)[]) | ||||
| 	| RuleSetUseFunction | ||||
| 	| RuleSetLoader; | ||||
| /** | ||||
|  * The function is called on each data and return rule set item. | ||||
|  */ | ||||
| export type RuleSetUseFunction = ( | ||||
| 	data: import("../lib/rules/RuleSetCompiler").EffectData | ||||
| ) => RuleSetUseItem | (Falsy | RuleSetUseItem)[]; | ||||
| /** | ||||
|  * A list of rules. | ||||
|  */ | ||||
|  | @ -390,10 +403,10 @@ export type GeneratorOptionsByModuleType = GeneratorOptionsByModuleTypeKnown & | |||
|  * Don't parse files matching. It's matched against the full resolved request. | ||||
|  */ | ||||
| export type NoParse = | ||||
| 	| (RegExp | string | Function)[] | ||||
| 	| (RegExp | string | ((content: string) => boolean))[] | ||||
| 	| RegExp | ||||
| 	| string | ||||
| 	| Function; | ||||
| 	| ((content: string) => boolean); | ||||
| /** | ||||
|  * Specify options for each parser. | ||||
|  */ | ||||
|  | @ -424,8 +437,19 @@ export type OptimizationRuntimeChunk = | |||
| 			/** | ||||
| 			 * The name or name factory for the runtime chunks. | ||||
| 			 */ | ||||
| 			name?: string | Function; | ||||
| 			name?: | ||||
| 				| string | ||||
| 				| import("../lib/optimize/RuntimeChunkPlugin").RuntimeChunkFunction; | ||||
| 	  }; | ||||
| /** | ||||
|  * A function returning cache groups. | ||||
|  */ | ||||
| export type OptimizationSplitChunksGetCacheGroups = ( | ||||
| 	module: import("../lib/Module") | ||||
| ) => | ||||
| 	| OptimizationSplitChunksCacheGroup | ||||
| 	| OptimizationSplitChunksCacheGroup[] | ||||
| 	| void; | ||||
| /** | ||||
|  * Size description for limits. | ||||
|  */ | ||||
|  | @ -794,6 +818,33 @@ export type EntryNormalized = EntryDynamicNormalized | EntryStaticNormalized; | |||
|  */ | ||||
| export type ExperimentsNormalized = ExperimentsCommon & | ||||
| 	ExperimentsNormalizedExtra; | ||||
| /** | ||||
|  * Get a resolve function with the current resolver options. | ||||
|  */ | ||||
| export type ExternalItemFunctionDataGetResolve = ( | ||||
| 	options?: ResolveOptions | ||||
| ) => | ||||
| 	| ExternalItemFunctionDataGetResolveCallbackResult | ||||
| 	| ExternalItemFunctionDataGetResolveResult; | ||||
| /** | ||||
|  * Result of get a resolve function with the current resolver options. | ||||
|  */ | ||||
| export type ExternalItemFunctionDataGetResolveCallbackResult = ( | ||||
| 	context: string, | ||||
| 	request: string, | ||||
| 	callback: ( | ||||
| 		err?: Error | null, | ||||
| 		result?: string | false, | ||||
| 		resolveRequest?: import("enhanced-resolve").ResolveRequest | ||||
| 	) => void | ||||
| ) => void; | ||||
| /** | ||||
|  * Callback result of get a resolve function with the current resolver options. | ||||
|  */ | ||||
| export type ExternalItemFunctionDataGetResolveResult = ( | ||||
| 	context: string, | ||||
| 	request: string | ||||
| ) => Promise<string>; | ||||
| /** | ||||
|  * The dependency used for the external. | ||||
|  */ | ||||
|  | @ -832,17 +883,8 @@ export type OptimizationRuntimeChunkNormalized = | |||
| 			/** | ||||
| 			 * The name factory for the runtime chunks. | ||||
| 			 */ | ||||
| 			name?: Function; | ||||
| 			name?: import("../lib/optimize/RuntimeChunkPlugin").RuntimeChunkFunction; | ||||
| 	  }; | ||||
| /** | ||||
|  * A function returning cache groups. | ||||
|  */ | ||||
| export type OptimizationSplitChunksGetCacheGroups = ( | ||||
| 	module: import("../lib/Module") | ||||
| ) => | ||||
| 	| OptimizationSplitChunksCacheGroup | ||||
| 	| OptimizationSplitChunksCacheGroup[] | ||||
| 	| void; | ||||
| 
 | ||||
| /** | ||||
|  * Options object as provided by the user. | ||||
|  | @ -1368,7 +1410,7 @@ export interface ModuleOptions { | |||
| 	/** | ||||
| 	 * Cache the resolving of module requests. | ||||
| 	 */ | ||||
| 	unsafeCache?: boolean | Function; | ||||
| 	unsafeCache?: boolean | ((module: import("../lib/Module")) => boolean); | ||||
| 	/** | ||||
| 	 * Enable warnings for partial dynamic dependencies. Deprecated: This option has moved to 'module.parser.javascript.wrappedContextCritical'. | ||||
| 	 */ | ||||
|  | @ -1835,7 +1877,7 @@ export interface OptimizationSplitChunksOptions { | |||
| 			| false | ||||
| 			| RegExp | ||||
| 			| string | ||||
| 			| Function | ||||
| 			| OptimizationSplitChunksGetCacheGroups | ||||
| 			| OptimizationSplitChunksCacheGroup; | ||||
| 	}; | ||||
| 	/** | ||||
|  | @ -2387,7 +2429,11 @@ export interface PerformanceOptions { | |||
| 	/** | ||||
| 	 * Filter function to select assets that are checked. | ||||
| 	 */ | ||||
| 	assetFilter?: Function; | ||||
| 	assetFilter?: ( | ||||
| 		name: import("../lib/Compilation").Asset["name"], | ||||
| 		source: import("../lib/Compilation").Asset["source"], | ||||
| 		assetInfo: import("../lib/Compilation").Asset["info"] | ||||
| 	) => boolean; | ||||
| 	/** | ||||
| 	 * Sets the format of the hints: warnings, errors or nothing at all. | ||||
| 	 */ | ||||
|  | @ -3178,19 +3224,7 @@ export interface ExternalItemFunctionData { | |||
| 	/** | ||||
| 	 * Get a resolve function with the current resolver options. | ||||
| 	 */ | ||||
| 	getResolve?: ( | ||||
| 		options?: ResolveOptions | ||||
| 	) => | ||||
| 		| (( | ||||
| 				context: string, | ||||
| 				request: string, | ||||
| 				callback: ( | ||||
| 					err?: Error | null, | ||||
| 					result?: string | false, | ||||
| 					resolveRequest?: import("enhanced-resolve").ResolveRequest | ||||
| 				) => void | ||||
| 		  ) => void) | ||||
| 		| ((context: string, request: string) => Promise<string>); | ||||
| 	getResolve?: ExternalItemFunctionDataGetResolve; | ||||
| 	/** | ||||
| 	 * The request as written by the user in the require/import expression/statement. | ||||
| 	 */ | ||||
|  | @ -3392,6 +3426,21 @@ export interface JsonGeneratorOptions { | |||
| 	 */ | ||||
| 	JSONParse?: boolean; | ||||
| } | ||||
| /** | ||||
|  * Parser options for JSON modules. | ||||
|  */ | ||||
| export interface JsonParserOptions { | ||||
| 	/** | ||||
| 	 * The depth of json dependency flagged as `exportInfo`. | ||||
| 	 */ | ||||
| 	exportsDepth?: number; | ||||
| 	/** | ||||
| 	 * Function to parser content and return JSON. | ||||
| 	 */ | ||||
| 	parse?: ( | ||||
| 		input: string | ||||
| 	) => Buffer | import("../lib/json/JsonParser").JsonValue; | ||||
| } | ||||
| /** | ||||
|  * Options for the default backend. | ||||
|  */ | ||||
|  | @ -3482,7 +3531,114 @@ export interface ModuleOptionsNormalized { | |||
| 	/** | ||||
| 	 * Cache the resolving of module requests. | ||||
| 	 */ | ||||
| 	unsafeCache?: boolean | Function; | ||||
| 	unsafeCache?: boolean | ((module: import("../lib/Module")) => boolean); | ||||
| } | ||||
| /** | ||||
|  * Enables/Disables integrated optimizations. | ||||
|  */ | ||||
| export interface OptimizationNormalized { | ||||
| 	/** | ||||
| 	 * Avoid wrapping the entry module in an IIFE. | ||||
| 	 */ | ||||
| 	avoidEntryIife?: boolean; | ||||
| 	/** | ||||
| 	 * Check for incompatible wasm types when importing/exporting from/to ESM. | ||||
| 	 */ | ||||
| 	checkWasmTypes?: boolean; | ||||
| 	/** | ||||
| 	 * Define the algorithm to choose chunk ids (named: readable ids for better debugging, deterministic: numeric hash ids for better long term caching, size: numeric ids focused on minimal initial download size, total-size: numeric ids focused on minimal total download size, false: no algorithm used, as custom one can be provided via plugin). | ||||
| 	 */ | ||||
| 	chunkIds?: | ||||
| 		| "natural" | ||||
| 		| "named" | ||||
| 		| "deterministic" | ||||
| 		| "size" | ||||
| 		| "total-size" | ||||
| 		| false; | ||||
| 	/** | ||||
| 	 * Concatenate modules when possible to generate less modules, more efficient code and enable more optimizations by the minimizer. | ||||
| 	 */ | ||||
| 	concatenateModules?: boolean; | ||||
| 	/** | ||||
| 	 * Emit assets even when errors occur. Critical errors are emitted into the generated code and will cause errors at runtime. | ||||
| 	 */ | ||||
| 	emitOnErrors?: boolean; | ||||
| 	/** | ||||
| 	 * Also flag chunks as loaded which contain a subset of the modules. | ||||
| 	 */ | ||||
| 	flagIncludedChunks?: boolean; | ||||
| 	/** | ||||
| 	 * Creates a module-internal dependency graph for top level symbols, exports and imports, to improve unused exports detection. | ||||
| 	 */ | ||||
| 	innerGraph?: boolean; | ||||
| 	/** | ||||
| 	 * Rename exports when possible to generate shorter code (depends on optimization.usedExports and optimization.providedExports, true/"deterministic": generate short deterministic names optimized for caching, "size": generate the shortest possible names). | ||||
| 	 */ | ||||
| 	mangleExports?: ("size" | "deterministic") | boolean; | ||||
| 	/** | ||||
| 	 * Reduce size of WASM by changing imports to shorter strings. | ||||
| 	 */ | ||||
| 	mangleWasmImports?: boolean; | ||||
| 	/** | ||||
| 	 * Merge chunks which contain the same modules. | ||||
| 	 */ | ||||
| 	mergeDuplicateChunks?: boolean; | ||||
| 	/** | ||||
| 	 * Enable minimizing the output. Uses optimization.minimizer. | ||||
| 	 */ | ||||
| 	minimize?: boolean; | ||||
| 	/** | ||||
| 	 * Minimizer(s) to use for minimizing the output. | ||||
| 	 */ | ||||
| 	minimizer?: ("..." | Falsy | WebpackPluginInstance | WebpackPluginFunction)[]; | ||||
| 	/** | ||||
| 	 * Define the algorithm to choose module ids (natural: numeric ids in order of usage, named: readable ids for better debugging, hashed: (deprecated) short hashes as ids for better long term caching, deterministic: numeric hash ids for better long term caching, size: numeric ids focused on minimal initial download size, false: no algorithm used, as custom one can be provided via plugin). | ||||
| 	 */ | ||||
| 	moduleIds?: "natural" | "named" | "hashed" | "deterministic" | "size" | false; | ||||
| 	/** | ||||
| 	 * Avoid emitting assets when errors occur (deprecated: use 'emitOnErrors' instead). | ||||
| 	 */ | ||||
| 	noEmitOnErrors?: boolean; | ||||
| 	/** | ||||
| 	 * Set process.env.NODE_ENV to a specific value. | ||||
| 	 */ | ||||
| 	nodeEnv?: false | string; | ||||
| 	/** | ||||
| 	 * Generate records with relative paths to be able to move the context folder. | ||||
| 	 */ | ||||
| 	portableRecords?: boolean; | ||||
| 	/** | ||||
| 	 * Figure out which exports are provided by modules to generate more efficient code. | ||||
| 	 */ | ||||
| 	providedExports?: boolean; | ||||
| 	/** | ||||
| 	 * Use real [contenthash] based on final content of the assets. | ||||
| 	 */ | ||||
| 	realContentHash?: boolean; | ||||
| 	/** | ||||
| 	 * Removes modules from chunks when these modules are already included in all parents. | ||||
| 	 */ | ||||
| 	removeAvailableModules?: boolean; | ||||
| 	/** | ||||
| 	 * Remove chunks which are empty. | ||||
| 	 */ | ||||
| 	removeEmptyChunks?: boolean; | ||||
| 	/** | ||||
| 	 * Create an additional chunk which contains only the webpack runtime and chunk hash maps. | ||||
| 	 */ | ||||
| 	runtimeChunk?: OptimizationRuntimeChunkNormalized; | ||||
| 	/** | ||||
| 	 * Skip over modules which contain no side effects when exports are not used (false: disabled, 'flag': only use manually placed side effects flag, true: also analyse source code for side effects). | ||||
| 	 */ | ||||
| 	sideEffects?: "flag" | boolean; | ||||
| 	/** | ||||
| 	 * Optimize duplication and caching by splitting chunks by shared modules and cache group. | ||||
| 	 */ | ||||
| 	splitChunks?: false | OptimizationSplitChunksOptions; | ||||
| 	/** | ||||
| 	 * Figure out which exports are used by modules to mangle export names, omit unused exports and generate more efficient code (true: analyse used exports for each runtime, "global": analyse exports globally for all runtimes combined). | ||||
| 	 */ | ||||
| 	usedExports?: "global" | boolean; | ||||
| } | ||||
| /** | ||||
|  * Normalized options affecting the output of the compilation. `output` options tell webpack how to write the compiled files to disk. | ||||
|  | @ -3772,7 +3928,7 @@ export interface WebpackOptionsNormalized { | |||
| 	/** | ||||
| 	 * Enables/Disables integrated optimizations. | ||||
| 	 */ | ||||
| 	optimization: Optimization; | ||||
| 	optimization: OptimizationNormalized; | ||||
| 	/** | ||||
| 	 * Normalized options affecting the output of the compilation. `output` options tell webpack how to write the compiled files to disk. | ||||
| 	 */ | ||||
|  | @ -3999,6 +4155,10 @@ export interface ParserOptionsByModuleTypeKnown { | |||
| 	 * Parser options for javascript modules. | ||||
| 	 */ | ||||
| 	"javascript/esm"?: JavascriptParserOptions; | ||||
| 	/** | ||||
| 	 * Parser options for JSON modules. | ||||
| 	 */ | ||||
| 	json?: JsonParserOptions; | ||||
| } | ||||
| /** | ||||
|  * Specify options for each parser. | ||||
|  |  | |||
|  | @ -57,6 +57,7 @@ const memoize = require("./util/memoize"); | |||
| /** @typedef {import("../declarations/WebpackOptions").Mode} Mode */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").NoParse} NoParse */ | ||||
| /** @typedef {import("./ChunkGraph")} ChunkGraph */ | ||||
| /** @typedef {import("./Compiler")} Compiler */ | ||||
| /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ | ||||
|  | @ -1079,7 +1080,7 @@ class NormalModule extends Module { | |||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {TODO} rule rule | ||||
| 	 * @param {Exclude<NoParse, EXPECTED_ANY[]>} rule rule | ||||
| 	 * @param {string} content content | ||||
| 	 * @returns {boolean} result | ||||
| 	 */ | ||||
|  | @ -1097,7 +1098,7 @@ class NormalModule extends Module { | |||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {TODO} noParseRule no parse rule | ||||
| 	 * @param {undefined | NoParse} noParseRule no parse rule | ||||
| 	 * @param {string} request request | ||||
| 	 * @returns {boolean} check if module should not be parsed, returns "true" if the module should !not! be parsed, returns "false" if the module !must! be parsed | ||||
| 	 */ | ||||
|  |  | |||
|  | @ -504,10 +504,7 @@ class WebpackOptionsApply extends OptionsApply { | |||
| 		} | ||||
| 		if (options.optimization.runtimeChunk) { | ||||
| 			const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin"); | ||||
| 			new RuntimeChunkPlugin( | ||||
| 				/** @type {{ name?: (entrypoint: { name: string }) => string }} */ | ||||
| 				(options.optimization.runtimeChunk) | ||||
| 			).apply(compiler); | ||||
| 			new RuntimeChunkPlugin(options.optimization.runtimeChunk).apply(compiler); | ||||
| 		} | ||||
| 		if (!options.optimization.emitOnErrors) { | ||||
| 			const NoEmitOnErrorsPlugin = require("./NoEmitOnErrorsPlugin"); | ||||
|  |  | |||
|  | @ -648,11 +648,14 @@ const applyModuleDefaults = ( | |||
| 			"unsafeCache", | ||||
| 			/** | ||||
| 			 * @param {Module} module module | ||||
| 			 * @returns {boolean | null | string} true, if we want to cache the module | ||||
| 			 * @returns {boolean} true, if we want to cache the module | ||||
| 			 */ | ||||
| 			module => { | ||||
| 				const name = module.nameForCondition(); | ||||
| 				return name && NODE_MODULES_REGEXP.test(name); | ||||
| 				if (!name) { | ||||
| 					return false; | ||||
| 				} | ||||
| 				return NODE_MODULES_REGEXP.test(name); | ||||
| 			} | ||||
| 		); | ||||
| 	} else { | ||||
|  | @ -683,7 +686,8 @@ const applyModuleDefaults = ( | |||
| 	F(module.parser, "javascript", () => ({})); | ||||
| 	F(module.parser, JSON_MODULE_TYPE, () => ({})); | ||||
| 	D( | ||||
| 		module.parser[JSON_MODULE_TYPE], | ||||
| 		/** @type {NonNullable<ParserOptionsByModuleTypeKnown[JSON_MODULE_TYPE]>} */ | ||||
| 		(module.parser[JSON_MODULE_TYPE]), | ||||
| 		"exportsDepth", | ||||
| 		mode === "development" ? 1 : Infinity | ||||
| 	); | ||||
|  |  | |||
|  | @ -549,16 +549,16 @@ const getNormalizedOptimizationRuntimeChunk = runtimeChunk => { | |||
| 	} | ||||
| 	if (runtimeChunk === true || runtimeChunk === "multiple") { | ||||
| 		return { | ||||
| 			/** | ||||
| 			 * @param {Entrypoint} entrypoint entrypoint | ||||
| 			 * @returns {string} runtime chunk name | ||||
| 			 */ | ||||
| 			name: entrypoint => `runtime~${entrypoint.name}` | ||||
| 		}; | ||||
| 	} | ||||
| 	const { name } = runtimeChunk; | ||||
| 	return { | ||||
| 		name: typeof name === "function" ? name : () => name | ||||
| 		name: | ||||
| 			typeof name === "function" | ||||
| 				? /** @type {Exclude<OptimizationRuntimeChunkNormalized, false>["name"]} */ | ||||
| 					(name) | ||||
| 				: () => /** @type {string} */ (name) | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								lib/index.js
								
								
								
								
							
							
						
						
									
										11
									
								
								lib/index.js
								
								
								
								
							|  | @ -11,20 +11,30 @@ const memoize = require("./util/memoize"); | |||
| /** @typedef {import("../declarations/WebpackOptions").Entry} Entry */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").EntryNormalized} EntryNormalized */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").EntryObject} EntryObject */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItem} ExternalItem */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunction} ExternalItemFunction */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionCallback} ExternalItemFunctionCallback */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionData} ExternalItemFunctionData */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionDataGetResolve} ExternalItemFunctionDataGetResolve */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionDataGetResolveCallbackResult} ExternalItemFunctionDataGetResolveCallbackResult */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionDataGetResolveResult} ExternalItemFunctionDataGetResolveResult */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionPromise} ExternalItemFunctionPromise */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectKnown} ExternalItemObjectKnown */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectUnknown} ExternalItemObjectUnknown */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ExternalItemValue} ExternalItemValue */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").Externals} Externals */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").MemoryCacheOptions} MemoryCacheOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetCondition} RuleSetCondition */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetConditionAbsolute} RuleSetConditionAbsolute */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetUse} RuleSetUse */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetUseFunction} RuleSetUseFunction */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */ | ||||
| /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} Configuration */ | ||||
|  | @ -37,6 +47,7 @@ const memoize = require("./util/memoize"); | |||
| /** @typedef {import("./Compilation").EntryOptions} EntryOptions */ | ||||
| /** @typedef {import("./Compilation").PathData} PathData */ | ||||
| /** @typedef {import("./Compiler").AssetEmittedInfo} AssetEmittedInfo */ | ||||
| /** @typedef {import("./Entrypoint")} Entrypoint */ | ||||
| /** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */ | ||||
| /** @typedef {import("./MultiStats")} MultiStats */ | ||||
| /** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */ | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ const JsonParser = require("./JsonParser"); | |||
| /** @typedef {import("../util/fs").JsonValue} JsonValue */ | ||||
| 
 | ||||
| const validate = createSchemaValidation( | ||||
| 	require("../../schemas/plugins/JsonModulesPluginParser.check.js"), | ||||
| 	() => require("../../schemas/plugins/JsonModulesPluginParser.json"), | ||||
| 	require("../../schemas/plugins/json/JsonModulesPluginParser.check.js"), | ||||
| 	() => require("../../schemas/plugins/json/JsonModulesPluginParser.json"), | ||||
| 	{ | ||||
| 		name: "Json Modules Plugin", | ||||
| 		baseDataPath: "parser" | ||||
|  | @ -25,8 +25,8 @@ const validate = createSchemaValidation( | |||
| ); | ||||
| 
 | ||||
| const validateGenerator = createSchemaValidation( | ||||
| 	require("../../schemas/plugins/JsonModulesPluginGenerator.check.js"), | ||||
| 	() => require("../../schemas/plugins/JsonModulesPluginGenerator.json"), | ||||
| 	require("../../schemas/plugins/json/JsonModulesPluginGenerator.check.js"), | ||||
| 	() => require("../../schemas/plugins/json/JsonModulesPluginGenerator.json"), | ||||
| 	{ | ||||
| 		name: "Json Modules Plugin", | ||||
| 		baseDataPath: "generator" | ||||
|  |  | |||
|  | @ -11,16 +11,15 @@ | |||
| 
 | ||||
| const PLUGIN_NAME = "RuntimeChunkPlugin"; | ||||
| 
 | ||||
| /** @typedef {(entrypoint: { name: string }) => string} RuntimeChunkFunction */ | ||||
| 
 | ||||
| class RuntimeChunkPlugin { | ||||
| 	/** | ||||
| 	 * @param {{ name?: (entrypoint: { name: string }) => string }} options options | ||||
| 	 * @param {{ name?: RuntimeChunkFunction }=} options options | ||||
| 	 */ | ||||
| 	constructor(options) { | ||||
| 		this.options = { | ||||
| 			/** | ||||
| 			 * @param {Entrypoint} entrypoint entrypoint name | ||||
| 			 * @returns {string} runtime chunk name | ||||
| 			 */ | ||||
| 			/** @type {RuntimeChunkFunction} */ | ||||
| 			name: entrypoint => `runtime~${entrypoint.name}`, | ||||
| 			...options | ||||
| 		}; | ||||
|  | @ -41,7 +40,7 @@ class RuntimeChunkPlugin { | |||
| 				if (data.options.runtime === undefined && !data.options.dependOn) { | ||||
| 					// Determine runtime chunk name
 | ||||
| 					let name = | ||||
| 						/** @type {string | ((entrypoint: { name: string }) => string)} */ | ||||
| 						/** @type {string | RuntimeChunkFunction} */ | ||||
| 						(this.options.name); | ||||
| 					if (typeof name === "function") { | ||||
| 						name = name({ name: entryName }); | ||||
|  |  | |||
|  | @ -37,8 +37,7 @@ class BasicEffectRulePlugin { | |||
| 				if (unhandledProperties.has(this.ruleProperty)) { | ||||
| 					unhandledProperties.delete(this.ruleProperty); | ||||
| 
 | ||||
| 					const value = | ||||
| 						rule[/** @type {keyof RuleSetRule} */ (this.ruleProperty)]; | ||||
| 					const value = rule[this.ruleProperty]; | ||||
| 
 | ||||
| 					result.effects.push({ | ||||
| 						type: this.effectType, | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| /** @typedef {import("../../declarations/WebpackOptions").RuleSetConditionOrConditions} RuleSetConditionOrConditions */ | ||||
| /** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ | ||||
| /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ | ||||
| /** @typedef {import("./RuleSetCompiler").EffectData} EffectData */ | ||||
| /** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */ | ||||
| /** @typedef {import("./RuleSetCompiler").RuleConditionFunction} RuleConditionFunction */ | ||||
| 
 | ||||
|  | @ -22,7 +23,7 @@ | |||
| class ObjectMatcherRulePlugin { | ||||
| 	/** | ||||
| 	 * @param {ObjectMatcherRuleKeys} ruleProperty the rule property | ||||
| 	 * @param {string=} dataProperty the data property | ||||
| 	 * @param {keyof EffectData=} dataProperty the data property | ||||
| 	 * @param {RuleConditionFunction=} additionalConditionFunction need to check | ||||
| 	 */ | ||||
| 	constructor(ruleProperty, dataProperty, additionalConditionFunction) { | ||||
|  |  | |||
|  | @ -13,7 +13,9 @@ const { SyncHook } = require("tapable"); | |||
| 
 | ||||
| /** @typedef {(Falsy | RuleSetRule)[]} RuleSetRules */ | ||||
| 
 | ||||
| /** @typedef {(value: string | EffectData) => boolean} RuleConditionFunction */ | ||||
| /** | ||||
|  * @typedef {(value: EffectData[keyof EffectData]) => boolean} RuleConditionFunction | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @typedef {object} RuleCondition | ||||
|  | @ -29,7 +31,19 @@ const { SyncHook } = require("tapable"); | |||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @typedef {Record<string, TODO>} EffectData | ||||
|  * @typedef {object} EffectData | ||||
|  * @property {string=} resource | ||||
|  * @property {string=} realResource | ||||
|  * @property {string=} resourceQuery | ||||
|  * @property {string=} resourceFragment | ||||
|  * @property {string=} scheme | ||||
|  * @property {ImportAttributes=} assertions | ||||
|  * @property {string=} mimetype | ||||
|  * @property {string} dependency | ||||
|  * @property {Record<string, EXPECTED_ANY>} descriptionData | ||||
|  * @property {string=} compiler | ||||
|  * @property {string} issuer | ||||
|  * @property {string} issuerLayer | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  | @ -102,7 +116,7 @@ class RuleSetCompiler { | |||
| 			for (const condition of rule.conditions) { | ||||
| 				const p = condition.property; | ||||
| 				if (Array.isArray(p)) { | ||||
| 					/** @type {EffectData | string | undefined} */ | ||||
| 					/** @type {EffectData | EffectData[keyof EffectData] | undefined} */ | ||||
| 					let current = data; | ||||
| 					for (const subProperty of p) { | ||||
| 						if ( | ||||
|  | @ -110,7 +124,7 @@ class RuleSetCompiler { | |||
| 							typeof current === "object" && | ||||
| 							Object.prototype.hasOwnProperty.call(current, subProperty) | ||||
| 						) { | ||||
| 							current = current[subProperty]; | ||||
| 							current = current[/** @type {keyof EffectData} */ (subProperty)]; | ||||
| 						} else { | ||||
| 							current = undefined; | ||||
| 							break; | ||||
|  | @ -121,7 +135,7 @@ class RuleSetCompiler { | |||
| 						continue; | ||||
| 					} | ||||
| 				} else if (p in data) { | ||||
| 					const value = data[p]; | ||||
| 					const value = data[/** @type {keyof EffectData} */ (p)]; | ||||
| 					if (value !== undefined) { | ||||
| 						if (!condition.fn(value)) return false; | ||||
| 						continue; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ const util = require("util"); | |||
| /** @typedef {import("../../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */ | ||||
| /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ | ||||
| /** @typedef {import("./RuleSetCompiler").Effect} Effect */ | ||||
| /** @typedef {import("./RuleSetCompiler").EffectData} EffectData */ | ||||
| 
 | ||||
| class UseEffectRulePlugin { | ||||
| 	/** | ||||
|  | @ -55,7 +56,7 @@ class UseEffectRulePlugin { | |||
| 					 * @param {string} path options path | ||||
| 					 * @param {string} defaultIdent default ident when none is provided | ||||
| 					 * @param {RuleSetUseItem} item user provided use value | ||||
| 					 * @returns {Effect | ((value: TODO) => Effect[])} effect | ||||
| 					 * @returns {(Effect | ((effectData: EffectData) => Effect[]))} effect | ||||
| 					 */ | ||||
| 					const useToEffect = (path, defaultIdent, item) => { | ||||
| 						if (typeof item === "function") { | ||||
|  | @ -139,7 +140,7 @@ class UseEffectRulePlugin { | |||
| 					/** | ||||
| 					 * @param {string} path current path | ||||
| 					 * @param {RuleSetUse} items user provided use value | ||||
| 					 * @returns {(Effect | ((value: TODO) => Effect[]))[]} effects | ||||
| 					 * @returns {(Effect | ((effectData: EffectData) => Effect[]))[]} effects | ||||
| 					 */ | ||||
| 					const useToEffects = (path, items) => { | ||||
| 						if (Array.isArray(items)) { | ||||
|  | @ -160,10 +161,7 @@ class UseEffectRulePlugin { | |||
| 
 | ||||
| 					if (typeof use === "function") { | ||||
| 						result.effects.push(data => | ||||
| 							useToEffectsWithoutIdent( | ||||
| 								`${path}.use`, | ||||
| 								use(/** @type {TODO} */ (data)) | ||||
| 							) | ||||
| 							useToEffectsWithoutIdent(`${path}.use`, use(data)) | ||||
| 						); | ||||
| 					} else { | ||||
| 						for (const effect of useToEffects(`${path}.use`, use)) { | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ | |||
|     "@types/jest": "^29.5.11", | ||||
|     "@types/mime-types": "^2.1.4", | ||||
|     "@types/node": "^22.13.10", | ||||
|     "@types/xxhashjs": "^0.2.4", | ||||
|     "assemblyscript": "^0.27.34", | ||||
|     "babel-loader": "^10.0.0", | ||||
|     "benchmark": "^2.1.4", | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -1179,12 +1179,26 @@ | |||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "description": "The function is called on each dependency (`function(context, request, callback(err, result))`).", | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "(((data: ExternalItemFunctionData, callback: (err?: (Error | null), result?: ExternalItemValue) => void) => void) | ((data: ExternalItemFunctionData) => Promise<ExternalItemValue>))" | ||||
|           "$ref": "#/definitions/ExternalItemFunction" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     "ExternalItemFunction": { | ||||
|       "description": "The function is called on each dependency.", | ||||
|       "anyOf": [ | ||||
|         { | ||||
|           "$ref": "#/definitions/ExternalItemFunctionCallback" | ||||
|         }, | ||||
|         { | ||||
|           "$ref": "#/definitions/ExternalItemFunctionPromise" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     "ExternalItemFunctionCallback": { | ||||
|       "description": "The function is called on each dependency (`function(context, request, callback(err, result))`).", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((data: ExternalItemFunctionData, callback: (err?: (Error | null), result?: ExternalItemValue) => void) => void)" | ||||
|     }, | ||||
|     "ExternalItemFunctionData": { | ||||
|       "description": "Data object passed as argument when a function is set for 'externals'.", | ||||
|       "type": "object", | ||||
|  | @ -1204,9 +1218,7 @@ | |||
|           "type": "string" | ||||
|         }, | ||||
|         "getResolve": { | ||||
|           "description": "Get a resolve function with the current resolver options.", | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "((options?: ResolveOptions) => ((context: string, request: string, callback: (err?: Error | null, result?: string | false, resolveRequest?: import('enhanced-resolve').ResolveRequest) => void) => void) | ((context: string, request: string) => Promise<string>))" | ||||
|           "$ref": "#/definitions/ExternalItemFunctionDataGetResolve" | ||||
|         }, | ||||
|         "request": { | ||||
|           "description": "The request as written by the user in the require/import expression/statement.", | ||||
|  | @ -1214,6 +1226,26 @@ | |||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "ExternalItemFunctionDataGetResolve": { | ||||
|       "description": "Get a resolve function with the current resolver options.", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((options?: ResolveOptions) => ExternalItemFunctionDataGetResolveCallbackResult | ExternalItemFunctionDataGetResolveResult)" | ||||
|     }, | ||||
|     "ExternalItemFunctionDataGetResolveCallbackResult": { | ||||
|       "description": "Result of get a resolve function with the current resolver options.", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((context: string, request: string, callback: (err?: Error | null, result?: string | false, resolveRequest?: import('enhanced-resolve').ResolveRequest) => void) => void)" | ||||
|     }, | ||||
|     "ExternalItemFunctionDataGetResolveResult": { | ||||
|       "description": "Callback result of get a resolve function with the current resolver options.", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((context: string, request: string) => Promise<string>)" | ||||
|     }, | ||||
|     "ExternalItemFunctionPromise": { | ||||
|       "description": "The function is called on each dependency (`function(context, request)`).", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((data: ExternalItemFunctionData) => Promise<ExternalItemValue>)" | ||||
|     }, | ||||
|     "ExternalItemValue": { | ||||
|       "description": "The dependency used for the external.", | ||||
|       "anyOf": [ | ||||
|  | @ -2023,6 +2055,22 @@ | |||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "JsonParserOptions": { | ||||
|       "description": "Parser options for JSON modules.", | ||||
|       "type": "object", | ||||
|       "additionalProperties": false, | ||||
|       "properties": { | ||||
|         "exportsDepth": { | ||||
|           "description": "The depth of json dependency flagged as `exportInfo`.", | ||||
|           "type": "number" | ||||
|         }, | ||||
|         "parse": { | ||||
|           "description": "Function to parser content and return JSON.", | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "((input: string) => Buffer | import('../lib/json/JsonParser').JsonValue)" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "Layer": { | ||||
|       "description": "Specifies the layer in which modules of this entrypoint are placed.", | ||||
|       "anyOf": [ | ||||
|  | @ -2474,7 +2522,7 @@ | |||
|             }, | ||||
|             { | ||||
|               "instanceof": "Function", | ||||
|               "tsType": "Function" | ||||
|               "tsType": "((module: import('../lib/Module')) => boolean)" | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|  | @ -2534,7 +2582,7 @@ | |||
|             }, | ||||
|             { | ||||
|               "instanceof": "Function", | ||||
|               "tsType": "Function" | ||||
|               "tsType": "((module: import('../lib/Module')) => boolean)" | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|  | @ -2565,7 +2613,7 @@ | |||
|               }, | ||||
|               { | ||||
|                 "instanceof": "Function", | ||||
|                 "tsType": "Function" | ||||
|                 "tsType": "((content: string) => boolean)" | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|  | @ -2583,7 +2631,7 @@ | |||
|         }, | ||||
|         { | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "Function" | ||||
|           "tsType": "((content: string) => boolean)" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|  | @ -2784,6 +2832,173 @@ | |||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "OptimizationNormalized": { | ||||
|       "description": "Enables/Disables integrated optimizations.", | ||||
|       "type": "object", | ||||
|       "additionalProperties": false, | ||||
|       "properties": { | ||||
|         "avoidEntryIife": { | ||||
|           "description": "Avoid wrapping the entry module in an IIFE.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "checkWasmTypes": { | ||||
|           "description": "Check for incompatible wasm types when importing/exporting from/to ESM.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "chunkIds": { | ||||
|           "description": "Define the algorithm to choose chunk ids (named: readable ids for better debugging, deterministic: numeric hash ids for better long term caching, size: numeric ids focused on minimal initial download size, total-size: numeric ids focused on minimal total download size, false: no algorithm used, as custom one can be provided via plugin).", | ||||
|           "enum": [ | ||||
|             "natural", | ||||
|             "named", | ||||
|             "deterministic", | ||||
|             "size", | ||||
|             "total-size", | ||||
|             false | ||||
|           ] | ||||
|         }, | ||||
|         "concatenateModules": { | ||||
|           "description": "Concatenate modules when possible to generate less modules, more efficient code and enable more optimizations by the minimizer.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "emitOnErrors": { | ||||
|           "description": "Emit assets even when errors occur. Critical errors are emitted into the generated code and will cause errors at runtime.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "flagIncludedChunks": { | ||||
|           "description": "Also flag chunks as loaded which contain a subset of the modules.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "innerGraph": { | ||||
|           "description": "Creates a module-internal dependency graph for top level symbols, exports and imports, to improve unused exports detection.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "mangleExports": { | ||||
|           "description": "Rename exports when possible to generate shorter code (depends on optimization.usedExports and optimization.providedExports, true/\"deterministic\": generate short deterministic names optimized for caching, \"size\": generate the shortest possible names).", | ||||
|           "anyOf": [ | ||||
|             { | ||||
|               "enum": ["size", "deterministic"] | ||||
|             }, | ||||
|             { | ||||
|               "type": "boolean" | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "mangleWasmImports": { | ||||
|           "description": "Reduce size of WASM by changing imports to shorter strings.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "mergeDuplicateChunks": { | ||||
|           "description": "Merge chunks which contain the same modules.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "minimize": { | ||||
|           "description": "Enable minimizing the output. Uses optimization.minimizer.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "minimizer": { | ||||
|           "description": "Minimizer(s) to use for minimizing the output.", | ||||
|           "type": "array", | ||||
|           "cli": { | ||||
|             "exclude": true | ||||
|           }, | ||||
|           "items": { | ||||
|             "description": "Plugin of type object or instanceof Function.", | ||||
|             "anyOf": [ | ||||
|               { | ||||
|                 "enum": ["..."] | ||||
|               }, | ||||
|               { | ||||
|                 "$ref": "#/definitions/Falsy" | ||||
|               }, | ||||
|               { | ||||
|                 "$ref": "#/definitions/WebpackPluginInstance" | ||||
|               }, | ||||
|               { | ||||
|                 "$ref": "#/definitions/WebpackPluginFunction" | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "moduleIds": { | ||||
|           "description": "Define the algorithm to choose module ids (natural: numeric ids in order of usage, named: readable ids for better debugging, hashed: (deprecated) short hashes as ids for better long term caching, deterministic: numeric hash ids for better long term caching, size: numeric ids focused on minimal initial download size, false: no algorithm used, as custom one can be provided via plugin).", | ||||
|           "enum": ["natural", "named", "hashed", "deterministic", "size", false] | ||||
|         }, | ||||
|         "noEmitOnErrors": { | ||||
|           "description": "Avoid emitting assets when errors occur (deprecated: use 'emitOnErrors' instead).", | ||||
|           "type": "boolean", | ||||
|           "cli": { | ||||
|             "exclude": true | ||||
|           } | ||||
|         }, | ||||
|         "nodeEnv": { | ||||
|           "description": "Set process.env.NODE_ENV to a specific value.", | ||||
|           "anyOf": [ | ||||
|             { | ||||
|               "enum": [false] | ||||
|             }, | ||||
|             { | ||||
|               "type": "string" | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "portableRecords": { | ||||
|           "description": "Generate records with relative paths to be able to move the context folder.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "providedExports": { | ||||
|           "description": "Figure out which exports are provided by modules to generate more efficient code.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "realContentHash": { | ||||
|           "description": "Use real [contenthash] based on final content of the assets.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "removeAvailableModules": { | ||||
|           "description": "Removes modules from chunks when these modules are already included in all parents.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "removeEmptyChunks": { | ||||
|           "description": "Remove chunks which are empty.", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "runtimeChunk": { | ||||
|           "$ref": "#/definitions/OptimizationRuntimeChunkNormalized" | ||||
|         }, | ||||
|         "sideEffects": { | ||||
|           "description": "Skip over modules which contain no side effects when exports are not used (false: disabled, 'flag': only use manually placed side effects flag, true: also analyse source code for side effects).", | ||||
|           "anyOf": [ | ||||
|             { | ||||
|               "enum": ["flag"] | ||||
|             }, | ||||
|             { | ||||
|               "type": "boolean" | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "splitChunks": { | ||||
|           "description": "Optimize duplication and caching by splitting chunks by shared modules and cache group.", | ||||
|           "anyOf": [ | ||||
|             { | ||||
|               "enum": [false] | ||||
|             }, | ||||
|             { | ||||
|               "$ref": "#/definitions/OptimizationSplitChunksOptions" | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "usedExports": { | ||||
|           "description": "Figure out which exports are used by modules to mangle export names, omit unused exports and generate more efficient code (true: analyse used exports for each runtime, \"global\": analyse exports globally for all runtimes combined).", | ||||
|           "anyOf": [ | ||||
|             { | ||||
|               "enum": ["global"] | ||||
|             }, | ||||
|             { | ||||
|               "type": "boolean" | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "OptimizationRuntimeChunk": { | ||||
|       "description": "Create an additional chunk which contains only the webpack runtime and chunk hash maps.", | ||||
|       "anyOf": [ | ||||
|  | @ -2805,7 +3020,7 @@ | |||
|                 }, | ||||
|                 { | ||||
|                   "instanceof": "Function", | ||||
|                   "tsType": "Function" | ||||
|                   "tsType": "import('../lib/optimize/RuntimeChunkPlugin').RuntimeChunkFunction" | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
|  | @ -2826,7 +3041,7 @@ | |||
|             "name": { | ||||
|               "description": "The name factory for the runtime chunks.", | ||||
|               "instanceof": "Function", | ||||
|               "tsType": "Function" | ||||
|               "tsType": "import('../lib/optimize/RuntimeChunkPlugin').RuntimeChunkFunction" | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | @ -3060,8 +3275,7 @@ | |||
|                 "type": "string" | ||||
|               }, | ||||
|               { | ||||
|                 "instanceof": "Function", | ||||
|                 "tsType": "Function" | ||||
|                 "$ref": "#/definitions/OptimizationSplitChunksGetCacheGroups" | ||||
|               }, | ||||
|               { | ||||
|                 "$ref": "#/definitions/OptimizationSplitChunksCacheGroup" | ||||
|  | @ -3084,8 +3298,7 @@ | |||
|                     "type": "string" | ||||
|                   }, | ||||
|                   { | ||||
|                     "instanceof": "Function", | ||||
|                     "tsType": "Function" | ||||
|                     "$ref": "#/definitions/OptimizationSplitChunksGetCacheGroups" | ||||
|                   } | ||||
|                 ] | ||||
|               } | ||||
|  | @ -3754,6 +3967,9 @@ | |||
|         }, | ||||
|         "javascript/esm": { | ||||
|           "$ref": "#/definitions/JavascriptParserOptions" | ||||
|         }, | ||||
|         "json": { | ||||
|           "$ref": "#/definitions/JsonParserOptions" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|  | @ -3792,7 +4008,7 @@ | |||
|         "assetFilter": { | ||||
|           "description": "Filter function to select assets that are checked.", | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "Function" | ||||
|           "tsType": "((name: import('../lib/Compilation').Asset['name'], source: import('../lib/Compilation').Asset['source'], assetInfo: import('../lib/Compilation').Asset['info'])  => boolean)" | ||||
|         }, | ||||
|         "hints": { | ||||
|           "description": "Sets the format of the hints: warnings, errors or nothing at all.", | ||||
|  | @ -4700,14 +4916,18 @@ | |||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "((data: { resource: string, realResource: string, resourceQuery: string, issuer: string, compiler: string }) => (Falsy | RuleSetUseItem)[])" | ||||
|           "$ref": "#/definitions/RuleSetUseFunction" | ||||
|         }, | ||||
|         { | ||||
|           "$ref": "#/definitions/RuleSetUseItem" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     "RuleSetUseFunction": { | ||||
|       "description": "The function is called on each data and return rule set item.", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((data: import('../lib/rules/RuleSetCompiler').EffectData) => (RuleSetUseItem | (Falsy | RuleSetUseItem)[]))" | ||||
|     }, | ||||
|     "RuleSetUseItem": { | ||||
|       "description": "A description of an applied loader.", | ||||
|       "anyOf": [ | ||||
|  | @ -4738,8 +4958,7 @@ | |||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "instanceof": "Function", | ||||
|           "tsType": "((data: object) => RuleSetUseItem | (Falsy | RuleSetUseItem)[])" | ||||
|           "$ref": "#/definitions/RuleSetUseFunction" | ||||
|         }, | ||||
|         { | ||||
|           "$ref": "#/definitions/RuleSetLoader" | ||||
|  | @ -5613,7 +5832,7 @@ | |||
|           "$ref": "#/definitions/Node" | ||||
|         }, | ||||
|         "optimization": { | ||||
|           "$ref": "#/definitions/Optimization" | ||||
|           "$ref": "#/definitions/OptimizationNormalized" | ||||
|         }, | ||||
|         "output": { | ||||
|           "$ref": "#/definitions/OutputNormalized" | ||||
|  |  | |||
|  | @ -1,7 +0,0 @@ | |||
| /* | ||||
|  * This file was automatically generated. | ||||
|  * DO NOT MODIFY BY HAND. | ||||
|  * Run `yarn special-lint-fix` to update | ||||
|  */ | ||||
| declare const check: (options: import("../../declarations/plugins/JsonModulesPluginGenerator").JsonModulesPluginGeneratorOptions) => boolean; | ||||
| export = check; | ||||
|  | @ -1,11 +0,0 @@ | |||
| { | ||||
|   "title": "JsonModulesPluginGeneratorOptions", | ||||
|   "type": "object", | ||||
|   "additionalProperties": false, | ||||
|   "properties": { | ||||
|     "JSONParse": { | ||||
|       "description": "Use `JSON.parse` when the JSON string is longer than 20 characters.", | ||||
|       "type": "boolean" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -1,7 +0,0 @@ | |||
| /* | ||||
|  * This file was automatically generated. | ||||
|  * DO NOT MODIFY BY HAND. | ||||
|  * Run `yarn special-lint-fix` to update | ||||
|  */ | ||||
| declare const check: (options: import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions) => boolean; | ||||
| export = check; | ||||
|  | @ -1,16 +0,0 @@ | |||
| { | ||||
|   "title": "JsonModulesPluginParserOptions", | ||||
|   "type": "object", | ||||
|   "additionalProperties": false, | ||||
|   "properties": { | ||||
|     "exportsDepth": { | ||||
|       "description": "The depth of json dependency flagged as `exportInfo`.", | ||||
|       "type": "number" | ||||
|     }, | ||||
|     "parse": { | ||||
|       "description": "Function that executes for a module source string and should return json-compatible data.", | ||||
|       "instanceof": "Function", | ||||
|       "tsType": "((input: string) => any)" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| /* | ||||
|  * This file was automatically generated. | ||||
|  * DO NOT MODIFY BY HAND. | ||||
|  * Run `yarn special-lint-fix` to update | ||||
|  */ | ||||
| declare const check: (options: any) => boolean; | ||||
| export = check; | ||||
|  | @ -0,0 +1,3 @@ | |||
| { | ||||
|   "$ref": "../../WebpackOptions.json#/definitions/JsonGeneratorOptions" | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| /* | ||||
|  * This file was automatically generated. | ||||
|  * DO NOT MODIFY BY HAND. | ||||
|  * Run `yarn special-lint-fix` to update | ||||
|  */ | ||||
| declare const check: (options: any) => boolean; | ||||
| export = check; | ||||
|  | @ -0,0 +1,3 @@ | |||
| { | ||||
|   "$ref": "../../WebpackOptions.json#/definitions/JsonParserOptions" | ||||
| } | ||||
|  | @ -4494,6 +4494,19 @@ Object { | |||
|     "multiple": false, | ||||
|     "simpleType": "string", | ||||
|   }, | ||||
|   "module-parser-json-exports-depth": Object { | ||||
|     "configs": Array [ | ||||
|       Object { | ||||
|         "description": "The depth of json dependency flagged as \`exportInfo\`.", | ||||
|         "multiple": false, | ||||
|         "path": "module.parser.json.exportsDepth", | ||||
|         "type": "number", | ||||
|       }, | ||||
|     ], | ||||
|     "description": "The depth of json dependency flagged as \`exportInfo\`.", | ||||
|     "multiple": false, | ||||
|     "simpleType": "number", | ||||
|   }, | ||||
|   "module-rules-compiler": Object { | ||||
|     "configs": Array [ | ||||
|       Object { | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinitionFunction} */ | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| exports.default = function (source) { | ||||
| 	const ref = JSON.parse(source); | ||||
| 	const callback = this.async(); | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinitionFunction} */ | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| exports.default = function (source) { | ||||
| 	const ref = JSON.parse(source); | ||||
| 	const callback = this.async(); | ||||
|  | @ -6,7 +6,7 @@ exports.default = function (source) { | |||
| 		if (err) { | ||||
| 			callback(null, JSON.stringify(`err: ${err && err.message}`)); | ||||
| 		} else { | ||||
| 			callback(null, JSON.stringify(`source: ${JSON.parse(source)}`)); | ||||
| 			callback(null, JSON.stringify(`source: ${JSON.parse(/** @type {string} */ (source))}`)); | ||||
| 		} | ||||
| 	}); | ||||
| }; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinitionFunction} */ | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| exports.default = function (source) { | ||||
| 	const callback = this.async(); | ||||
| 	const ref = JSON.parse(source); | ||||
|  | @ -6,7 +6,7 @@ exports.default = function (source) { | |||
| 		if (err) { | ||||
| 			callback(err); | ||||
| 		} else { | ||||
| 			callback(null, JSON.stringify(`source: ${JSON.parse(source)}`)); | ||||
| 			callback(null, JSON.stringify(`source: ${JSON.parse(/** @type {string} */ (source))}`)); | ||||
| 		} | ||||
| 	}); | ||||
| }; | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ const acornParser = acorn.Parser; | |||
| 
 | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = function (source) { | ||||
| 	/** @type {TODO} */ | ||||
| 	const comments = []; | ||||
| 
 | ||||
| 	const semicolons = new Set(); | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ const Source = require("webpack-sources").Source; | |||
| module.exports = { | ||||
| 	plugins: [ | ||||
| 		compiler => { | ||||
| 			/** @type {Record<string, boolean>} */ | ||||
| 			const files = {}; | ||||
| 			compiler.hooks.assetEmitted.tap( | ||||
| 				"Test", | ||||
|  |  | |||
|  | @ -2,7 +2,8 @@ | |||
| module.exports = { | ||||
| 	mode: "development", | ||||
| 	output: { | ||||
| 		assetModuleFilename: ({ filename }) => { | ||||
| 		assetModuleFilename: ({ filename: _filename }) => { | ||||
| 			const filename = /** @type {string} */ (_filename); | ||||
| 			if (/.png$/.test(filename)) { | ||||
| 				return "images/[\\ext\\]/success-png[ext]"; | ||||
| 			} | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| const path = require("path"); | ||||
| const NormalModule = require("../../../../").NormalModule; | ||||
| 
 | ||||
| /** @typedef {import("../../../../").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "development", | ||||
|  | @ -9,6 +11,7 @@ module.exports = { | |||
| 			{ | ||||
| 				test: /\.png$/, | ||||
| 				type: "asset", | ||||
| 				/** @type {ParserOptionsByModuleTypeKnown['asset']} */ | ||||
| 				parser: { | ||||
| 					dataUrlCondition: (source, { filename, module }) => { | ||||
| 						expect(source).toBeInstanceOf(Buffer); | ||||
|  | @ -23,6 +26,7 @@ module.exports = { | |||
| 			{ | ||||
| 				test: /\.jpg$/, | ||||
| 				type: "asset", | ||||
| 				/** @type {ParserOptionsByModuleTypeKnown['asset']} */ | ||||
| 				parser: { | ||||
| 					dataUrlCondition: (source, { filename, module }) => { | ||||
| 						expect(source).toBeInstanceOf(Buffer); | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ const path = require("path"); | |||
| const fs = require("fs"); | ||||
| const webpack = require("../../../../"); | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| const common = { | ||||
| 	module: { | ||||
| 		rules: [ | ||||
|  | @ -46,6 +47,10 @@ const common = { | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * @param {number} i index | ||||
|  * @returns {import("../../../../").Configuration | undefined} configuration | ||||
|  */ | ||||
| const entry = i => { | ||||
| 	switch (i % 4) { | ||||
| 		case 0: | ||||
|  | @ -80,6 +85,10 @@ const entry = i => { | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * @param {number} i index | ||||
|  * @returns {import("../../../../").Configuration} configuration | ||||
|  */ | ||||
| const esm = i => ({ | ||||
| 	...common, | ||||
| 	...entry(i), | ||||
|  | @ -97,6 +106,10 @@ const esm = i => ({ | |||
| 	} | ||||
| }); | ||||
| 
 | ||||
| /** | ||||
|  * @param {number} i index | ||||
|  * @returns {import("../../../../").Configuration} configuration | ||||
|  */ | ||||
| const node = i => ({ | ||||
| 	...common, | ||||
| 	...entry(i), | ||||
|  | @ -110,6 +123,10 @@ const node = i => ({ | |||
| 	target: "node" | ||||
| }); | ||||
| 
 | ||||
| /** | ||||
|  * @param {number} i index | ||||
|  * @returns {import("../../../../").Configuration} configuration | ||||
|  */ | ||||
| const web = i => ({ | ||||
| 	...common, | ||||
| 	...entry(i), | ||||
|  |  | |||
|  | @ -13,7 +13,10 @@ module.exports = { | |||
| 		generator: { | ||||
| 			asset: { | ||||
| 				dataUrl: (source, { module }) => { | ||||
| 					const mimeType = mimeTypes.lookup(module.nameForCondition()); | ||||
| 					const mimeType = mimeTypes.lookup( | ||||
| 						/** @type {string} */ | ||||
| 						(module.nameForCondition()) | ||||
| 					); | ||||
| 					if (mimeType === "image/svg+xml") { | ||||
| 						if (typeof source !== "string") { | ||||
| 							source = source.toString(); | ||||
|  |  | |||
|  | @ -1 +1,2 @@ | |||
| /** @type {import("../../../../../").LoaderDefinition} */ | ||||
| module.exports = content => `export default ${JSON.stringify(content + ".webpack{}")}`; | ||||
|  |  | |||
|  | @ -1 +1,2 @@ | |||
| /** @type {import("../../../../../").LoaderDefinition} */ | ||||
| module.exports = content => `export default ${JSON.stringify(content)}`; | ||||
|  |  | |||
|  | @ -2,14 +2,16 @@ const http = require("http"); | |||
| const fs = require("fs"); | ||||
| const path = require("path"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../../").Compiler} Compiler */ | ||||
| 
 | ||||
| /** | ||||
|  * @returns {import("http").Server} server instance | ||||
|  */ | ||||
| function createServer() { | ||||
| 	const server = http.createServer((req, res) => { | ||||
| 		let file; | ||||
| 		const pathname = "." + req.url.replace(/\?.*$/, ""); | ||||
| 		if (req.url.endsWith("?no-cache")) { | ||||
| 		const pathname = "." + /** @type {string} */ (req.url).replace(/\?.*$/, ""); | ||||
| 		if (/** @type {string} */ (req.url).endsWith("?no-cache")) { | ||||
| 			res.setHeader("Cache-Control", "no-cache, max-age=60"); | ||||
| 		} else { | ||||
| 			res.setHeader("Cache-Control", "public, immutable, max-age=600"); | ||||
|  | @ -52,23 +54,28 @@ class ServerPlugin { | |||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {import("../../../../../").Compiler} compiler | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.beforeRun.tapPromise( | ||||
| 			"ServerPlugin", | ||||
| 			async (compiler, callback) => { | ||||
| 			async () => { | ||||
| 				this.refs++; | ||||
| 				if (!this.server) { | ||||
| 					this.server = createServer(); | ||||
| 					await new Promise((resolve, reject) => { | ||||
| 						this.server.listen(this.port, err => { | ||||
| 							if (err) { | ||||
| 								reject(err); | ||||
| 							} else { | ||||
| 								resolve(); | ||||
| 							} | ||||
| 						}); | ||||
| 					await new Promise( | ||||
| 						/** | ||||
| 						 * @param {(value: void) => void} resolve resolve | ||||
| 						 * @param {(reason?: Error) => void} _reject reject | ||||
| 						 */ | ||||
| 						(resolve, _reject) => { | ||||
| 							/** @type {import("http").Server} */ | ||||
| 							(this.server).listen( | ||||
| 								this.port, | ||||
| 								() => { | ||||
| 									resolve(); | ||||
| 								} | ||||
| 							); | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	node: { | ||||
|  | @ -18,9 +20,12 @@ module.exports = { | |||
| 			{ | ||||
| 				test: /\.scss$/i, | ||||
| 				type: "asset/resource", | ||||
| 				/** @type {GeneratorOptionsByModuleTypeKnown['asset/resource']} */ | ||||
| 				generator: { | ||||
| 					binary: false, | ||||
| 					filename: pathInfo => pathInfo.filename.replace(/\.scss/gi, ".css") | ||||
| 					filename: pathInfo => | ||||
| 						/** @type {string} */ | ||||
| 						(pathInfo.filename).replace(/\.scss/gi, ".css") | ||||
| 				}, | ||||
| 				use: ["./loader.js"] | ||||
| 			} | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "development", | ||||
|  | @ -6,6 +8,7 @@ module.exports = { | |||
| 			{ | ||||
| 				test: /\.(png|svg|jpg)$/, | ||||
| 				type: "asset", | ||||
| 				/** @type {ParserOptionsByModuleTypeKnown['asset']} */ | ||||
| 				parser: { | ||||
| 					dataUrlCondition: (source, { filename, module }) => | ||||
| 						filename.includes("?foo=bar") | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| const svgToMiniDataURI = require("mini-svg-data-uri"); | ||||
| const mimeTypes = require("mime-types"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "development", | ||||
|  | @ -9,6 +11,7 @@ module.exports = { | |||
| 			{ | ||||
| 				test: /\.(png|svg|jpg)$/, | ||||
| 				type: "asset/inline", | ||||
| 				/** @type {GeneratorOptionsByModuleTypeKnown["asset/inline"]} */ | ||||
| 				generator: { | ||||
| 					dataUrl: (source, { filename, module }) => { | ||||
| 						if (filename.endsWith("?foo=bar")) { | ||||
|  | @ -19,7 +22,10 @@ module.exports = { | |||
| 							return svgToMiniDataURI(source); | ||||
| 						} | ||||
| 
 | ||||
| 						const mimeType = mimeTypes.lookup(module.nameForCondition()); | ||||
| 						const mimeType = mimeTypes.lookup( | ||||
| 							/** @type {string} */ | ||||
| 							(module.nameForCondition()) | ||||
| 						); | ||||
| 						const encodedContent = source.toString("base64"); | ||||
| 
 | ||||
| 						return `data:${mimeType};base64,${encodedContent}`; | ||||
|  |  | |||
|  | @ -1,8 +1,5 @@ | |||
| const path = require("path"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../types").Configuration} */ | ||||
| module.exports = (env, { testPath }) => ({ | ||||
| 	target: "node14", | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| "use strict"; | ||||
| 
 | ||||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").FileCacheOptions} FileCacheOptions */ | ||||
| 
 | ||||
| // with explicit cache names
 | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
|  | @ -13,13 +16,18 @@ module.exports = [ | |||
| 		}, | ||||
| 		plugins: [ | ||||
| 			{ | ||||
| 				/** | ||||
| 				 * @param {Compiler} compiler compiler | ||||
| 				 */ | ||||
| 				apply(compiler) { | ||||
| 					compiler.hooks.environment.tap("FixTestCachePlugin", () => { | ||||
| 						compiler.options.cache.cacheLocation = | ||||
| 							compiler.options.cache.cacheLocation.replace( | ||||
| 								/filesystem$/, | ||||
| 								"filesystem-extra-1" | ||||
| 							); | ||||
| 						/** @type {FileCacheOptions} */ | ||||
| 						(compiler.options.cache).cacheLocation = | ||||
| 							/** @type {string} */ | ||||
| 							( | ||||
| 								/** @type {FileCacheOptions} */ | ||||
| 								(compiler.options.cache).cacheLocation | ||||
| 							).replace(/filesystem$/, "filesystem-extra-1"); | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
|  | @ -34,13 +42,18 @@ module.exports = [ | |||
| 		}, | ||||
| 		plugins: [ | ||||
| 			{ | ||||
| 				/** | ||||
| 				 * @param {Compiler} compiler compiler | ||||
| 				 */ | ||||
| 				apply(compiler) { | ||||
| 					compiler.hooks.environment.tap("FixTestCachePlugin", () => { | ||||
| 						compiler.options.cache.cacheLocation = | ||||
| 							compiler.options.cache.cacheLocation.replace( | ||||
| 								/filesystem$/, | ||||
| 								"filesystem-extra-2" | ||||
| 							); | ||||
| 						/** @type {FileCacheOptions} */ | ||||
| 						(compiler.options.cache).cacheLocation = | ||||
| 							/** @type {string} */ | ||||
| 							( | ||||
| 								/** @type {FileCacheOptions} */ | ||||
| 								(compiler.options.cache).cacheLocation | ||||
| 							).replace(/filesystem$/, "filesystem-extra-2"); | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -2,7 +2,11 @@ | |||
| 
 | ||||
| // with explicit cache names
 | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| /** @typedef {import("../../../../").Configuration} Configuration */ | ||||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").FileCacheOptions} FileCacheOptions */ | ||||
| 
 | ||||
| /** @type {Configuration} */ | ||||
| module.exports = [ | ||||
| 	{ | ||||
| 		mode: "production", | ||||
|  | @ -13,13 +17,18 @@ module.exports = [ | |||
| 		}, | ||||
| 		plugins: [ | ||||
| 			{ | ||||
| 				/** | ||||
| 				 * @param {Compiler} compiler compiler | ||||
| 				 */ | ||||
| 				apply(compiler) { | ||||
| 					compiler.hooks.environment.tap("FixTestCachePlugin", () => { | ||||
| 						compiler.options.cache.cacheLocation = | ||||
| 							compiler.options.cache.cacheLocation.replace( | ||||
| 								/default$/, | ||||
| 								"default-extra" | ||||
| 							); | ||||
| 						/** @type {FileCacheOptions} */ | ||||
| 						(compiler.options.cache).cacheLocation = | ||||
| 							/** @type {string} */ | ||||
| 							( | ||||
| 								/** @type {FileCacheOptions} */ | ||||
| 								(compiler.options.cache).cacheLocation | ||||
| 							).replace(/default$/, "default-extra"); | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ module.exports = { | |||
| 			 */ | ||||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterSeal.tap("testcase", () => { | ||||
| 					/** @type {Record<string, string>} */ | ||||
| 					const data = {}; | ||||
| 					for (const [name, group] of compilation.namedChunkGroups) { | ||||
| 						/** @type {Map<Module, number>} */ | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ module.exports = { | |||
| 			const handler = compilation => { | ||||
| 				const moduleGraph = compilation.moduleGraph; | ||||
| 				compilation.hooks.afterSeal.tap("testcase", () => { | ||||
| 					/** @type {Record<string, string>} */ | ||||
| 					const data = {}; | ||||
| 					for (const [name, group] of compilation.namedChunkGroups) { | ||||
| 						/** @type {Map<Module, number>} */ | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ module.exports = { | |||
| 			 */ | ||||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterSeal.tap("testcase", () => { | ||||
| 					/** @type {Record<string, string>} */ | ||||
| 					const data = {}; | ||||
| 					for (const [name, group] of compilation.namedChunkGroups) { | ||||
| 						/** @type {Map<Module, number>} */ | ||||
|  |  | |||
|  | @ -1,12 +1,22 @@ | |||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
| 
 | ||||
| /** | ||||
|  * @param {string} path path | ||||
|  * @returns {string} path | ||||
|  */ | ||||
| function handlePath(path) { | ||||
| 	return path.replace(/\\/g, "/"); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {string} from from | ||||
|  * @returns {{ files: string[], directories: string[] }} | ||||
|  */ | ||||
| module.exports = function readDir(from) { | ||||
| 	/** @type {string[]} */ | ||||
| 	const collectedFiles = []; | ||||
| 	/** @type {string[]} */ | ||||
| 	const collectedDirectories = []; | ||||
| 	const stack = [from]; | ||||
| 	let cursor; | ||||
|  |  | |||
|  | @ -1,12 +1,22 @@ | |||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
| 
 | ||||
| /** | ||||
|  * @param {string} path path | ||||
|  * @returns {string} path | ||||
|  */ | ||||
| function handlePath(path) { | ||||
| 	return path.replace(/\\/g, "/"); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {string} from from | ||||
|  * @returns {{ files: string[], directories: string[] }} | ||||
|  */ | ||||
| module.exports = function readDir(from) { | ||||
| 	/** @type {string[]} */ | ||||
| 	const collectedFiles = []; | ||||
| 	/** @type {string[]} */ | ||||
| 	const collectedDirectories = []; | ||||
| 	const stack = [from]; | ||||
| 	let cursor; | ||||
|  |  | |||
|  | @ -12,7 +12,9 @@ module.exports = { | |||
| 			let once = true; | ||||
| 			compiler.hooks.environment.tap("Test", () => { | ||||
| 				if (once) { | ||||
| 					const outputPath = compiler.options.output.path; | ||||
| 					const outputPath = | ||||
| 						/** @type {string} */ | ||||
| 						(compiler.options.output.path); | ||||
| 					const originalPath = path.join(outputPath, "file.ext"); | ||||
| 					fs.writeFileSync(originalPath, ""); | ||||
| 					const customDir = path.join(outputPath, "this/dir/should/be/removed"); | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinitionFunction} */ | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = function () { | ||||
| 	const callback = this.async(); | ||||
| 	this.importModule("./module1", { baseUri: "webpack://" }, (err, exports) => { | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| /** @type {import("../../../../").Configuration} */ | ||||
| const common = { | ||||
| 	target: "web", | ||||
| 	optimization: { | ||||
|  | @ -8,6 +9,8 @@ const common = { | |||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** @typedef {import("../../../../").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration[]} */ | ||||
| module.exports = [ | ||||
| 	{ | ||||
|  | @ -76,6 +79,7 @@ module.exports = [ | |||
| 				{ | ||||
| 					test: /\.css$/, | ||||
| 					type: "css/module", | ||||
| 					/** @type {GeneratorOptionsByModuleTypeKnown["css/module"]} */ | ||||
| 					generator: { | ||||
| 						exportsConvention: name => name.toUpperCase() | ||||
| 					} | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const webpack = require("../../../../"); | ||||
| const path = require("path"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration} */ | ||||
| module.exports = (env, { testPath }) => ({ | ||||
| 	target: "web", | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const path = require("path"); | ||||
| const webpack = require("../../../../"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */ | ||||
| module.exports = (env, { testPath }) => [ | ||||
| 	{ | ||||
|  |  | |||
|  | @ -1,6 +1,3 @@ | |||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration} */ | ||||
| module.exports = (env, { testPath }) => ({ | ||||
| 	target: "web", | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const webpack = require("../../../../"); | ||||
| const path = require("path"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */ | ||||
| module.exports = (env, { testPath }) => [ | ||||
| 	{ | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| const webpack = require("../../../../"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| const common = { | ||||
| 	optimization: { | ||||
| 		chunkIds: "named" | ||||
|  | @ -42,6 +44,7 @@ const common = { | |||
| 					}, | ||||
| 					{ | ||||
| 						resourceQuery: /\?upper$/, | ||||
| 						/** @type {GeneratorOptionsByModuleTypeKnown["css/module"]} */ | ||||
| 						generator: { | ||||
| 							exportsConvention: name => name.toUpperCase() | ||||
| 						} | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = function loader(content) { | ||||
| 	return content + `.using-loader { color: red; }`; | ||||
| }; | ||||
|  |  | |||
|  | @ -2,6 +2,10 @@ const path = require("path"); | |||
| const fs = require("fs"); | ||||
| const webpack = require("../../../../"); | ||||
| 
 | ||||
| /** | ||||
|  * @param {0 | 1 | 2} i index | ||||
|  * @returns {{ main: string[] }} entry | ||||
|  */ | ||||
| const entry = i => { | ||||
| 	switch (i) { | ||||
| 		case 0: | ||||
|  | @ -20,7 +24,7 @@ const entry = i => { | |||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * @param {number} i param | ||||
|  * @param {0 | 1 | 2} i param | ||||
|  * @returns {import("../../../../").Configuration} return | ||||
|  */ | ||||
| const common = i => ({ | ||||
|  | @ -66,4 +70,4 @@ const common = i => ({ | |||
| }); | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration[]} */ | ||||
| module.exports = [...[0, 1].map(i => common(i))]; | ||||
| module.exports = [.../** @type {(0 | 1 | 2)[]} */ ([0, 1]).map(i => common(i))]; | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| const toml = require("toml"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration[]} */ | ||||
| module.exports = [ | ||||
| 	{ | ||||
|  | @ -9,6 +11,7 @@ module.exports = [ | |||
| 				{ | ||||
| 					test: /\.toml$/, | ||||
| 					type: "json", | ||||
| 					/** @type {ParserOptionsByModuleTypeKnown['json']} */ | ||||
| 					parser: { | ||||
| 						parse(input) { | ||||
| 							expect(arguments.length).toBe(1); | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ const webpack = require("../../../../"); | |||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").ParserState} ParserState */ | ||||
| /** @typedef {import("../../../../lib/Parser").PreparsedAst} PreparsedAst */ | ||||
| /** @typedef {import("../../../../").Module} Module */ | ||||
| 
 | ||||
| class LocalizationParser extends Parser { | ||||
| 	/** | ||||
|  | @ -18,22 +19,28 @@ class LocalizationParser extends Parser { | |||
| 	parse(source, state) { | ||||
| 		if (typeof source !== "string") throw new Error("Unexpected input"); | ||||
| 		const { module } = state; | ||||
| 		module.buildInfo.content = JSON.parse(source); | ||||
| 		/** @type {NonNullable<Module["buildInfo"]>} */ | ||||
| 		(module.buildInfo).content = JSON.parse(source); | ||||
| 		return state; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const TYPES = new Set(["localization"]); | ||||
| 
 | ||||
| /** | ||||
|  * @extends {Generator} | ||||
|  */ | ||||
| class LocalizationGenerator extends Generator { | ||||
| 	getTypes() { | ||||
| 		return TYPES; | ||||
| 	} | ||||
| 
 | ||||
| 	/** @type {Generator["getSize"]} */ | ||||
| 	getSize(module, type) { | ||||
| 		return 42; | ||||
| 	} | ||||
| 
 | ||||
| 	/** @type {Generator["generate"]} */ | ||||
| 	generate(module, { type }) { | ||||
| 		return null; | ||||
| 	} | ||||
|  | @ -62,6 +69,9 @@ ${RuntimeGlobals.ensureChunkHandlers}.localization = (chunkId, promises) => { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @type {{ TARGET: string, CONTENT2: boolean, NORMAL1: boolean, NORMAL2: boolean }[]} | ||||
|  */ | ||||
| const definitions = ["node", "async-node", "web"].reduce( | ||||
| 	(arr, target) => | ||||
| 		arr.concat([ | ||||
|  | @ -102,7 +112,8 @@ const definitions = ["node", "async-node", "web"].reduce( | |||
| 				NORMAL2: false | ||||
| 			} | ||||
| 		]), | ||||
| 	[] | ||||
| 	/** @type {{ TARGET: string, CONTENT2: boolean, NORMAL1: boolean, NORMAL2: boolean }[]} */ | ||||
| 	([]) | ||||
| ); | ||||
| 
 | ||||
| module.exports = definitions.map((defs, i) => ({ | ||||
|  | @ -136,6 +147,7 @@ module.exports = definitions.map((defs, i) => ({ | |||
| 					compilation.chunkTemplate.hooks.renderManifest.tap( | ||||
| 						"LocalizationPlugin", | ||||
| 						(result, { chunk, chunkGraph }) => { | ||||
| 							/** @type {Module[]} */ | ||||
| 							const localizationModules = []; | ||||
| 							for (const module of chunkGraph.getChunkModulesIterable(chunk)) { | ||||
| 								if (module.getSourceTypes().has("localization")) | ||||
|  | @ -144,10 +156,15 @@ module.exports = definitions.map((defs, i) => ({ | |||
| 
 | ||||
| 							result.push({ | ||||
| 								render: () => { | ||||
| 									/** @type {Record<number | string, string>} */ | ||||
| 									const data = {}; | ||||
| 									for (const module of localizationModules) { | ||||
| 										data[chunkGraph.getModuleId(module)] = | ||||
| 											module.buildInfo.content; | ||||
| 										data[ | ||||
| 											/** @type {number | string} */ | ||||
| 											(chunkGraph.getModuleId(module)) | ||||
| 										] = | ||||
| 											/** @type {NonNullable<Module["buildInfo"]>} */ | ||||
| 											(module.buildInfo).content; | ||||
| 									} | ||||
| 									return new RawSource( | ||||
| 										`module.exports = ${JSON.stringify(data)}` | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| /** @typedef {import("../../../../").Module} Module */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
|  | @ -19,7 +20,9 @@ module.exports = { | |||
| 					compilation.hooks.dependencyReferencedExports.tap( | ||||
| 						"Test", | ||||
| 						(referencedExports, dep) => { | ||||
| 							const module = compilation.moduleGraph.getParentModule(dep); | ||||
| 							const module = | ||||
| 								/** @type {Module} */ | ||||
| 								(compilation.moduleGraph.getParentModule(dep)); | ||||
| 							if (!module.identifier().endsWith("module.js")) | ||||
| 								return referencedExports; | ||||
| 							const refModule = compilation.moduleGraph.getModule(dep); | ||||
|  | @ -36,7 +39,8 @@ module.exports = { | |||
| 								return referencedExports.filter( | ||||
| 									names => | ||||
| 										(Array.isArray(names) && names.length !== 1) || | ||||
| 										names[0] !== "unused" | ||||
| 										/** @type {string[]} */ | ||||
| 										(names)[0] !== "unused" | ||||
| 								); | ||||
| 							} | ||||
| 							return referencedExports; | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| /** @typedef {import("../../../../").Module} Module */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
|  | @ -13,7 +14,9 @@ module.exports = { | |||
| 				compilation.hooks.dependencyReferencedExports.tap( | ||||
| 					"Test", | ||||
| 					(referencedExports, dep) => { | ||||
| 						const module = compilation.moduleGraph.getParentModule(dep); | ||||
| 						const module = | ||||
| 							/** @type {Module} */ | ||||
| 							(compilation.moduleGraph.getParentModule(dep)); | ||||
| 						if (!module.identifier().endsWith("module.js")) | ||||
| 							return referencedExports; | ||||
| 						const refModule = compilation.moduleGraph.getModule(dep); | ||||
|  | @ -30,7 +33,8 @@ module.exports = { | |||
| 							return referencedExports.filter( | ||||
| 								names => | ||||
| 									(Array.isArray(names) && names.length !== 1) || | ||||
| 									names[0] !== "unused" | ||||
| 									/** @type {string[]} */ | ||||
| 									(names)[0] !== "unused" | ||||
| 							); | ||||
| 						} | ||||
| 						return referencedExports; | ||||
|  |  | |||
|  | @ -1,4 +1,7 @@ | |||
| const { ChunkGraph, ExternalModule } = require("../../../../"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").Module} Module */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	plugins: [ | ||||
|  | @ -57,7 +60,9 @@ module.exports = { | |||
| 					m.issuer = module; | ||||
| 					expect(m.issuer).toBe(module); | ||||
| 					expect( | ||||
| 						typeof m.usedExports === "boolean" ? [] : [...m.usedExports] | ||||
| 						typeof m.usedExports === "boolean" | ||||
| 							? [] | ||||
| 							: [.../** @type {Set<string>} */ (m.usedExports)] | ||||
| 					).toEqual(["testExport"]); | ||||
| 					expect(Array.isArray(m.optimizationBailout)).toBe(true); | ||||
| 					expect(m.optional).toBe(false); | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	entry: { | ||||
|  | @ -19,7 +21,8 @@ module.exports = { | |||
| 					const hashes = []; | ||||
| 					expect(() => { | ||||
| 						for (const module of compilation.chunkGraph.getChunkModulesIterable( | ||||
| 							compilation.namedChunks.get("a") | ||||
| 							/** @type {Chunk} */ | ||||
| 							(compilation.namedChunks.get("a")) | ||||
| 						)) { | ||||
| 							hashes.push(module.hash); | ||||
| 						} | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| /** @typedef {import("../../../../").Configuration} Configuration */ | ||||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| 
 | ||||
| /** @type {Configuration} */ | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
|  | @ -34,12 +35,19 @@ module.exports = { | |||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterSeal.tap("testcase", () => { | ||||
| 					const { chunkGraph } = compilation; | ||||
| 					/** @type {Record<string, Set<string>>} */ | ||||
| 					const chunkModules = {}; | ||||
| 					for (const chunk of compilation.chunks) { | ||||
| 						chunkModules[chunk.name] = new Set(); | ||||
| 						chunkModules[ | ||||
| 							/** @type {NonNullable<Chunk["name"]>} */ | ||||
| 							(chunk.name) | ||||
| 						] = new Set(); | ||||
| 
 | ||||
| 						for (const module of chunkGraph.getChunkModulesIterable(chunk)) { | ||||
| 							chunkModules[chunk.name].add(module.identifier()); | ||||
| 							chunkModules[ | ||||
| 								/** @type {NonNullable<Chunk["name"]>} */ | ||||
| 								(chunk.name) | ||||
| 							].add(module.identifier()); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| /** @typedef {import("../../../../").Module} Module */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
|  | @ -23,12 +25,19 @@ module.exports = { | |||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterSeal.tap("testcase", () => { | ||||
| 					const { chunkGraph } = compilation; | ||||
| 					/** @type {Record<string, Set<Module>>} */ | ||||
| 					const chunkModules = {}; | ||||
| 					for (const chunk of compilation.chunks) { | ||||
| 						chunkModules[chunk.name] = new Set(); | ||||
| 						chunkModules[ | ||||
| 							/** @type {NonNullable<Chunk["name"]>} */ | ||||
| 							(chunk.name) | ||||
| 						] = new Set(); | ||||
| 
 | ||||
| 						for (const module of chunkGraph.getChunkModulesIterable(chunk)) { | ||||
| 							chunkModules[chunk.name].add(module); | ||||
| 							chunkModules[ | ||||
| 								/** @type {NonNullable<Chunk["name"]>} */ | ||||
| 								(chunk.name) | ||||
| 							].add(module); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,9 @@ | |||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| 
 | ||||
| class ThrowsExceptionInRender { | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap("ThrowsException", compilation => { | ||||
| 			compilation.mainTemplate.hooks.requireExtensions.tap( | ||||
|  |  | |||
|  | @ -1,26 +1,37 @@ | |||
| /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */ | ||||
| /** @typedef {import("../../../../").ExternalItemFunctionData} ExternalItemFunctionData */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	optimization: { | ||||
| 		concatenateModules: true | ||||
| 	}, | ||||
| 	externals: [ | ||||
| 		({ context, request, getResolve }, callback) => { | ||||
| 		({ context: _context, request, getResolve }, callback) => { | ||||
| 			if (request !== "external" && request !== "external-false") { | ||||
| 				return callback(null, false); | ||||
| 			} | ||||
| 
 | ||||
| 			const resolve = getResolve({ | ||||
| 				alias: { | ||||
| 					"external-false": false | ||||
| 				} | ||||
| 			}); | ||||
| 			const context = /** @type {string} */ (_context); | ||||
| 
 | ||||
| 			const resolve = | ||||
| 				/** @type {ReturnType<NonNullable<ExternalItemFunctionData["getResolve"]>>} */ ( | ||||
| 					/** @type {NonNullable<ExternalItemFunctionData["getResolve"]>} */ | ||||
| 					(getResolve)({ | ||||
| 						alias: { | ||||
| 							"external-false": false | ||||
| 						} | ||||
| 					}) | ||||
| 				); | ||||
| 
 | ||||
| 			if (request === "external-false") { | ||||
| 				resolve(context, request, callback); | ||||
| 			} else { | ||||
| 				resolve(context, request, (err, resolved, resolveRequest) => { | ||||
| 					if (err) callback(err); | ||||
| 					else if (resolved !== resolveRequest.path) | ||||
| 					else if ( | ||||
| 						resolved !== /** @type {ResolveRequest} */ (resolveRequest).path | ||||
| 					) | ||||
| 						callback(new Error("Error")); | ||||
| 					else callback(null, `var ${JSON.stringify(resolved)}`); | ||||
| 				}); | ||||
|  |  | |||
|  | @ -1,16 +1,27 @@ | |||
| /** @typedef {import("../../../../").ExternalItemFunctionData} ExternalItemFunctionData */ | ||||
| /** @typedef {import("../../../../").ExternalItemFunctionPromise} ExternalItemFunctionPromise */ | ||||
| /** @typedef {import("../../../../").ExternalItemFunctionDataGetResolve} ExternalItemFunctionDataGetResolve */ | ||||
| /** @typedef {import("../../../../").ExternalItemFunctionDataGetResolveResult} ExternalItemFunctionDataGetResolveResult */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	optimization: { | ||||
| 		concatenateModules: true | ||||
| 	}, | ||||
| 	externals: [ | ||||
| 		/** @type {ExternalItemFunctionPromise} */ | ||||
| 		async ({ context, request, getResolve }) => { | ||||
| 			if (request !== "external" && request !== "external-promise") { | ||||
| 				return false; | ||||
| 			} | ||||
| 
 | ||||
| 			const resolve = getResolve(); | ||||
| 			const resolved = await resolve(context, request); | ||||
| 			const resolve = | ||||
| 				/** @type {ExternalItemFunctionDataGetResolveResult} */ | ||||
| 				( | ||||
| 					/** @type {ExternalItemFunctionDataGetResolve} */ | ||||
| 					(getResolve)() | ||||
| 				); | ||||
| 			const resolved = await resolve(/** @type {string} */ (context), request); | ||||
| 			return `var ${JSON.stringify(resolved)}`; | ||||
| 		} | ||||
| 	] | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| /** @typedef {import("../../../../").Chunk & { name: string }} Chunk */ | ||||
| /** @typedef {import("../../../../").PathData & { chunk: Chunk }} PathData */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "development", | ||||
|  | @ -5,12 +8,24 @@ module.exports = { | |||
| 		a: "./a", | ||||
| 		b: { | ||||
| 			import: "./b", | ||||
| 			/** | ||||
| 			 * @param {PathData} data data | ||||
| 			 * @returns {string} filename | ||||
| 			 */ | ||||
| 			filename: data => | ||||
| 				`${data.chunk.name + data.chunk.name + data.chunk.name}.js` | ||||
| 		} | ||||
| 	}, | ||||
| 	output: { | ||||
| 		/** | ||||
| 		 * @param {PathData} data data | ||||
| 		 * @returns {string} filename | ||||
| 		 */ | ||||
| 		filename: data => `${data.chunk.name + data.chunk.name}.js`, | ||||
| 		/** | ||||
| 		 * @param {PathData} data data | ||||
| 		 * @returns {string} filename | ||||
| 		 */ | ||||
| 		chunkFilename: data => `${data.chunk.name + data.chunk.name}.js` | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -1,18 +1,17 @@ | |||
| /** | ||||
|  * Escapes regular expression metacharacters | ||||
|  * @param {string} str String to quote | ||||
|  * @returns {string} Escaped string | ||||
|  */ | ||||
| const quotemeta = str => { | ||||
| 	return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); | ||||
| }; | ||||
| /** @typedef {import("../../../../").Configuration} Configuration */ | ||||
| 
 | ||||
| /** | ||||
|  * @param {Record<string, { name?: string, usedExports: string[], expect: Record<string, string[]> }>} testCases | ||||
|  * @returns {Configuration[]} configurations | ||||
|  */ | ||||
| module.exports = testCases => { | ||||
| 	/** @type {Configuration[]} */ | ||||
| 	const configs = []; | ||||
| 	for (const name of Object.keys(testCases)) { | ||||
| 		const testCase = testCases[name]; | ||||
| 		testCase.name = name; | ||||
| 		const entry = `../_helpers/entryLoader.js?${JSON.stringify(testCase)}!`; | ||||
| 		/** @type {{ alias: Record<string, string> }} */ | ||||
| 		const resolve = { | ||||
| 			alias: {} | ||||
| 		}; | ||||
|  |  | |||
|  | @ -1,12 +1,4 @@ | |||
| const matchAll = (str, regexp) => { | ||||
| 	const matches = []; | ||||
| 	let match; | ||||
| 	while ((match = regexp.exec(str)) !== null) { | ||||
| 		matches.push(match); | ||||
| 	} | ||||
| 	return matches; | ||||
| }; | ||||
| 
 | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = source => { | ||||
| 	return [ | ||||
| 		source, | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| const createTestCases = require("../_helpers/createTestCases"); | ||||
| 
 | ||||
| module.exports = createTestCases({ | ||||
| 	nothing: { | ||||
| 		usedExports: [], | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| title = "TOML Example" | ||||
| 
 | ||||
| [owner] | ||||
| name = "Tom Preston-Werner" | ||||
| organization = "GitHub" | ||||
| bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." | ||||
| dob = 1979-05-27T07:32:00Z | ||||
|  | @ -0,0 +1,13 @@ | |||
| import toml from "./data.toml"; | ||||
| 
 | ||||
| it("should transform toml to json", () => { | ||||
| 	expect(toml).toMatchObject({ | ||||
| 		title: "TOML Example", | ||||
| 		owner: { | ||||
| 			name: 'Tom Preston-Werner', | ||||
| 			organization: 'GitHub', | ||||
| 			bio: 'GitHub Cofounder & CEO\nLikes tater tots and beer.', | ||||
| 			dob: '1979-05-27T07:32:00.000Z' | ||||
| 		} | ||||
| 	}); | ||||
| }); | ||||
|  | @ -0,0 +1,24 @@ | |||
| const toml = require("toml"); | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration[]} */ | ||||
| module.exports = [ | ||||
| 	{ | ||||
| 		mode: "development", | ||||
| 		module: { | ||||
| 			parser: { | ||||
| 				json: { | ||||
| 					parse(input) { | ||||
| 						expect(arguments.length).toBe(1); | ||||
| 						return toml.parse(input); | ||||
| 					} | ||||
| 				} | ||||
| 			}, | ||||
| 			rules: [ | ||||
| 				{ | ||||
| 					test: /\.toml$/, | ||||
| 					type: "json" | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 	} | ||||
| ]; | ||||
|  | @ -2,9 +2,6 @@ const path = require("path"); | |||
| const webpack = require("../../../../"); | ||||
| const supportsAsync = require("../../../helpers/supportsAsync"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */ | ||||
| module.exports = (env, { testPath }) => [ | ||||
| 	{ | ||||
|  |  | |||
|  | @ -5,9 +5,6 @@ const webpack = require("../../../../"); | |||
| const path = require("path"); | ||||
| const supportsAsync = require("../../../helpers/supportsAsync"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */ | ||||
| module.exports = (env, { testPath }) => [ | ||||
| 	{ | ||||
|  |  | |||
|  | @ -1,11 +1,15 @@ | |||
| /** @type {import("../../../../").LoaderDefinitionFunction} */ | ||||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| 
 | ||||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = async function loader() { | ||||
| 	const callback = this.async(); | ||||
| 	const loader = this; | ||||
| 	const compilerName = `extract:${loader.resourcePath}`; | ||||
| 	const compiler = loader._compiler; | ||||
| 	const compiler = /** @type {Compiler} */ (loader._compiler); | ||||
| 	const compilation = /** @type {Compilation} */ (loader._compilation); | ||||
| 	const filename = "*"; | ||||
| 	const childCompiler = loader._compilation.createChildCompiler( | ||||
| 	const childCompiler = compilation.createChildCompiler( | ||||
| 		compilerName, | ||||
| 		{ | ||||
| 			filename, | ||||
|  | @ -24,7 +28,7 @@ module.exports = async function loader() { | |||
| 		library: { | ||||
| 			EnableLibraryPlugin | ||||
| 		} | ||||
| 	} = loader._compiler.webpack; | ||||
| 	} = compiler.webpack; | ||||
| 
 | ||||
| 	new EnableLibraryPlugin('commonjs2').apply(childCompiler); | ||||
| 
 | ||||
|  | @ -59,12 +63,19 @@ module.exports = async function loader() { | |||
| 	}); | ||||
| 
 | ||||
| 	try { | ||||
| 		await new Promise((resolve, reject) => { | ||||
| 			childCompiler.runAsChild((err, _entries, compilation) => { | ||||
| 		await new Promise( | ||||
| 			/** | ||||
| 			 * @param {(value?: void) => void} resolve resolve | ||||
| 			 * @param {(reason?: Error) => void} reject | ||||
| 			 */ | ||||
| 			(resolve, reject) => { | ||||
| 			childCompiler.runAsChild((err, _entries, _compilation) => { | ||||
| 				if (err) { | ||||
| 					return reject(err); | ||||
| 				} | ||||
| 
 | ||||
| 				const compilation = /** @type {Compilation} */ (_compilation); | ||||
| 
 | ||||
| 				if (compilation.errors.length > 0) { | ||||
| 					return reject(compilation.errors[0]); | ||||
| 				} | ||||
|  | @ -73,7 +84,7 @@ module.exports = async function loader() { | |||
| 			}); | ||||
| 		}) | ||||
| 	} catch (e) { | ||||
| 		callback(e); | ||||
| 		callback(/** @type {Error} */ (e)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| 
 | ||||
| /** @type {import("../../../../types").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "none", | ||||
|  | @ -23,6 +25,9 @@ module.exports = { | |||
| 	}, | ||||
| 	plugins: [ | ||||
| 		function () { | ||||
| 			/** | ||||
| 			 * @param {Compilation} compilation compilation | ||||
| 			 */ | ||||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterProcessAssets.tap("testcase", assets => { | ||||
| 					const source = assets["test.js"].source(); | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Compilation} Compilation */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "none", | ||||
|  | @ -44,6 +46,9 @@ module.exports = { | |||
| 	}, | ||||
| 	plugins: [ | ||||
| 		function () { | ||||
| 			/** | ||||
| 			 * @param {Compilation} compilation compilation | ||||
| 			 */ | ||||
| 			const handler = compilation => { | ||||
| 				compilation.hooks.afterProcessAssets.tap("testcase", assets => { | ||||
| 					const source = assets["bundle0.mjs"].source(); | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	output: { | ||||
|  | @ -56,7 +58,9 @@ module.exports = { | |||
| 						"info", | ||||
| 						expect.objectContaining({ sourceFilename: "file.jpg" }) | ||||
| 					); | ||||
| 					const { auxiliaryFiles } = stats.compilation.namedChunks.get("main"); | ||||
| 					const { auxiliaryFiles } = | ||||
| 						/** @type {Chunk} */ | ||||
| 						(stats.compilation.namedChunks.get("main")); | ||||
| 					expect(auxiliaryFiles).toContain("assets/file.png"); | ||||
| 					expect(auxiliaryFiles).toContain("assets/file.png?1"); | ||||
| 					expect(auxiliaryFiles).toContain("assets/file.jpg"); | ||||
|  |  | |||
|  | @ -13,11 +13,18 @@ class FailPlugin { | |||
| } | ||||
| 
 | ||||
| class TestChildCompilationPlugin { | ||||
| 	constructor(output) {} | ||||
| 	constructor() {} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {TODO} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.make.tapAsync( | ||||
| 			"TestChildCompilationFailurePlugin", | ||||
| 			/** | ||||
| 			 * @param {TODO} compilation compilation | ||||
| 			 * @param {TODO} cb cb | ||||
| 			 */ | ||||
| 			(compilation, cb) => { | ||||
| 				const child = compilation.createChildCompiler( | ||||
| 					"name", | ||||
|  |  | |||
|  | @ -3,7 +3,12 @@ const { NormalModule } = require("webpack"); | |||
| const PLUGIN_NAME = "PluginWithLoader"; | ||||
| const loaderPath = require.resolve("./loader.js"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| 
 | ||||
| class PluginWithLoader { | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { | ||||
| 			NormalModule.getCompilationHooks(compilation).beforeLoaders.tap( | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| // const { getRuntimeKey } = require("../../../../lib/util/runtime");
 | ||||
| /** @typedef {import("webpack-sources").Source} Source */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
|  | @ -30,7 +30,9 @@ module.exports = { | |||
| 										module, | ||||
| 										"main" | ||||
| 									); | ||||
| 									const source = sources.get("javascript"); | ||||
| 									const source = | ||||
| 										/** @type {Source} */ | ||||
| 										(sources.get("javascript")); | ||||
| 									const file = compilation.getAssetPath("[name].js", { | ||||
| 										filename: `${module | ||||
| 											.readableIdentifier(compilation.requestShortener) | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const path = require("path"); | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration[]} */ | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration[]} */ | ||||
| module.exports = (env, { testPath }) => [ | ||||
| 	{ | ||||
| 		devtool: false, | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	entry() { | ||||
|  | @ -8,6 +10,9 @@ module.exports = { | |||
| 	}, | ||||
| 	output: { | ||||
| 		filename: data => | ||||
| 			data.chunk.name === "a" ? `${data.chunk.name}.js` : "[name].js" | ||||
| 			/** @type {Chunk} */ | ||||
| 			(data.chunk).name === "a" | ||||
| 				? `${/** @type {Chunk} */ (data.chunk).name}.js` | ||||
| 				: "[name].js" | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| /** @typedef {import("../../../../").Chunk} Chunk */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	mode: "none", | ||||
|  | @ -18,7 +20,14 @@ module.exports = { | |||
| 	}, | ||||
| 	output: { | ||||
| 		filename: data => | ||||
| 			/^[ac]$/.test(data.chunk.name) ? "inner1/inner2/[name].js" : "[name].js", | ||||
| 			/^[ac]$/.test( | ||||
| 				/** @type {string} */ ( | ||||
| 					/** @type {Chunk} */ | ||||
| 					(data.chunk).name | ||||
| 				) | ||||
| 			) | ||||
| 				? "inner1/inner2/[name].js" | ||||
| 				: "[name].js", | ||||
| 		assetModuleFilename: "[name][ext]" | ||||
| 	}, | ||||
| 	module: { | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| /** @type {import("../../../../").LoaderDefinition} */ | ||||
| module.exports = function loader(content) { | ||||
| 	return `module.exports = ${JSON.stringify(content)}`; | ||||
| }; | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| const webpack = require("../../../../"); | ||||
| 
 | ||||
| /** | ||||
|  * @param {boolean | undefined} system system | ||||
|  * @returns {import("../../../../").Configuration} configuration | ||||
|  */ | ||||
| function createConfig(system) { | ||||
| 	const systemString = "" + system; | ||||
| 	return { | ||||
|  |  | |||
|  | @ -20,6 +20,10 @@ module.exports = { | |||
| 			NEGATIVE_ZER0: -0, | ||||
| 			NEGATIVE_NUMBER: -100.25, | ||||
| 			POSITIVE_NUMBER: +100.25, | ||||
| 			/** | ||||
| 			 * @param {number} a a | ||||
| 			 * @returns {number} result | ||||
| 			 */ | ||||
| 			// eslint-disable-next-line object-shorthand
 | ||||
| 			FUNCTION: /* istanbul ignore next */ function (a) { | ||||
| 				return a + 1; | ||||
|  | @ -29,6 +33,10 @@ module.exports = { | |||
| 			OBJECT: { | ||||
| 				SUB: { | ||||
| 					UNDEFINED: undefined, | ||||
| 					/** | ||||
| 					 * @param {number} a a | ||||
| 					 * @returns {number} result | ||||
| 					 */ | ||||
| 					// eslint-disable-next-line object-shorthand
 | ||||
| 					FUNCTION: /* istanbul ignore next */ function (a) { | ||||
| 						return a + 1; | ||||
|  |  | |||
|  | @ -1,9 +1,6 @@ | |||
| const path = require("path"); | ||||
| const LibManifestPlugin = require("../../../../").LibManifestPlugin; | ||||
| 
 | ||||
| /** @typedef {import("../../../WatchTestCases.template").Env} Env */ | ||||
| /** @typedef {import("../../../WatchTestCases.template").TestOptions} TestOptions */ | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration} */ | ||||
| module.exports = (env, { testPath }) => ({ | ||||
| 	entry: { | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| const MCEP = require("mini-css-extract-plugin"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").StatsCompilation} StatsCompilation */ | ||||
| 
 | ||||
| /** @type {(i: number, options?: import("mini-css-extract-plugin").PluginOptions) => import("../../../../").Configuration} */ | ||||
| const config = (i, options) => ({ | ||||
| 	entry: { | ||||
|  | @ -37,10 +39,11 @@ const config = (i, options) => ({ | |||
| 		new MCEP(options), | ||||
| 		compiler => { | ||||
| 			compiler.hooks.done.tap("Test", stats => { | ||||
| 				const chunkIds = stats | ||||
| 					.toJson({ all: false, chunks: true, ids: true }) | ||||
| 					.chunks.map(c => c.id) | ||||
| 					.sort(); | ||||
| 				const chunkIds = | ||||
| 					/** @type {NonNullable<StatsCompilation["chunks"]>} */ | ||||
| 					(stats.toJson({ all: false, chunks: true, ids: true }).chunks) | ||||
| 						.map(c => c.id) | ||||
| 						.sort(); | ||||
| 				expect(chunkIds).toEqual([ | ||||
| 					"a", | ||||
| 					"b", | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ const rootPath = "../../../../"; | |||
| const webpack = require(rootPath); | ||||
| const path = require("path"); | ||||
| 
 | ||||
| /** @type {(env: Env, options: TestOptions) => import("../../../../").Configuration} */ | ||||
| module.exports = (env, { testPath }) => ({ | ||||
| 	plugins: [ | ||||
| 		new webpack.debug.ProfilingPlugin({ | ||||
|  |  | |||
|  | @ -1,6 +1,9 @@ | |||
| const path = require("path"); | ||||
| const webpack = require("../../../../"); | ||||
| const data = require("./data"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").ProgressPlugin} ProgressPlugin */ | ||||
| 
 | ||||
| /** @type {import("../../../../").Configuration} */ | ||||
| module.exports = { | ||||
| 	externals: { | ||||
|  | @ -14,7 +17,9 @@ module.exports = { | |||
| 			apply: compiler => { | ||||
| 				compiler.hooks.compilation.tap("CustomPlugin", compilation => { | ||||
| 					compilation.hooks.optimize.tap("CustomPlugin", () => { | ||||
| 						const reportProgress = webpack.ProgressPlugin.getReporter(compiler); | ||||
| 						const reportProgress = | ||||
| 							/** @type {NonNullable<ReturnType<typeof webpack.ProgressPlugin['getReporter']>>} */ | ||||
| 							(webpack.ProgressPlugin.getReporter(compiler)); | ||||
| 						reportProgress(0, "custom category", "custom message"); | ||||
| 					}); | ||||
| 				}); | ||||
|  |  | |||
|  | @ -5,11 +5,22 @@ const { | |||
| 	optimize: { RealContentHashPlugin } | ||||
| } = require("../../../../"); | ||||
| 
 | ||||
| /** @typedef {import("../../../../").Compiler} Compiler */ | ||||
| /** @typedef {import("../../../../").Asset} Asset */ | ||||
| /** @typedef {import("../../../../").AssetInfo} AssetInfo */ | ||||
| /** @typedef {import("../../../../").ChunkGroup} Entrypoint */ | ||||
| 
 | ||||
| class VerifyAdditionalAssetsPlugin { | ||||
| 	/** | ||||
| 	 * @param {number} stage stage | ||||
| 	 */ | ||||
| 	constructor(stage) { | ||||
| 		this.stage = stage; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap( | ||||
| 			"VerifyAdditionalAssetsPlugin", | ||||
|  | @ -34,10 +45,16 @@ class VerifyAdditionalAssetsPlugin { | |||
| } | ||||
| 
 | ||||
| class HtmlPlugin { | ||||
| 	/** | ||||
| 	 * @param {string[]} entrypoints entrypoints | ||||
| 	 */ | ||||
| 	constructor(entrypoints) { | ||||
| 		this.entrypoints = entrypoints; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap("html-plugin", compilation => { | ||||
| 			compilation.hooks.processAssets.tap( | ||||
|  | @ -49,17 +66,27 @@ class HtmlPlugin { | |||
| 					const publicPath = compilation.outputOptions.publicPath; | ||||
| 					const files = []; | ||||
| 					for (const name of this.entrypoints) { | ||||
| 						for (const file of compilation.entrypoints.get(name).getFiles()) | ||||
| 						for (const file of /** @type {Entrypoint} */ ( | ||||
| 							compilation.entrypoints.get(name) | ||||
| 						).getFiles()) | ||||
| 							files.push(file); | ||||
| 					} | ||||
| 					const toScriptTag = (file, extra) => { | ||||
| 						const asset = compilation.getAsset(file); | ||||
| 					/** | ||||
| 					 * @param {string} file file | ||||
| 					 * @returns {string} content of script tag | ||||
| 					 */ | ||||
| 					const toScriptTag = file => { | ||||
| 						const asset = /** @type {Asset} */ (compilation.getAsset(file)); | ||||
| 						const hash = createHash("sha512"); | ||||
| 						hash.update(asset.source.source()); | ||||
| 						const integrity = `sha512-${hash.digest("base64")}`; | ||||
| 						compilation.updateAsset( | ||||
| 							file, | ||||
| 							x => x, | ||||
| 							/** | ||||
| 							 * @param {AssetInfo} assetInfo asset info | ||||
| 							 * @returns {AssetInfo} new asset info | ||||
| 							 */ | ||||
| 							assetInfo => ({ | ||||
| 								...assetInfo, | ||||
| 								contenthash: Array.isArray(assetInfo.contenthash) | ||||
|  | @ -91,10 +118,16 @@ ${files.map(file => `		${toScriptTag(file)}`).join("\n")} | |||
| } | ||||
| 
 | ||||
| class HtmlInlinePlugin { | ||||
| 	/** | ||||
| 	 * @param {RegExp} inline inline | ||||
| 	 */ | ||||
| 	constructor(inline) { | ||||
| 		this.inline = inline; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap("html-inline-plugin", compilation => { | ||||
| 			compilation.hooks.processAssets.tap( | ||||
|  | @ -104,11 +137,14 @@ class HtmlInlinePlugin { | |||
| 					additionalAssets: true | ||||
| 				}, | ||||
| 				assets => { | ||||
| 					const publicPath = compilation.outputOptions.publicPath; | ||||
| 					const publicPath = | ||||
| 						/** @type {string} */ | ||||
| 						(compilation.outputOptions.publicPath); | ||||
| 					for (const name of Object.keys(assets)) { | ||||
| 						if (/\.html$/.test(name)) { | ||||
| 							const asset = compilation.getAsset(name); | ||||
| 							const content = asset.source.source(); | ||||
| 							const asset = /** @type {Asset} */ (compilation.getAsset(name)); | ||||
| 							const content = /** @type {string} */ (asset.source.source()); | ||||
| 							/** @type {{ start: number, length: number, asset: Asset }[]} */ | ||||
| 							const matches = []; | ||||
| 							const regExp = | ||||
| 								/<script\s+src\s*=\s*"([^"]+)"(?:\s+[^"=\s]+(?:\s*=\s*(?:"[^"]*"|[^\s]+))?)*\s*><\/script>/g; | ||||
|  | @ -118,7 +154,9 @@ class HtmlInlinePlugin { | |||
| 								if (url.startsWith(publicPath)) | ||||
| 									url = url.slice(publicPath.length); | ||||
| 								if (this.inline.test(url)) { | ||||
| 									const asset = compilation.getAsset(url); | ||||
| 									const asset = /** @type {Asset} */ ( | ||||
| 										compilation.getAsset(url) | ||||
| 									); | ||||
| 									matches.push({ | ||||
| 										start: match.index, | ||||
| 										length: match[0].length, | ||||
|  | @ -147,6 +185,9 @@ class HtmlInlinePlugin { | |||
| } | ||||
| 
 | ||||
| class SriHashSupportPlugin { | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap("sri-hash-support-plugin", compilation => { | ||||
| 			RealContentHashPlugin.getCompilationHooks(compilation).updateHash.tap( | ||||
|  | @ -164,6 +205,9 @@ class SriHashSupportPlugin { | |||
| } | ||||
| 
 | ||||
| class HtmlMinimizePlugin { | ||||
| 	/** | ||||
| 	 * @param {Compiler} compiler compiler | ||||
| 	 */ | ||||
| 	apply(compiler) { | ||||
| 		compiler.hooks.compilation.tap("html-minimize-plugin", compilation => { | ||||
| 			compilation.hooks.processAssets.tap( | ||||
|  | @ -177,7 +221,11 @@ class HtmlMinimizePlugin { | |||
| 						if (/\.html$/.test(name)) { | ||||
| 							compilation.updateAsset( | ||||
| 								name, | ||||
| 								source => new RawSource(source.source().replace(/\s+/g, " ")), | ||||
| 								source => | ||||
| 									new RawSource( | ||||
| 										/** @type {string} */ | ||||
| 										(source.source()).replace(/\s+/g, " ") | ||||
| 									), | ||||
| 								assetInfo => ({ | ||||
| 									...assetInfo, | ||||
| 									minimized: true | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue