StartupChunkDependenciesPlugin.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const RuntimeGlobals = require("../RuntimeGlobals");
  6. const StartupChunkDependenciesRuntimeModule = require("./StartupChunkDependenciesRuntimeModule");
  7. const StartupEntrypointRuntimeModule = require("./StartupEntrypointRuntimeModule");
  8. /** @typedef {import("../../declarations/WebpackOptions").ChunkLoadingType} ChunkLoadingType */
  9. /** @typedef {import("../Chunk")} Chunk */
  10. /** @typedef {import("../Compiler")} Compiler */
  11. /**
  12. * @typedef {object} Options
  13. * @property {ChunkLoadingType} chunkLoading
  14. * @property {boolean=} asyncChunkLoading
  15. */
  16. const PLUGIN_NAME = "StartupChunkDependenciesPlugin";
  17. class StartupChunkDependenciesPlugin {
  18. /**
  19. * @param {Options} options options
  20. */
  21. constructor(options) {
  22. /** @type {ChunkLoadingType} */
  23. this.chunkLoading = options.chunkLoading;
  24. /** @type {boolean} */
  25. this.asyncChunkLoading =
  26. typeof options.asyncChunkLoading === "boolean"
  27. ? options.asyncChunkLoading
  28. : true;
  29. }
  30. /**
  31. * Apply the plugin
  32. * @param {Compiler} compiler the compiler instance
  33. * @returns {void}
  34. */
  35. apply(compiler) {
  36. compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
  37. const globalChunkLoading = compilation.outputOptions.chunkLoading;
  38. /**
  39. * @param {Chunk} chunk chunk to check
  40. * @returns {boolean} true, when the plugin is enabled for the chunk
  41. */
  42. const isEnabledForChunk = (chunk) => {
  43. const options = chunk.getEntryOptions();
  44. const chunkLoading =
  45. options && options.chunkLoading !== undefined
  46. ? options.chunkLoading
  47. : globalChunkLoading;
  48. return chunkLoading === this.chunkLoading;
  49. };
  50. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  51. PLUGIN_NAME,
  52. (chunk, set, { chunkGraph }) => {
  53. if (!isEnabledForChunk(chunk)) return;
  54. if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
  55. set.add(RuntimeGlobals.startup);
  56. set.add(RuntimeGlobals.ensureChunk);
  57. set.add(RuntimeGlobals.ensureChunkIncludeEntries);
  58. compilation.addRuntimeModule(
  59. chunk,
  60. new StartupChunkDependenciesRuntimeModule(this.asyncChunkLoading)
  61. );
  62. }
  63. }
  64. );
  65. compilation.hooks.runtimeRequirementInTree
  66. .for(RuntimeGlobals.startupEntrypoint)
  67. .tap(PLUGIN_NAME, (chunk, set) => {
  68. if (!isEnabledForChunk(chunk)) return;
  69. set.add(RuntimeGlobals.require);
  70. set.add(RuntimeGlobals.ensureChunk);
  71. set.add(RuntimeGlobals.ensureChunkIncludeEntries);
  72. compilation.addRuntimeModule(
  73. chunk,
  74. new StartupEntrypointRuntimeModule(this.asyncChunkLoading)
  75. );
  76. });
  77. });
  78. }
  79. }
  80. module.exports = StartupChunkDependenciesPlugin;