webpack
Version:
Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
110 lines (100 loc) • 3.6 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
;
const RuntimeGlobals = require("../RuntimeGlobals");
const lazyModule = require("../util/lazyModule");
/** @import { ChunkLoadingType } from "../../declarations/WebpackOptions" */
/** @import Chunk from "../Chunk" */
/** @import Compiler from "../Compiler" */
// only a chunk with startup dependencies emits these
const getStartupChunkDependenciesRuntimeModule = lazyModule(() =>
require("./StartupChunkDependenciesRuntimeModule")
);
const getStartupEntrypointRuntimeModule = lazyModule(() =>
require("./StartupEntrypointRuntimeModule")
);
/**
* Options that describe which chunk loading backend should receive startup
* dependency handling and whether the runtime should wait for those chunks
* asynchronously.
* @typedef {object} Options
* @property {ChunkLoadingType} chunkLoading
* @property {boolean=} asyncChunkLoading
*/
const PLUGIN_NAME = "StartupChunkDependenciesPlugin";
/**
* Adds runtime modules that delay entry startup until entry-dependent chunks
* required by the selected chunk loading strategy have been loaded.
*/
class StartupChunkDependenciesPlugin {
/**
* Configures which chunk loading implementation this plugin should enhance
* and whether startup waits should use promises or synchronous ensures.
* @param {Options} options options
*/
constructor(options) {
/** @type {ChunkLoadingType} */
this.chunkLoading = options.chunkLoading;
/** @type {boolean} */
this.asyncChunkLoading =
typeof options.asyncChunkLoading === "boolean"
? options.asyncChunkLoading
: true;
}
/**
* Registers compilation hooks that attach the startup dependency runtime
* modules to entry chunks using the configured chunk loading mechanism.
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
const globalChunkLoading = compilation.outputOptions.chunkLoading;
/**
* Determines whether a chunk uses the chunk loading backend that this
* plugin is responsible for augmenting.
* @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 === this.chunkLoading;
};
compilation.hooks.additionalTreeRuntimeRequirements.tap(
PLUGIN_NAME,
(chunk, set, { chunkGraph }) => {
if (!isEnabledForChunk(chunk)) return;
if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
set.add(RuntimeGlobals.startup);
set.add(RuntimeGlobals.ensureChunk);
set.add(RuntimeGlobals.ensureChunkIncludeEntries);
compilation.addLazyRuntimeModule(
chunk,
getStartupChunkDependenciesRuntimeModule,
(Ctor) => new Ctor(this.asyncChunkLoading)
);
}
}
);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.startupEntrypoint)
.tap(PLUGIN_NAME, (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.require);
set.add(RuntimeGlobals.ensureChunk);
set.add(RuntimeGlobals.ensureChunkIncludeEntries);
compilation.addLazyRuntimeModule(
chunk,
getStartupEntrypointRuntimeModule,
(Ctor) => new Ctor(this.asyncChunkLoading)
);
});
});
}
}
module.exports = StartupChunkDependenciesPlugin;