/
githubmirror
/
webpack
Обзор
Документация
Войти
/
githubmirror
/
webpack
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
lib/esm/ModuleChunkLoadingPlugin.js
172 строки
6 KB
Alexander Akait
feat(esm): widen analyzable output to HMR, hashed and function chunk filenames (#21653)
10 авг 2026, 09:28
Не верифицирован
10 авг 2026, 09:28
e3f177c
Код
Авторство
О чём код?
/* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ "use strict"; const RuntimeGlobals = require("../RuntimeGlobals"); const lazyModule = require("../util/lazyModule"); const AnalyzableChunkHashPlugin = require("./AnalyzableChunkHashPlugin"); /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ // only a chunk that loads other chunks at runtime emits these const getExportWebpackRequireRuntimeModule = lazyModule(() => require("./ExportWebpackRequireRuntimeModule") ); const getModuleChunkLoadingRuntimeModule = lazyModule(() => require("./ModuleChunkLoadingRuntimeModule") ); const PLUGIN_NAME = "ModuleChunkLoadingPlugin"; class ModuleChunkLoadingPlugin { /** * Applies the plugin by registering its hooks on the compiler. * @param {Compiler} compiler the compiler instance * @returns {void} */ apply(compiler) { // Fills in the specifiers this plugin's analyzable `import()` reserves. new AnalyzableChunkHashPlugin().apply(compiler); compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { const globalChunkLoading = compilation.outputOptions.chunkLoading; /** * Checks whether this module chunk loading plugin is enabled for chunk. * @param {Chunk} chunk chunk to check * @returns {boolean} true, when the plugin is enabled for the chunk */ const isEnabledForChunk = (chunk) => { const options = chunk.getEntryOptions(); const chunkLoading = options && options.chunkLoading !== undefined ? options.chunkLoading : globalChunkLoading; return chunkLoading === "import"; }; /** @type {WeakSet<Chunk>} */ const onceForChunkSet = new WeakSet(); /** * Handles the hook callback for this code path. * @param {Chunk} chunk chunk to check * @param {RuntimeRequirements} set runtime requirements */ const handler = (chunk, set) => { if (onceForChunkSet.has(chunk)) return; onceForChunkSet.add(chunk); if (!isEnabledForChunk(chunk)) return; set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.hasOwnProperty); compilation.addLazyRuntimeModule( chunk, getModuleChunkLoadingRuntimeModule, (Ctor) => new Ctor(set) ); }; compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.ensureChunkHandlers) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.baseURI) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.externalInstallChunk) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.analyzableChunkImport) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.onChunksLoaded) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.hmrDownloadUpdateHandlers) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.hmrDownloadManifest) .tap(PLUGIN_NAME, handler); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.externalInstallChunk) .tap(PLUGIN_NAME, (chunk) => { if (!isEnabledForChunk(chunk)) return; compilation.addLazyRuntimeModule( chunk, getExportWebpackRequireRuntimeModule, (Ctor) => new Ctor() ); }); // The prefetch/preload handlers build the chunk URL themselves, so they need // the public path and script filename directly — without relying on // `ensureChunkHandlers` to pull them in (an analyzable `import()` may replace it). compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.prefetchChunkHandlers) .tap(PLUGIN_NAME, (chunk, set) => { if (!isEnabledForChunk(chunk)) return; set.add(RuntimeGlobals.publicPath); set.add(RuntimeGlobals.getChunkScriptFilename); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.preloadChunkHandlers) .tap(PLUGIN_NAME, (chunk, set) => { if (!isEnabledForChunk(chunk)) return; set.add(RuntimeGlobals.publicPath); set.add(RuntimeGlobals.getChunkScriptFilename); }); // Keyed on `ensureChunk`, not on the handler map: only the runtime chunk loader // builds a URL from a chunk id, and an analyzable `import()` carries its own. compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.ensureChunk) .tap(PLUGIN_NAME, (chunk, set) => { if (!isEnabledForChunk(chunk)) return; if (compilation.outputOptions.publicPath !== "auto") { set.add(RuntimeGlobals.publicPath); } set.add(RuntimeGlobals.getChunkScriptFilename); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.hmrDownloadUpdateHandlers) .tap(PLUGIN_NAME, (chunk, set) => { if (!isEnabledForChunk(chunk)) return; set.add(RuntimeGlobals.publicPath); set.add(RuntimeGlobals.getChunkUpdateScriptFilename); // The hot runtime force-loads through the handler map by bare chunk id, so // the map and loader stay however analyzable — but only where there are // async chunks to force-load. if (chunk.hasAsyncChunks()) { set.add(RuntimeGlobals.ensureChunkHandlers); set.add(RuntimeGlobals.getChunkScriptFilename); } set.add(RuntimeGlobals.moduleCache); set.add(RuntimeGlobals.hmrModuleData); set.add(RuntimeGlobals.moduleFactoriesAddOnly); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.hmrDownloadManifest) .tap(PLUGIN_NAME, (chunk, set) => { if (!isEnabledForChunk(chunk)) return; set.add(RuntimeGlobals.publicPath); set.add(RuntimeGlobals.getUpdateManifestFilename); }); compilation.hooks.additionalTreeRuntimeRequirements.tap( PLUGIN_NAME, (chunk, set, { chunkGraph }) => { if (chunkGraph.hasChunkEntryDependentChunks(chunk)) { set.add(RuntimeGlobals.externalInstallChunk); } } ); }); } } module.exports = ModuleChunkLoadingPlugin;