EnsureChunkRuntimeModule.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const RuntimeGlobals = require("../RuntimeGlobals");
  6. const RuntimeModule = require("../RuntimeModule");
  7. const Template = require("../Template");
  8. /** @import Compilation from "../Compilation" */
  9. /** @import { ReadOnlyRuntimeRequirements } from "../Module" */
  10. class EnsureChunkRuntimeModule extends RuntimeModule {
  11. /**
  12. * Returns true, if the runtime module should get it's own scope.
  13. * When false, `generate()` must emit complete statements ending with `;`
  14. * so a following runtime IIFE is not parsed as a call (ASI).
  15. * @returns {boolean} true, if the runtime module should get it's own scope
  16. */
  17. shouldIsolate() {
  18. return false;
  19. }
  20. /**
  21. * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
  22. */
  23. constructor(runtimeRequirements) {
  24. super("ensure chunk");
  25. /** @type {ReadOnlyRuntimeRequirements} */
  26. this.runtimeRequirements = runtimeRequirements;
  27. }
  28. /**
  29. * Generates runtime code for this runtime module.
  30. * @returns {string | null} runtime code
  31. */
  32. generate() {
  33. const compilation = /** @type {Compilation} */ (this.compilation);
  34. const { runtimeTemplate } = compilation;
  35. // An analyzable `import()` dispatches the handlers itself, so a build can need the
  36. // map without the function around it.
  37. const withEnsureChunk = this.runtimeRequirements.has(
  38. RuntimeGlobals.ensureChunk
  39. );
  40. // Check if there are non initial chunks which need to be imported using require-ensure
  41. if (this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)) {
  42. const withFetchPriority = this.runtimeRequirements.has(
  43. RuntimeGlobals.hasFetchPriority
  44. );
  45. const handlers = RuntimeGlobals.ensureChunkHandlers;
  46. if (!withEnsureChunk) return `${handlers} = {};`;
  47. return Template.asString([
  48. `${handlers} = {};`,
  49. "// This file contains only the entry chunk.",
  50. "// The chunk loading function for additional chunks",
  51. `${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.basicFunction(
  52. `chunkId${withFetchPriority ? ", fetchPriority" : ""}`,
  53. [
  54. `return Promise.all(Object.keys(${handlers}).reduce(${runtimeTemplate.basicFunction(
  55. "promises, key",
  56. [
  57. `${handlers}[key](chunkId, promises${
  58. withFetchPriority ? ", fetchPriority" : ""
  59. });`,
  60. "return promises;"
  61. ]
  62. )}, []));`
  63. ]
  64. )};`
  65. ]);
  66. }
  67. // There ensureChunk is used somewhere in the tree, so we need an empty requireEnsure
  68. // function. This can happen with multiple entrypoints.
  69. return Template.asString([
  70. "// The chunk loading function for additional chunks",
  71. "// Since all referenced chunks are already included",
  72. "// in this file, this function is empty here.",
  73. `${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.returningFunction(
  74. "Promise.resolve()"
  75. )};`
  76. ]);
  77. }
  78. }
  79. module.exports = EnsureChunkRuntimeModule;