| | |
| | | const { getRuntimeKey } = require("./util/runtime"); |
| | | const { isSourceEqual } = require("./util/source"); |
| | | |
| | | /** @template T @typedef {import("tapable").AsArray<T>} AsArray<T> */ |
| | | /** @typedef {import("webpack-sources").Source} Source */ |
| | | /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */ |
| | | /** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */ |
| | |
| | | /** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */ |
| | | /** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */ |
| | | /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ |
| | | /** @typedef {import("./NormalModule")} NormalModule */ |
| | | /** @typedef {import("./NormalModule").AnyLoaderContext} AnyLoaderContext */ |
| | | /** @typedef {import("./NormalModule").ParserOptions} ParserOptions */ |
| | | /** @typedef {import("./NormalModule").GeneratorOptions} GeneratorOptions */ |
| | | /** @typedef {import("./RequestShortener")} RequestShortener */ |
| | |
| | | /** @typedef {import("./util/Hash")} Hash */ |
| | | |
| | | /** |
| | | * Defines the shared type used by this module. |
| | | * @template T |
| | | * @typedef {import("tapable").AsArray<T>} AsArray<T> |
| | | */ |
| | | |
| | | /** |
| | | * Defines the shared type used by this module. |
| | | * @template T |
| | | * @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T> |
| | | */ |
| | |
| | | /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ |
| | | |
| | | /** |
| | | * Defines the callback callback. |
| | | * @callback Callback |
| | | * @param {(WebpackError | null)=} err |
| | | * @returns {void} |
| | | */ |
| | | |
| | | /** |
| | | * Defines the module callback callback. |
| | | * @callback ModuleCallback |
| | | * @param {WebpackError | null=} err |
| | | * @param {Module | null=} result |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the module factory result callback callback. |
| | | * @callback ModuleFactoryResultCallback |
| | | * @param {WebpackError | null=} err |
| | | * @param {ModuleFactoryResult | null=} result |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the module or module factory result callback callback. |
| | | * @callback ModuleOrModuleFactoryResultCallback |
| | | * @param {WebpackError | null=} err |
| | | * @param {Module | ModuleFactoryResult | null=} result |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the execute module callback callback. |
| | | * @callback ExecuteModuleCallback |
| | | * @param {WebpackError | null=} err |
| | | * @param {ExecuteModuleResult | null=} result |
| | |
| | | /** @typedef {Record<string, Source>} CompilationAssets */ |
| | | |
| | | /** |
| | | * Defines the available modules chunk group mapping type used by this module. |
| | | * @typedef {object} AvailableModulesChunkGroupMapping |
| | | * @property {ChunkGroup} chunkGroup |
| | | * @property {Set<Module>} availableModules |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the dependencies block like type used by this module. |
| | | * @typedef {object} DependenciesBlockLike |
| | | * @property {Dependency[]} dependencies |
| | | * @property {AsyncDependenciesBlock[]} blocks |
| | |
| | | /** @typedef {Set<Chunk>} Chunks */ |
| | | |
| | | /** |
| | | * Defines the chunk path data type used by this module. |
| | | * @typedef {object} ChunkPathData |
| | | * @property {string | number} id |
| | | * @property {string=} name |
| | | * @property {string} hash |
| | | * @property {((length: number) => string)=} hashWithLength |
| | | * @property {HashWithLengthFunction=} hashWithLength |
| | | * @property {(Record<string, string>)=} contentHash |
| | | * @property {(Record<string, (length: number) => string>)=} contentHashWithLength |
| | | * @property {(Record<string, HashWithLengthFunction>)=} contentHashWithLength |
| | | */ |
| | | |
| | | /** |
| | | * Defines the chunk hash context type used by this module. |
| | | * @typedef {object} ChunkHashContext |
| | | * @property {CodeGenerationResults} codeGenerationResults results of code generation |
| | | * @property {RuntimeTemplate} runtimeTemplate the runtime template |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the runtime requirements context type used by this module. |
| | | * @typedef {object} RuntimeRequirementsContext |
| | | * @property {ChunkGraph} chunkGraph the chunk graph |
| | | * @property {CodeGenerationResults} codeGenerationResults the code generation results |
| | | */ |
| | | |
| | | /** |
| | | * Defines the execute module options type used by this module. |
| | | * @typedef {object} ExecuteModuleOptions |
| | | * @property {EntryOptions=} entryOptions |
| | | */ |
| | | |
| | | /** @typedef {LazySet<string>} FileSystemDependencies */ |
| | | |
| | | /** @typedef {EXPECTED_ANY} ExecuteModuleExports */ |
| | | |
| | | /** |
| | | * Defines the execute module result type used by this module. |
| | | * @typedef {object} ExecuteModuleResult |
| | | * @property {ExecuteModuleExports} exports |
| | | * @property {boolean} cacheable |
| | | * @property {Map<string, { source: Source, info: AssetInfo | undefined }>} assets |
| | | * @property {LazySet<string>} fileDependencies |
| | | * @property {LazySet<string>} contextDependencies |
| | | * @property {LazySet<string>} missingDependencies |
| | | * @property {LazySet<string>} buildDependencies |
| | | * @property {ExecuteModuleAssets} assets |
| | | * @property {FileSystemDependencies} fileDependencies |
| | | * @property {FileSystemDependencies} contextDependencies |
| | | * @property {FileSystemDependencies} missingDependencies |
| | | * @property {FileSystemDependencies} buildDependencies |
| | | */ |
| | | |
| | | /** |
| | | * Defines the execute module object type used by this module. |
| | | * @typedef {object} ExecuteModuleObject |
| | | * @property {string=} id module id |
| | | * @property {ExecuteModuleExports} exports exports |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the execute module argument type used by this module. |
| | | * @typedef {object} ExecuteModuleArgument |
| | | * @property {Module} module |
| | | * @property {ExecuteModuleObject=} moduleObject |
| | |
| | | /** @typedef {((id: string) => ExecuteModuleExports) & { i?: ((options: ExecuteOptions) => void)[], c?: Record<string, ExecuteModuleObject> }} WebpackRequire */ |
| | | |
| | | /** |
| | | * Defines the execute options type used by this module. |
| | | * @typedef {object} ExecuteOptions |
| | | * @property {string=} id module id |
| | | * @property {ExecuteModuleObject} module module |
| | | * @property {WebpackRequire} require require function |
| | | */ |
| | | |
| | | /** @typedef {Map<string, { source: Source, info: AssetInfo | undefined }>} ExecuteModuleAssets */ |
| | | |
| | | /** |
| | | * Defines the execute module context type used by this module. |
| | | * @typedef {object} ExecuteModuleContext |
| | | * @property {Map<string, { source: Source, info: AssetInfo | undefined }>} assets |
| | | * @property {ExecuteModuleAssets} assets |
| | | * @property {Chunk} chunk |
| | | * @property {ChunkGraph} chunkGraph |
| | | * @property {WebpackRequire=} __webpack_require__ |
| | | */ |
| | | |
| | | /** |
| | | * Defines the entry data type used by this module. |
| | | * @typedef {object} EntryData |
| | | * @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup |
| | | * @property {Dependency[]} includeDependencies dependencies of the entrypoint that should be included but not evaluated |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Defines the log entry type used by this module. |
| | | * @typedef {object} LogEntry |
| | | * @property {string} type |
| | | * @property {keyof LogType} type |
| | | * @property {EXPECTED_ANY[]=} args |
| | | * @property {number} time |
| | | * @property {string[]=} trace |
| | | */ |
| | | |
| | | /** |
| | | * Defines the known asset info type used by this module. |
| | | * @typedef {object} KnownAssetInfo |
| | | * @property {boolean=} immutable true, if the asset can be long term cached forever (contains a hash) |
| | | * @property {boolean=} minimized whether the asset is minimized |
| | |
| | | /** @typedef {{ path: string, info: AssetInfo }} InterpolatedPathAndAssetInfo */ |
| | | |
| | | /** |
| | | * Defines the asset type used by this module. |
| | | * @typedef {object} Asset |
| | | * @property {string} name the filename of the asset |
| | | * @property {Source} source source of the asset |
| | | * @property {AssetInfo} info info about the asset |
| | | */ |
| | | |
| | | /** @typedef {(length: number) => string} HashWithLengthFunction */ |
| | | |
| | | /** |
| | | * Defines the module path data type used by this module. |
| | | * @typedef {object} ModulePathData |
| | | * @property {string | number} id |
| | | * @property {string} hash |
| | | * @property {((length: number) => string)=} hashWithLength |
| | | * @property {HashWithLengthFunction=} hashWithLength |
| | | */ |
| | | |
| | | /** @typedef {(id: string | number) => string | number} PrepareIdFunction */ |
| | | |
| | | /** |
| | | * Defines the path data type used by this module. |
| | | * @typedef {object} PathData |
| | | * @property {ChunkGraph=} chunkGraph |
| | | * @property {string=} hash |
| | | * @property {((length: number) => string)=} hashWithLength |
| | | * @property {HashWithLengthFunction=} hashWithLength |
| | | * @property {(Chunk | ChunkPathData)=} chunk |
| | | * @property {(Module | ModulePathData)=} module |
| | | * @property {RuntimeSpec=} runtime |
| | |
| | | * @property {string=} query |
| | | * @property {string=} contentHashType |
| | | * @property {string=} contentHash |
| | | * @property {((length: number) => string)=} contentHashWithLength |
| | | * @property {HashWithLengthFunction=} contentHashWithLength |
| | | * @property {boolean=} noChunkHash |
| | | * @property {string=} url |
| | | * @property {string=} local |
| | | * @property {PrepareIdFunction=} prepareId |
| | | */ |
| | | |
| | | /** @typedef {"module" | "chunk" | "root-of-chunk" | "nested"} ExcludeModulesType */ |
| | | |
| | | /** |
| | | * Defines the known normalized stats options type used by this module. |
| | | * @typedef {object} KnownNormalizedStatsOptions |
| | | * @property {string} context |
| | | * @property {RequestShortener} requestShortener |
| | |
| | | /** @typedef {KnownNormalizedStatsOptions & Omit<StatsOptions, keyof KnownNormalizedStatsOptions> & Record<string, EXPECTED_ANY>} NormalizedStatsOptions */ |
| | | |
| | | /** |
| | | * Defines the known create stats options context type used by this module. |
| | | * @typedef {object} KnownCreateStatsOptionsContext |
| | | * @property {boolean=} forToString |
| | | */ |
| | | |
| | | /** @typedef {KnownCreateStatsOptionsContext & Record<string, EXPECTED_ANY>} CreateStatsOptionsContext */ |
| | | |
| | | /** @typedef {{ module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}} CodeGenerationJob */ |
| | | /** @typedef {{ module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[] }} CodeGenerationJob */ |
| | | |
| | | /** @typedef {CodeGenerationJob[]} CodeGenerationJobs */ |
| | | |
| | | /** @typedef {{javascript: ModuleTemplate}} ModuleTemplates */ |
| | | /** @typedef {{ javascript: ModuleTemplate }} ModuleTemplates */ |
| | | |
| | | /** @typedef {Set<Module>} NotCodeGeneratedModules */ |
| | | |
| | |
| | | // TODO webpack 6: remove |
| | | const deprecatedNormalModuleLoaderHook = util.deprecate( |
| | | /** |
| | | * Handles the callback logic for this hook. |
| | | * @param {Compilation} compilation compilation |
| | | * @returns {NormalModuleCompilationHooks["loader"]} hooks |
| | | */ |
| | |
| | | |
| | | // TODO webpack 6: remove |
| | | /** |
| | | * Define removed module templates. |
| | | * @param {ModuleTemplates | undefined} moduleTemplates module templates |
| | | */ |
| | | const defineRemovedModuleTemplates = (moduleTemplates) => { |
| | |
| | | const compareErrors = concatComparators(byModule, byLocation, byMessage); |
| | | |
| | | /** |
| | | * Defines the known unsafe cache data type used by this module. |
| | | * @typedef {object} KnownUnsafeCacheData |
| | | * @property {FactoryMeta=} factoryMeta factory meta |
| | | * @property {ResolveOptions=} resolveOptions resolve options |
| | |
| | | /** @typedef {KnownUnsafeCacheData & Record<string, EXPECTED_ANY>} UnsafeCacheData */ |
| | | |
| | | /** |
| | | * Defines the module with restore from unsafe cache type used by this module. |
| | | * @typedef {Module & { restoreFromUnsafeCache?: (unsafeCacheData: UnsafeCacheData, moduleFactory: ModuleFactory, compilationParams: CompilationParams) => void }} ModuleWithRestoreFromUnsafeCache |
| | | */ |
| | | |
| | | /** @typedef {(module: Module) => boolean} UnsafeCachePredicate */ |
| | | |
| | | /** @type {WeakMap<Dependency, ModuleWithRestoreFromUnsafeCache | null>} */ |
| | | const unsafeCacheDependencies = new WeakMap(); |
| | |
| | | /** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */ |
| | | const processAssetsHook = new AsyncSeriesHook(["assets"]); |
| | | |
| | | /** @type {Set<string>} */ |
| | | let savedAssets = new Set(); |
| | | /** |
| | | * Returns new assets. |
| | | * @param {CompilationAssets} assets assets |
| | | * @returns {CompilationAssets} new assets |
| | | */ |
| | | const popNewAssets = (assets) => { |
| | | /** @type {undefined | CompilationAssets} */ |
| | | let newAssets; |
| | | for (const file of Object.keys(assets)) { |
| | | if (savedAssets.has(file)) continue; |
| | | if (newAssets === undefined) { |
| | | newAssets = Object.create(null); |
| | | } |
| | | newAssets[file] = assets[file]; |
| | | /** @type {CompilationAssets} */ |
| | | (newAssets)[file] = assets[file]; |
| | | savedAssets.add(file); |
| | | } |
| | | return newAssets; |
| | | return /** @type {CompilationAssets} */ (newAssets); |
| | | }; |
| | | processAssetsHook.intercept({ |
| | | name: "Compilation", |
| | |
| | | /** @type {ProcessedAssets | undefined} */ |
| | | const processedAssets = additionalAssetsFn ? new WeakSet() : undefined; |
| | | /** |
| | | * Gets available assets. |
| | | * @param {CompilationAssets} assets to be processed by additionalAssetsFn |
| | | * @returns {CompilationAssets} available assets |
| | | */ |
| | |
| | | ...remainingTap, |
| | | type: "async", |
| | | /** |
| | | * Processes the provided asset. |
| | | * @param {CompilationAssets} assets assets |
| | | * @param {(err?: Error | null, result?: void) => void} callback callback |
| | | * @returns {void} |
| | |
| | | return { |
| | | ...remainingTap, |
| | | /** |
| | | * Processes the provided asset. |
| | | * @param {CompilationAssets} assets assets |
| | | * @param {(err?: Error | null, result?: void) => void} callback callback |
| | | * @returns {void} |
| | |
| | | fn( |
| | | assets, |
| | | /** |
| | | * Handles the callback logic for this hook. |
| | | * @param {Error} err err |
| | | * @returns {void} |
| | | */ |
| | |
| | | return { |
| | | ...remainingTap, |
| | | /** |
| | | * Returns result. |
| | | * @param {CompilationAssets} assets assets |
| | | * @returns {Promise<CompilationAssets>} result |
| | | */ |
| | |
| | | const afterProcessAssetsHook = new SyncHook(["assets"]); |
| | | |
| | | /** |
| | | * Creates a process assets hook. |
| | | * @template T |
| | | * @param {string} name name of the hook |
| | | * @param {number} stage new stage |
| | |
| | | const createProcessAssetsHook = (name, stage, getArgs, code) => { |
| | | if (!this._backCompat && code) return; |
| | | /** |
| | | * Returns error message. |
| | | * @param {string} reason reason |
| | | * @returns {string} error message |
| | | */ |
| | |
| | | ) => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}. |
| | | BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a single Compilation.hooks.processAssets hook.`; |
| | | /** |
| | | * @param {string | (import("tapable").TapOptions & { name: string; } & ProcessAssetsAdditionalOptions)} options hook options |
| | | * @returns {import("tapable").TapOptions & { name: string; } & ProcessAssetsAdditionalOptions} modified options |
| | | * Normalizes tap options for migrated process-assets hooks. |
| | | * @param {string | (import("tapable").TapOptions & { name: string } & ProcessAssetsAdditionalOptions)} options hook options |
| | | * @returns {import("tapable").TapOptions & { name: string } & ProcessAssetsAdditionalOptions} modified options |
| | | */ |
| | | const getOptions = (options) => { |
| | | if (typeof options === "string") options = { name: options }; |
| | |
| | | /** @type {SyncHook<[StatsPrinter, NormalizedStatsOptions]>} */ |
| | | statsPrinter: new SyncHook(["statsPrinter", "options"]), |
| | | |
| | | /** |
| | | * Gets normal module loader. |
| | | * @deprecated |
| | | * @returns {SyncHook<[AnyLoaderContext, NormalModule]>} normal module loader hook |
| | | */ |
| | | get normalModuleLoader() { |
| | | return getNormalModuleLoader(); |
| | | } |
| | |
| | | this.emittedAssets = new Set(); |
| | | /** @type {Set<string>} */ |
| | | this.comparedForEmitAssets = new Set(); |
| | | /** @type {LazySet<string>} */ |
| | | /** @type {FileSystemDependencies} */ |
| | | this.fileDependencies = new LazySet(); |
| | | /** @type {LazySet<string>} */ |
| | | /** @type {FileSystemDependencies} */ |
| | | this.contextDependencies = new LazySet(); |
| | | /** @type {LazySet<string>} */ |
| | | /** @type {FileSystemDependencies} */ |
| | | this.missingDependencies = new LazySet(); |
| | | /** @type {LazySet<string>} */ |
| | | /** @type {FileSystemDependencies} */ |
| | | this.buildDependencies = new LazySet(); |
| | | // TODO webpack 6 remove |
| | | /** |
| | | * @deprecated |
| | | * @type {{ add: (item: string) => FileSystemDependencies }} |
| | | */ |
| | | this.compilationDependencies = { |
| | | add: util.deprecate( |
| | | /** |
| | | * Handles the add callback for this hook. |
| | | * @param {string} item item |
| | | * @returns {LazySet<string>} file dependencies |
| | | * @returns {FileSystemDependencies} file dependencies |
| | | */ |
| | | (item) => this.fileDependencies.add(item), |
| | | "Compilation.compilationDependencies is deprecated (used Compilation.fileDependencies instead)", |
| | |
| | | this._codeGenerationCache = this.getCache("Compilation/codeGeneration"); |
| | | |
| | | const unsafeCache = options.module.unsafeCache; |
| | | /** @type {boolean} */ |
| | | this._unsafeCache = Boolean(unsafeCache); |
| | | /** @type {UnsafeCachePredicate} */ |
| | | this._unsafeCachePredicate = |
| | | typeof unsafeCache === "function" ? unsafeCache : () => true; |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates a stats options. |
| | | * @param {string | boolean | StatsOptions | undefined} optionsOrPreset stats option value |
| | | * @param {CreateStatsOptionsContext=} context context |
| | | * @returns {NormalizedStatsOptions} normalized options |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates a stats factory. |
| | | * @param {NormalizedStatsOptions} options options |
| | | * @returns {StatsFactory} the stats factory |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates a stats printer. |
| | | * @param {NormalizedStatsOptions} options options |
| | | * @returns {StatsPrinter} the stats printer |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the cache facade instance. |
| | | * @param {string} name cache name |
| | | * @returns {CacheFacade} the cache facade instance |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns a logger with that name. |
| | | * @param {string | (() => string)} name name of the logger, or function called once to get the logger name |
| | | * @returns {Logger} a logger with that name |
| | | */ |
| | |
| | | ); |
| | | } |
| | | } |
| | | /** @type {LogEntry["trace"]} */ |
| | | let trace; |
| | | switch (type) { |
| | | case LogType.warn: |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided module to the compilation. |
| | | * @param {Module} module module to be added that was created |
| | | * @param {ModuleCallback} callback returns the module in the compilation, |
| | | * it could be the passed one (if new), or an already existing in the compilation |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided module to the compilation. |
| | | * @param {Module} module module to be added that was created |
| | | * @param {ModuleCallback} callback returns the module in the compilation, |
| | | * it could be the passed one (if new), or an already existing in the compilation |
| | |
| | | /** |
| | | * Attempts to search for a module by its identifier |
| | | * @param {string} identifier identifier (usually path) for module |
| | | * @returns {Module|undefined} attempt to search for module and return it, else undefined |
| | | * @returns {Module | undefined} attempt to search for module and return it, else undefined |
| | | */ |
| | | findModule(identifier) { |
| | | return this._modules.get(identifier); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Process module dependencies. |
| | | * @param {Module} module to be processed for deps |
| | | * @param {ModuleCallback} callback callback to be triggered |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Process module dependencies non recursive. |
| | | * @param {Module} module to be processed for deps |
| | | * @returns {void} |
| | | */ |
| | | processModuleDependenciesNonRecursive(module) { |
| | | /** |
| | | * Process dependencies block. |
| | | * @param {DependenciesBlock} block block |
| | | */ |
| | | const processDependenciesBlock = (block) => { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Process module dependencies. |
| | | * @param {Module} module to be processed for deps |
| | | * @param {ModuleCallback} callback callback to be triggered |
| | | * @returns {void} |
| | |
| | | let inProgressTransitive = 1; |
| | | |
| | | /** |
| | | * On dependencies sorted. |
| | | * @param {WebpackError=} err error |
| | | * @returns {void} |
| | | */ |
| | |
| | | }; |
| | | |
| | | /** |
| | | * On transitive tasks finished. |
| | | * @param {WebpackError=} err error |
| | | * @returns {void} |
| | | */ |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Process dependency. |
| | | * @param {Dependency} dep dependency |
| | | * @param {number} index index in block |
| | | * @returns {void} |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Process dependency for resolving. |
| | | * @param {Dependency} dep dependency |
| | | * @returns {void} |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Handle new module from unsafe cache. |
| | | * @private |
| | | * @param {Module} originModule original module |
| | | * @param {Dependency} dependency dependency |
| | |
| | | } |
| | | |
| | | /** |
| | | * Handle existing module from unsafe cache. |
| | | * @private |
| | | * @param {Module} originModule original modules |
| | | * @param {Dependency} dependency dependency |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided factorize module option. |
| | | * @param {FactorizeModuleOptions} options options |
| | | * @param {ModuleOrModuleFactoryResultCallback} callback callback |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module callback. |
| | | * @overload |
| | | * @param {FactorizeModuleOptions & { factoryResult?: false }} options options |
| | | * @param {ModuleCallback} callback callback |
| | | * @returns {void} |
| | | */ |
| | | /** |
| | | * Processes the provided module factory result callback. |
| | | * @overload |
| | | * @param {FactorizeModuleOptions & { factoryResult: true }} options options |
| | | * @param {ModuleFactoryResultCallback} callback callback |
| | | * @returns {void} |
| | | */ |
| | | /** |
| | | * Processes the provided |. |
| | | * @param {FactorizeModuleOptions & { factoryResult?: false } | FactorizeModuleOptions & { factoryResult: true }} options options |
| | | * @param {ModuleCallback | ModuleFactoryResultCallback} callback callback |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Defines the handle module creation options type used by this module. |
| | | * @typedef {object} HandleModuleCreationOptions |
| | | * @property {ModuleFactory} factory |
| | | * @property {Dependency[]} dependencies |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Handle module creation. |
| | | * @param {HandleModuleCreationOptions} options options object |
| | | * @param {ModuleCallback} callback callback |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Handle module build and dependencies. |
| | | * @private |
| | | * @param {Module | null} originModule original module |
| | | * @param {Module} module module |
| | |
| | | (originModule) |
| | | ); |
| | | if (creatingModuleDuringBuildSet === undefined) { |
| | | /** @type {Set<Module>} */ |
| | | creatingModuleDuringBuildSet = new Set(); |
| | | this.creatingModuleDuringBuild.set( |
| | | /** @type {Module} */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided string to the compilation. |
| | | * @param {string} context context string path |
| | | * @param {Dependency} dependency dependency used to create Module chain |
| | | * @param {ModuleCallback} callback callback for when module chain is complete |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided object to the compilation. |
| | | * @param {object} options options |
| | | * @param {string} options.context context string path |
| | | * @param {Dependency} options.dependency dependency used to create Module chain |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided string to the compilation. |
| | | * @param {string} context context path for entry |
| | | * @param {Dependency} entry entry dependency that should be followed |
| | | * @param {string | EntryOptions} optionsOrName options or deprecated name of entry |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided string to the compilation. |
| | | * @param {string} context context path for entry |
| | | * @param {Dependency} dependency dependency that should be followed |
| | | * @param {EntryOptions} options options |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided string to the compilation. |
| | | * @param {string} context context path for entry |
| | | * @param {Dependency} entry entry dependency that should be followed |
| | | * @param {"dependencies" | "includeDependencies"} target type of entry |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module module to be rebuilt |
| | | * @param {ModuleCallback} callback callback when module finishes rebuilding |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module module to be rebuilt |
| | | * @param {ModuleCallback} callback callback when module finishes rebuilding |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Compute affected modules. |
| | | * @private |
| | | * @param {Set<Module>} modules modules |
| | | */ |
| | |
| | | this.moduleGraph.setModuleMemCaches(this.moduleMemCaches); |
| | | } |
| | | const { moduleGraph, moduleMemCaches } = this; |
| | | /** @type {Set<Module>} */ |
| | | const affectedModules = new Set(); |
| | | /** @type {Set<Module>} */ |
| | | const infectedModules = new Set(); |
| | | let statNew = 0; |
| | | let statChanged = 0; |
| | |
| | | let statWithoutBuild = 0; |
| | | |
| | | /** |
| | | * Compute references. |
| | | * @param {Module} module module |
| | | * @returns {WeakReferences | undefined} references |
| | | */ |
| | |
| | | }; |
| | | |
| | | /** |
| | | * Compares references. |
| | | * @param {Module} module the module |
| | | * @param {WeakReferences | undefined} references references |
| | | * @returns {boolean} true, when the references differ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Reduce affect type. |
| | | * @param {Readonly<ModuleGraphConnection[]>} connections connections |
| | | * @returns {symbol | boolean} result |
| | | */ |
| | |
| | | } |
| | | return affected; |
| | | }; |
| | | /** @type {Set<Module>} */ |
| | | const directOnlyInfectedModules = new Set(); |
| | | for (const module of infectedModules) { |
| | | for (const [ |
| | |
| | | } |
| | | } |
| | | for (const module of directOnlyInfectedModules) infectedModules.add(module); |
| | | /** @type {Set<Module>} */ |
| | | const directOnlyAffectModules = new Set(); |
| | | for (const module of affectedModules) { |
| | | for (const [ |
| | |
| | | let statChanged = 0; |
| | | let statNew = 0; |
| | | /** |
| | | * Compute references. |
| | | * @param {Module} module module |
| | | * @returns {References} references |
| | | */ |
| | |
| | | return { id, modules, blocks }; |
| | | }; |
| | | /** |
| | | * Compares references. |
| | | * @param {Module} module module |
| | | * @param {object} references references |
| | | * @param {string | number} references.id id |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided callback. |
| | | * @param {Callback} callback callback |
| | | */ |
| | | finish(callback) { |
| | |
| | | const logger = this.getLogger("webpack.Compilation.ModuleProfile"); |
| | | // Avoid coverage problems due indirect changes |
| | | /** |
| | | * Processes the provided value. |
| | | * @param {number} value value |
| | | * @param {string} msg message |
| | | */ |
| | |
| | | } |
| | | }; |
| | | /** |
| | | * Log normal summary. |
| | | * @param {string} category a category |
| | | * @param {(profile: ModuleProfile) => number} getDuration get duration callback |
| | | * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback |
| | |
| | | ); |
| | | }; |
| | | /** |
| | | * Log by loaders summary. |
| | | * @param {string} category a category |
| | | * @param {(profile: ModuleProfile) => number} getDuration get duration callback |
| | | * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback |
| | | */ |
| | | const logByLoadersSummary = (category, getDuration, getParallelism) => { |
| | | /** @type {Map<string, { module: Module, profile: ModuleProfile }[]>} */ |
| | | const map = new Map(); |
| | | for (const [module, profile] of modulesWithProfiles) { |
| | | const list = getOrInsert( |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided callback. |
| | | * @param {Callback} callback signals when the call finishes |
| | | * @returns {void} |
| | | */ |
| | | seal(callback) { |
| | | /** |
| | | * Processes the provided err. |
| | | * @param {WebpackError=} err err |
| | | * @returns {void} |
| | | */ |
| | |
| | | this.chunkGroups.push(entrypoint); |
| | | connectChunkGroupAndChunk(entrypoint, chunk); |
| | | |
| | | /** @type {Set<Module>} */ |
| | | const entryModules = new Set(); |
| | | for (const dep of [...this.globalEntry.dependencies, ...dependencies]) { |
| | | entrypoint.addOrigin( |
| | |
| | | this.assignDepths(entryModules); |
| | | |
| | | /** |
| | | * Returns sorted deps. |
| | | * @param {Dependency[]} deps deps |
| | | * @returns {Module[]} sorted deps |
| | | */ |
| | |
| | | chunkGraphInit.set(entrypoint, (modulesList = [])); |
| | | } |
| | | for (const module of includedModules) { |
| | | this.assignDepth(module); |
| | | this.assignDepths([module]); |
| | | modulesList.push(module); |
| | | } |
| | | } |
| | | /** @type {Set<Chunk>} */ |
| | | const runtimeChunks = new Set(); |
| | | outer: for (const [ |
| | | name, |
| | |
| | | } |
| | | |
| | | /** |
| | | * Report dependency errors and warnings. |
| | | * @param {Module} module module to report from |
| | | * @param {DependenciesBlock[]} blocks blocks to report from |
| | | * @returns {boolean} true, when it has warnings or errors |
| | |
| | | } |
| | | |
| | | /** |
| | | * Generates code and runtime requirements for this module. |
| | | * @param {Callback} callback callback |
| | | */ |
| | | codeGeneration(callback) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Run code generation jobs. |
| | | * @private |
| | | * @param {CodeGenerationJobs} jobs code generation jobs |
| | | * @param {Callback} callback callback |
| | |
| | | const runIteration = () => { |
| | | /** @type {CodeGenerationJobs} */ |
| | | let delayedJobs = []; |
| | | /** @type {Set<Module>} */ |
| | | let delayedModules = new Set(); |
| | | asyncLib.eachLimit( |
| | | jobs, |
| | |
| | | ); |
| | | }, |
| | | (err) => { |
| | | if (err) return callback(err); |
| | | if (err) return callback(/** @type {WebpackError} */ (err)); |
| | | if (delayedJobs.length > 0) { |
| | | if (delayedJobs.length === jobs.length) { |
| | | return callback( |
| | |
| | | } |
| | | |
| | | /** |
| | | * Code generation module. |
| | | * @param {Module} module module |
| | | * @param {RuntimeSpec} runtime runtime |
| | | * @param {RuntimeSpec[]} runtimes runtimes |
| | |
| | | ); |
| | | cache.get((err, cachedResult) => { |
| | | if (err) return callback(/** @type {WebpackError} */ (err)); |
| | | /** @type {CodeGenerationResult} */ |
| | | let result; |
| | | if (!cachedResult) { |
| | | try { |
| | |
| | | dependencyTemplates, |
| | | runtimeTemplate, |
| | | runtime, |
| | | runtimes, |
| | | codeGenerationResults: results, |
| | | compilation: this |
| | | }); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Process runtime requirements. |
| | | * @param {object} options options |
| | | * @param {ChunkGraph=} options.chunkGraph the chunk graph |
| | | * @param {Iterable<Module>=} options.modules modules |
| | |
| | | continue; |
| | | } |
| | | } |
| | | /** @type {RuntimeRequirements} */ |
| | | let set; |
| | | const runtimeRequirements = |
| | | codeGenerationResults.getRuntimeRequirements(module, runtime); |
| | |
| | | |
| | | // TODO webpack 6 make chunkGraph argument non-optional |
| | | /** |
| | | * Adds runtime module. |
| | | * @param {Chunk} chunk target chunk |
| | | * @param {RuntimeModule} module runtime module |
| | | * @param {ChunkGraph} chunkGraph the chunk graph |
| | |
| | | * @param {string | ChunkGroupOptions} groupOptions options for the chunk group |
| | | * @param {Module=} module the module the references the chunk group |
| | | * @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module) |
| | | * @param {string=} request the request from which the the chunk group is referenced |
| | | * @param {string=} request the request from which the chunk group is referenced |
| | | * @returns {ChunkGroup} the new or existing chunk group |
| | | */ |
| | | addChunkInGroup(groupOptions, module, loc, request) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided async entrypoint to this chunk group. |
| | | * @param {EntryOptions} options options for the entrypoint |
| | | * @param {Module} module the module the references the chunk group |
| | | * @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module) |
| | | * @param {string} request the request from which the the chunk group is referenced |
| | | * @param {string} request the request from which the chunk group is referenced |
| | | * @returns {Entrypoint} the new or existing entrypoint |
| | | */ |
| | | addAsyncEntrypoint(options, module, loc, request) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @deprecated |
| | | * @param {Module} module module to assign depth |
| | | * @returns {void} |
| | |
| | | moduleGraph.setDepth(module, 0); |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module module for processing |
| | | * @returns {void} |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * @param {Set<Module>} modules module to assign depth |
| | | * Assigns depth values to the provided modules. |
| | | * @param {Module[] | Set<Module>} modules modules to assign depth |
| | | * @returns {void} |
| | | */ |
| | | assignDepths(modules) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Gets dependency referenced exports. |
| | | * @param {Dependency} dependency the dependency |
| | | * @param {RuntimeSpec} runtime the runtime |
| | | * @returns {ReferencedExports} referenced exports |
| | |
| | | } |
| | | |
| | | /** |
| | | * Removes reasons of dependency block. |
| | | * @param {Module} module module relationship for removal |
| | | * @param {DependenciesBlockLike} block dependencies block |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Patch chunks after reason removal. |
| | | * @param {Module} module module to patch tie |
| | | * @param {Chunk} chunk chunk to patch tie |
| | | * @returns {void} |
| | |
| | | } |
| | | |
| | | /** |
| | | * Removes chunk from dependencies. |
| | | * @param {DependenciesBlock} block block tie for Chunk |
| | | * @param {Chunk} chunk chunk to remove from dep |
| | | * @returns {void} |
| | | */ |
| | | removeChunkFromDependencies(block, chunk) { |
| | | /** |
| | | * Iterator dependency. |
| | | * @param {Dependency} d dependency to (maybe) patch up |
| | | */ |
| | | const iteratorDependency = (d) => { |
| | |
| | | assignRuntimeIds() { |
| | | const { chunkGraph } = this; |
| | | /** |
| | | * Process entrypoint. |
| | | * @param {Entrypoint} ep an entrypoint |
| | | */ |
| | | const processEntrypoint = (ep) => { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Create module hash. |
| | | * @private |
| | | * @param {Module} module module |
| | | * @param {ChunkGraph} chunkGraph the chunk graph |
| | |
| | | hashDigestLength, |
| | | errors |
| | | ) { |
| | | /** @type {string} */ |
| | | let moduleHashDigest; |
| | | try { |
| | | const moduleHash = createHash(hashFunction); |
| | |
| | | |
| | | this.logger.time("hashing: sort chunks"); |
| | | /* |
| | | * all non-runtime chunks need to be hashes first, |
| | | * since runtime chunk might use their hashes. |
| | | * runtime chunks need to be hashed in the correct order |
| | | * since they may depend on each other (for async entrypoints). |
| | | * So we put all non-runtime chunks first and hash them in any order. |
| | | * And order runtime chunks according to referenced between each other. |
| | | * Chunks need to be in deterministic order since we add hashes to full chunk |
| | | * during these hashing. |
| | | * Chunks are hashed in 4 categories, in this order: |
| | | * 1. Async chunks - no hash dependencies on other chunks |
| | | * 2. Non-entry initial chunks (e.g. shared split chunks) - no hash |
| | | * dependencies on other chunks, but runtime chunks may read their |
| | | * hashes via GetChunkFilenameRuntimeModule (dependentHash) |
| | | * 3. Runtime chunks - may use hashes of async and non-entry initial |
| | | * chunks (via GetChunkFilenameRuntimeModule). Ordered by references |
| | | * between each other (for async entrypoints) |
| | | * 4. Entry chunks - may depend on runtimeChunk.hash (via |
| | | * createChunkHashHandler for ESM/CJS entry importing runtime) |
| | | * |
| | | * This ordering ensures all hash dependencies flow in one direction: |
| | | * async/initial → runtime → entry, with no circular dependencies. |
| | | * Chunks within each category are sorted by id for determinism. |
| | | */ |
| | | /** @type {Chunk[]} */ |
| | | const unorderedRuntimeChunks = []; |
| | | /** @type {Chunk[]} */ |
| | | const initialChunks = []; |
| | | /** @type {Chunk[]} */ |
| | | const entryChunks = []; |
| | | /** @type {Chunk[]} */ |
| | | const asyncChunks = []; |
| | | for (const c of this.chunks) { |
| | | if (c.hasRuntime()) { |
| | | unorderedRuntimeChunks.push(c); |
| | | } else if (chunkGraph.getNumberOfEntryModules(c) > 0) { |
| | | entryChunks.push(c); |
| | | } else if (c.canBeInitial()) { |
| | | initialChunks.push(c); |
| | | } else { |
| | |
| | | } |
| | | } |
| | | unorderedRuntimeChunks.sort(byId); |
| | | entryChunks.sort(byId); |
| | | initialChunks.sort(byId); |
| | | asyncChunks.sort(byId); |
| | | |
| | |
| | | (e) => e.chunks[e.chunks.length - 1] |
| | | ) |
| | | )) { |
| | | const otherInfo = |
| | | /** @type {RuntimeChunkInfo} */ |
| | | (runtimeChunksMap.get(other)); |
| | | otherInfo.referencedBy.push(info); |
| | | info.remaining++; |
| | | remaining++; |
| | | const otherInfo = runtimeChunksMap.get(other); |
| | | // other may be a non-runtime chunk (e.g. worker chunk) |
| | | // when you have a worker chunk in your app.js (new Worker(...)) and as a separate entry point |
| | | if (otherInfo) { |
| | | otherInfo.referencedBy.push(info); |
| | | info.remaining++; |
| | | remaining++; |
| | | } |
| | | } |
| | | } |
| | | /** @type {Chunk[]} */ |
| | |
| | | // If there are any references between chunks |
| | | // make sure to follow these chains |
| | | if (remaining > 0) { |
| | | /** @type {Chunk[]} */ |
| | | const readyChunks = []; |
| | | for (const chunk of runtimeChunks) { |
| | | const hasFullHashModules = |
| | |
| | | } |
| | | // If there are still remaining references we have cycles and want to create a warning |
| | | if (remaining > 0) { |
| | | /** @type {RuntimeChunkInfo[]} */ |
| | | const circularRuntimeChunkInfo = []; |
| | | for (const info of runtimeChunksMap.values()) { |
| | | if (info.remaining !== 0) { |
| | |
| | | } |
| | | this.logger.timeEnd("hashing: sort chunks"); |
| | | |
| | | /** @type {Set<Chunk>} */ |
| | | const fullHashChunks = new Set(); |
| | | /** @type {CodeGenerationJobs} */ |
| | | const codeGenerationJobs = []; |
| | |
| | | const errors = []; |
| | | |
| | | /** |
| | | * Processes the provided chunk. |
| | | * @param {Chunk} chunk chunk |
| | | */ |
| | | const processChunk = (chunk) => { |
| | |
| | | this.logger.timeAggregate("hashing: hash chunks"); |
| | | }; |
| | | for (const chunk of asyncChunks) processChunk(chunk); |
| | | for (const chunk of runtimeChunks) processChunk(chunk); |
| | | for (const chunk of initialChunks) processChunk(chunk); |
| | | for (const chunk of runtimeChunks) processChunk(chunk); |
| | | for (const chunk of entryChunks) processChunk(chunk); |
| | | if (errors.length > 0) { |
| | | errors.sort( |
| | | compareSelect((err) => err.module, compareModulesByIdentifier) |
| | |
| | | ).hash = moduleHashDigest; |
| | | } |
| | | const chunkHash = createHash(hashFunction); |
| | | chunkHash.update(chunk.hash); |
| | | chunkHash.update(/** @type {string} */ (chunk.hash)); |
| | | chunkHash.update(this.hash); |
| | | const chunkHashDigest = chunkHash.digest(hashDigest); |
| | | chunk.hash = chunkHashDigest; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided file. |
| | | * @param {string} file file name |
| | | * @param {Source} source asset source |
| | | * @param {AssetInfo} assetInfo extra asset information |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided file. |
| | | * @private |
| | | * @param {string} file file name |
| | | * @param {AssetInfo=} newInfo new asset information |
| | |
| | | if (oldRelated) { |
| | | for (const key of Object.keys(oldRelated)) { |
| | | /** |
| | | * Processes the provided name. |
| | | * @param {string} name name |
| | | */ |
| | | const remove = (name) => { |
| | |
| | | if (newRelated) { |
| | | for (const key of Object.keys(newRelated)) { |
| | | /** |
| | | * Processes the provided name. |
| | | * @param {string} name name |
| | | */ |
| | | const add = (name) => { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates asset using the provided file. |
| | | * @param {string} file file name |
| | | * @param {Source | ((source: Source) => Source)} newSourceOrFunction new asset source or function converting old to new |
| | | * @param {(AssetInfo | ((assetInfo?: AssetInfo) => AssetInfo | undefined)) | undefined} assetInfoUpdateOrFunction new asset info or function converting old to new |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided file. |
| | | * @param {string} file file name |
| | | * @param {string} newFile the new name of file |
| | | */ |
| | |
| | | const related = info.related; |
| | | if (!related) continue; |
| | | const entry = related[key]; |
| | | /** @type {string | string[]} */ |
| | | let newEntry; |
| | | if (Array.isArray(entry)) { |
| | | newEntry = entry.map((x) => (x === file ? newFile : x)); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided file. |
| | | * @param {string} file file name |
| | | */ |
| | | deleteAsset(file) { |
| | |
| | | if (related) { |
| | | for (const key of Object.keys(related)) { |
| | | /** |
| | | * Checks used and delete. |
| | | * @param {string} file file |
| | | */ |
| | | const checkUsedAndDelete = (file) => { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the asset or undefined when not found. |
| | | * @param {string} name the name of the asset |
| | | * @returns {Readonly<Asset> | undefined} the asset or undefined when not found |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Gets render manifest. |
| | | * @param {RenderManifestOptions} options options object |
| | | * @returns {RenderManifestEntry[]} manifest entries |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates a chunk assets. |
| | | * @param {Callback} callback signals when the call finishes |
| | | * @returns {void} |
| | | */ |
| | | createChunkAssets(callback) { |
| | | const outputOptions = this.outputOptions; |
| | | /** @type {WeakMap<Source, CachedSource>} */ |
| | | const cachedSourceMap = new WeakMap(); |
| | | /** @type {Map<string, {hash: string, source: Source, chunk: Chunk}>} */ |
| | | /** @type {Map<string, { hash: string, source: Source, chunk: Chunk }>} */ |
| | | const alreadyWrittenFiles = new Map(); |
| | | |
| | | asyncLib.forEachLimit( |
| | |
| | | |
| | | let inTry = true; |
| | | /** |
| | | * Error and callback. |
| | | * @param {Error} err error |
| | | * @returns {void} |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns interpolated path. |
| | | * @param {TemplatePath} filename used to get asset path with hash |
| | | * @param {PathData} data context data |
| | | * @returns {string} interpolated path |
| | |
| | | } |
| | | |
| | | /** |
| | | * Gets path with info. |
| | | * @param {TemplatePath} filename used to get asset path with hash |
| | | * @param {PathData} data context data |
| | | * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns interpolated path. |
| | | * @param {TemplatePath} filename used to get asset path with hash |
| | | * @param {PathData} data context data |
| | | * @returns {string} interpolated path |
| | |
| | | } |
| | | |
| | | /** |
| | | * Gets asset path with info. |
| | | * @param {TemplatePath} filename used to get asset path with hash |
| | | * @param {PathData} data context data |
| | | * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module the module |
| | | * @param {ExecuteModuleOptions} options options |
| | | * @param {ExecuteModuleCallback} callback callback |
| | |
| | | this.outputOptions.hashFunction |
| | | ); |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {Module} module the module |
| | | * @param {Callback} callback callback |
| | | * @returns {void} |
| | |
| | | }; |
| | | |
| | | // Generate code for all aggregated modules |
| | | asyncLib.eachLimit(modules, 10, codeGen, (err) => { |
| | | if (err) return callback(err); |
| | | reportErrors(); |
| | | |
| | | // for backward-compat temporary set the chunk graph |
| | | // TODO webpack 6 |
| | | const old = this.chunkGraph; |
| | | this.chunkGraph = chunkGraph; |
| | | this.processRuntimeRequirements({ |
| | | chunkGraph, |
| | | modules, |
| | | chunks, |
| | | codeGenerationResults, |
| | | chunkGraphEntries: chunks |
| | | }); |
| | | this.chunkGraph = old; |
| | | |
| | | const runtimeModules = |
| | | chunkGraph.getChunkRuntimeModulesIterable(chunk); |
| | | |
| | | // Hash runtime modules |
| | | for (const module of runtimeModules) { |
| | | modules.add(module); |
| | | this._createModuleHash( |
| | | module, |
| | | chunkGraph, |
| | | runtime, |
| | | hashFunction, |
| | | runtimeTemplate, |
| | | hashDigest, |
| | | hashDigestLength, |
| | | errors |
| | | ); |
| | | } |
| | | |
| | | // Generate code for all runtime modules |
| | | asyncLib.eachLimit(runtimeModules, 10, codeGen, (err) => { |
| | | asyncLib.eachLimit( |
| | | /** @type {import("neo-async").IterableCollection<Module>} */ ( |
| | | /** @type {unknown} */ (modules) |
| | | ), |
| | | 10, |
| | | codeGen, |
| | | (err) => { |
| | | if (err) return callback(err); |
| | | reportErrors(); |
| | | |
| | | /** @type {Map<Module, ExecuteModuleArgument>} */ |
| | | const moduleArgumentsMap = new Map(); |
| | | /** @type {Map<string, ExecuteModuleArgument>} */ |
| | | const moduleArgumentsById = new Map(); |
| | | |
| | | /** @type {ExecuteModuleResult["fileDependencies"]} */ |
| | | const fileDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["contextDependencies"]} */ |
| | | const contextDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["missingDependencies"]} */ |
| | | const missingDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["buildDependencies"]} */ |
| | | const buildDependencies = new LazySet(); |
| | | |
| | | /** @type {ExecuteModuleResult["assets"]} */ |
| | | const assets = new Map(); |
| | | |
| | | let cacheable = true; |
| | | |
| | | /** @type {ExecuteModuleContext} */ |
| | | const context = { |
| | | assets, |
| | | __webpack_require__: undefined, |
| | | chunk, |
| | | chunkGraph |
| | | }; |
| | | |
| | | // Prepare execution |
| | | asyncLib.eachLimit( |
| | | // for backward-compat temporary set the chunk graph |
| | | // TODO webpack 6 |
| | | const old = this.chunkGraph; |
| | | this.chunkGraph = chunkGraph; |
| | | this.processRuntimeRequirements({ |
| | | chunkGraph, |
| | | modules, |
| | | chunks, |
| | | codeGenerationResults, |
| | | chunkGraphEntries: chunks |
| | | }); |
| | | this.chunkGraph = old; |
| | | |
| | | const runtimeModules = |
| | | chunkGraph.getChunkRuntimeModulesIterable(chunk); |
| | | |
| | | // Hash runtime modules |
| | | for (const module of runtimeModules) { |
| | | modules.add(module); |
| | | this._createModuleHash( |
| | | module, |
| | | chunkGraph, |
| | | runtime, |
| | | hashFunction, |
| | | runtimeTemplate, |
| | | hashDigest, |
| | | hashDigestLength, |
| | | errors |
| | | ); |
| | | } |
| | | |
| | | // Generate code for all runtime modules |
| | | asyncLib.eachLimit( |
| | | /** @type {import("neo-async").IterableCollection<RuntimeModule>} */ ( |
| | | runtimeModules |
| | | ), |
| | | 10, |
| | | (module, callback) => { |
| | | const codeGenerationResult = codeGenerationResults.get( |
| | | module, |
| | | runtime |
| | | ); |
| | | /** @type {ExecuteModuleArgument} */ |
| | | const moduleArgument = { |
| | | module, |
| | | codeGenerationResult, |
| | | moduleObject: undefined |
| | | }; |
| | | moduleArgumentsMap.set(module, moduleArgument); |
| | | moduleArgumentsById.set(module.identifier(), moduleArgument); |
| | | module.addCacheDependencies( |
| | | fileDependencies, |
| | | contextDependencies, |
| | | missingDependencies, |
| | | buildDependencies |
| | | ); |
| | | if ( |
| | | /** @type {BuildInfo} */ (module.buildInfo).cacheable === |
| | | false |
| | | ) { |
| | | cacheable = false; |
| | | } |
| | | if (module.buildInfo && module.buildInfo.assets) { |
| | | const { assets: moduleAssets, assetsInfo } = module.buildInfo; |
| | | for (const assetName of Object.keys(moduleAssets)) { |
| | | assets.set(assetName, { |
| | | source: moduleAssets[assetName], |
| | | info: assetsInfo ? assetsInfo.get(assetName) : undefined |
| | | }); |
| | | } |
| | | } |
| | | this.hooks.prepareModuleExecution.callAsync( |
| | | moduleArgument, |
| | | context, |
| | | callback |
| | | ); |
| | | }, |
| | | codeGen, |
| | | (err) => { |
| | | if (err) return callback(err); |
| | | reportErrors(); |
| | | |
| | | /** @type {ExecuteModuleExports | undefined} */ |
| | | let exports; |
| | | try { |
| | | const { |
| | | strictModuleErrorHandling, |
| | | strictModuleExceptionHandling |
| | | } = this.outputOptions; |
| | | /** @type {Map<Module, ExecuteModuleArgument>} */ |
| | | const moduleArgumentsMap = new Map(); |
| | | /** @type {Map<string, ExecuteModuleArgument>} */ |
| | | const moduleArgumentsById = new Map(); |
| | | |
| | | /** @type {WebpackRequire} */ |
| | | const __webpack_require__ = (id) => { |
| | | const cached = moduleCache[id]; |
| | | if (cached !== undefined) { |
| | | if (cached.error) throw cached.error; |
| | | return cached.exports; |
| | | } |
| | | const moduleArgument = moduleArgumentsById.get(id); |
| | | return __webpack_require_module__( |
| | | /** @type {ExecuteModuleArgument} */ |
| | | (moduleArgument), |
| | | id |
| | | ); |
| | | }; |
| | | const interceptModuleExecution = (__webpack_require__[ |
| | | /** @type {"i"} */ |
| | | ( |
| | | RuntimeGlobals.interceptModuleExecution.replace( |
| | | `${RuntimeGlobals.require}.`, |
| | | "" |
| | | ) |
| | | ) |
| | | ] = /** @type {NonNullable<WebpackRequire["i"]>} */ ([])); |
| | | const moduleCache = (__webpack_require__[ |
| | | /** @type {"c"} */ ( |
| | | RuntimeGlobals.moduleCache.replace( |
| | | `${RuntimeGlobals.require}.`, |
| | | "" |
| | | ) |
| | | ) |
| | | ] = /** @type {NonNullable<WebpackRequire["c"]>} */ ({})); |
| | | /** @type {ExecuteModuleResult["fileDependencies"]} */ |
| | | const fileDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["contextDependencies"]} */ |
| | | const contextDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["missingDependencies"]} */ |
| | | const missingDependencies = new LazySet(); |
| | | /** @type {ExecuteModuleResult["buildDependencies"]} */ |
| | | const buildDependencies = new LazySet(); |
| | | |
| | | context.__webpack_require__ = __webpack_require__; |
| | | /** @type {ExecuteModuleResult["assets"]} */ |
| | | const assets = new Map(); |
| | | |
| | | /** |
| | | * @param {ExecuteModuleArgument} moduleArgument the module argument |
| | | * @param {string=} id id |
| | | * @returns {ExecuteModuleExports} exports |
| | | */ |
| | | const __webpack_require_module__ = (moduleArgument, id) => { |
| | | /** @type {ExecuteOptions} */ |
| | | const execOptions = { |
| | | id, |
| | | module: { |
| | | id, |
| | | exports: {}, |
| | | loaded: false, |
| | | error: undefined |
| | | }, |
| | | require: __webpack_require__ |
| | | }; |
| | | for (const handler of interceptModuleExecution) { |
| | | handler(execOptions); |
| | | } |
| | | const module = moduleArgument.module; |
| | | this.buildTimeExecutedModules.add(module); |
| | | const moduleObject = execOptions.module; |
| | | moduleArgument.moduleObject = moduleObject; |
| | | try { |
| | | if (id) moduleCache[id] = moduleObject; |
| | | let cacheable = true; |
| | | |
| | | tryRunOrWebpackError( |
| | | () => |
| | | this.hooks.executeModule.call( |
| | | moduleArgument, |
| | | context |
| | | ), |
| | | "Compilation.hooks.executeModule" |
| | | ); |
| | | moduleObject.loaded = true; |
| | | return moduleObject.exports; |
| | | } catch (execErr) { |
| | | if (strictModuleExceptionHandling) { |
| | | if (id) delete moduleCache[id]; |
| | | } else if (strictModuleErrorHandling) { |
| | | moduleObject.error = |
| | | /** @type {WebpackError} */ |
| | | (execErr); |
| | | } |
| | | if (!(/** @type {WebpackError} */ (execErr).module)) { |
| | | /** @type {WebpackError} */ |
| | | (execErr).module = module; |
| | | } |
| | | throw execErr; |
| | | } |
| | | }; |
| | | |
| | | for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder( |
| | | chunk |
| | | )) { |
| | | __webpack_require_module__( |
| | | /** @type {ExecuteModuleArgument} */ |
| | | (moduleArgumentsMap.get(runtimeModule)) |
| | | ); |
| | | } |
| | | |
| | | exports = __webpack_require__(module.identifier()); |
| | | } catch (execErr) { |
| | | const { message, stack, module } = |
| | | /** @type {WebpackError} */ |
| | | (execErr); |
| | | const err = new WebpackError( |
| | | `Execution of module code from module graph (${ |
| | | /** @type {Module} */ |
| | | (module).readableIdentifier(this.requestShortener) |
| | | }) failed: ${message}`, |
| | | { cause: execErr } |
| | | ); |
| | | err.stack = stack; |
| | | err.module = module; |
| | | return callback(err); |
| | | } |
| | | |
| | | callback(null, { |
| | | exports, |
| | | /** @type {ExecuteModuleContext} */ |
| | | const context = { |
| | | assets, |
| | | cacheable, |
| | | fileDependencies, |
| | | contextDependencies, |
| | | missingDependencies, |
| | | buildDependencies |
| | | }); |
| | | __webpack_require__: undefined, |
| | | chunk, |
| | | chunkGraph |
| | | }; |
| | | |
| | | // Prepare execution |
| | | asyncLib.eachLimit( |
| | | modules, |
| | | 10, |
| | | (module, callback) => { |
| | | const codeGenerationResult = codeGenerationResults.get( |
| | | module, |
| | | runtime |
| | | ); |
| | | /** @type {ExecuteModuleArgument} */ |
| | | const moduleArgument = { |
| | | module, |
| | | codeGenerationResult, |
| | | moduleObject: undefined |
| | | }; |
| | | moduleArgumentsMap.set(module, moduleArgument); |
| | | moduleArgumentsById.set( |
| | | module.identifier(), |
| | | moduleArgument |
| | | ); |
| | | module.addCacheDependencies( |
| | | fileDependencies, |
| | | contextDependencies, |
| | | missingDependencies, |
| | | buildDependencies |
| | | ); |
| | | if ( |
| | | /** @type {BuildInfo} */ (module.buildInfo).cacheable === |
| | | false |
| | | ) { |
| | | cacheable = false; |
| | | } |
| | | if (module.buildInfo && module.buildInfo.assets) { |
| | | const { assets: moduleAssets, assetsInfo } = |
| | | module.buildInfo; |
| | | for (const assetName of Object.keys(moduleAssets)) { |
| | | assets.set(assetName, { |
| | | source: moduleAssets[assetName], |
| | | info: assetsInfo |
| | | ? assetsInfo.get(assetName) |
| | | : undefined |
| | | }); |
| | | } |
| | | } |
| | | this.hooks.prepareModuleExecution.callAsync( |
| | | moduleArgument, |
| | | context, |
| | | callback |
| | | ); |
| | | }, |
| | | (err) => { |
| | | if (err) return callback(/** @type {WebpackError} */ (err)); |
| | | |
| | | /** @type {ExecuteModuleExports | undefined} */ |
| | | let exports; |
| | | try { |
| | | const { |
| | | strictModuleErrorHandling, |
| | | strictModuleExceptionHandling |
| | | } = this.outputOptions; |
| | | |
| | | /** @type {WebpackRequire} */ |
| | | const __webpack_require__ = (id) => { |
| | | const cached = moduleCache[id]; |
| | | if (cached !== undefined) { |
| | | if (cached.error) throw cached.error; |
| | | return cached.exports; |
| | | } |
| | | const moduleArgument = moduleArgumentsById.get(id); |
| | | return __webpack_require_module__( |
| | | /** @type {ExecuteModuleArgument} */ |
| | | (moduleArgument), |
| | | id |
| | | ); |
| | | }; |
| | | const interceptModuleExecution = (__webpack_require__[ |
| | | /** @type {"i"} */ |
| | | ( |
| | | RuntimeGlobals.interceptModuleExecution.replace( |
| | | `${RuntimeGlobals.require}.`, |
| | | "" |
| | | ) |
| | | ) |
| | | ] = /** @type {NonNullable<WebpackRequire["i"]>} */ ([])); |
| | | const moduleCache = (__webpack_require__[ |
| | | /** @type {"c"} */ ( |
| | | RuntimeGlobals.moduleCache.replace( |
| | | `${RuntimeGlobals.require}.`, |
| | | "" |
| | | ) |
| | | ) |
| | | ] = /** @type {NonNullable<WebpackRequire["c"]>} */ ({})); |
| | | |
| | | context.__webpack_require__ = __webpack_require__; |
| | | |
| | | /** |
| | | * Webpack require module. |
| | | * @param {ExecuteModuleArgument} moduleArgument the module argument |
| | | * @param {string=} id id |
| | | * @returns {ExecuteModuleExports} exports |
| | | */ |
| | | const __webpack_require_module__ = ( |
| | | moduleArgument, |
| | | id |
| | | ) => { |
| | | /** @type {ExecuteOptions} */ |
| | | const execOptions = { |
| | | id, |
| | | module: { |
| | | id, |
| | | exports: {}, |
| | | loaded: false, |
| | | error: undefined |
| | | }, |
| | | require: __webpack_require__ |
| | | }; |
| | | for (const handler of interceptModuleExecution) { |
| | | handler(execOptions); |
| | | } |
| | | const module = moduleArgument.module; |
| | | this.buildTimeExecutedModules.add(module); |
| | | const moduleObject = execOptions.module; |
| | | moduleArgument.moduleObject = moduleObject; |
| | | try { |
| | | if (id) moduleCache[id] = moduleObject; |
| | | |
| | | tryRunOrWebpackError( |
| | | () => |
| | | this.hooks.executeModule.call( |
| | | moduleArgument, |
| | | context |
| | | ), |
| | | "Compilation.hooks.executeModule" |
| | | ); |
| | | moduleObject.loaded = true; |
| | | return moduleObject.exports; |
| | | } catch (execErr) { |
| | | if (strictModuleExceptionHandling) { |
| | | if (id) delete moduleCache[id]; |
| | | } else if (strictModuleErrorHandling) { |
| | | moduleObject.error = |
| | | /** @type {WebpackError} */ |
| | | (execErr); |
| | | } |
| | | if (!(/** @type {WebpackError} */ (execErr).module)) { |
| | | /** @type {WebpackError} */ |
| | | (execErr).module = module; |
| | | } |
| | | throw execErr; |
| | | } |
| | | }; |
| | | |
| | | for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder( |
| | | chunk |
| | | )) { |
| | | __webpack_require_module__( |
| | | /** @type {ExecuteModuleArgument} */ |
| | | (moduleArgumentsMap.get(runtimeModule)) |
| | | ); |
| | | } |
| | | |
| | | exports = __webpack_require__(module.identifier()); |
| | | } catch (execErr) { |
| | | const { message, stack, module } = |
| | | /** @type {WebpackError} */ |
| | | (execErr); |
| | | const err = new WebpackError( |
| | | `Execution of module code from module graph (${ |
| | | /** @type {Module} */ |
| | | (module).readableIdentifier(this.requestShortener) |
| | | }) failed: ${message}`, |
| | | { cause: execErr } |
| | | ); |
| | | err.stack = stack; |
| | | err.module = module; |
| | | return callback(err); |
| | | } |
| | | |
| | | callback(null, { |
| | | exports, |
| | | assets, |
| | | cacheable, |
| | | fileDependencies, |
| | | contextDependencies, |
| | | missingDependencies, |
| | | buildDependencies |
| | | }); |
| | | } |
| | | ); |
| | | } |
| | | ); |
| | | }); |
| | | }); |
| | | } |
| | | ); |
| | | } |
| | | ); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Defines the factorize module options type used by this module. |
| | | * @typedef {object} FactorizeModuleOptions |
| | | * @property {ModuleProfile=} currentProfile |
| | | * @property {ModuleFactory} factory |
| | |
| | | */ |
| | | |
| | | /** |
| | | * Processes the provided factorize module option. |
| | | * @param {FactorizeModuleOptions} options options object |
| | | * @param {ModuleCallback | ModuleFactoryResultCallback} callback callback |
| | | * @returns {void} |
| | |
| | | configurable: false, |
| | | get: util.deprecate( |
| | | /** |
| | | * Returns the cache. |
| | | * @this {Compilation} the compilation |
| | | * @returns {Cache} the cache |
| | | */ |
| | |
| | | ), |
| | | set: util.deprecate( |
| | | /** |
| | | * Handles the value callback for this hook. |
| | | * @param {EXPECTED_ANY} _v value |
| | | */ |
| | | (_v) => {}, |