OnChunksLoadedRuntimeModule.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. class OnChunksLoadedRuntimeModule extends RuntimeModule {
  10. constructor() {
  11. super("chunk loaded");
  12. }
  13. /**
  14. * Generates runtime code for this runtime module.
  15. * @returns {string | null} runtime code
  16. */
  17. generate() {
  18. const compilation = /** @type {Compilation} */ (this.compilation);
  19. const { runtimeTemplate } = compilation;
  20. return Template.asString([
  21. `${runtimeTemplate.renderConst()} deferred = [];`,
  22. `${RuntimeGlobals.onChunksLoaded} = ${runtimeTemplate.basicFunction(
  23. "result, chunkIds, fn, priority",
  24. [
  25. "if(chunkIds) {",
  26. Template.indent([
  27. `${runtimeTemplate.assignOr("priority", "0")};`,
  28. "for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];",
  29. "deferred[i] = [chunkIds, fn, priority];",
  30. "return;"
  31. ]),
  32. "}",
  33. `${runtimeTemplate.renderLet()} notFulfilled = Infinity;`,
  34. "for (var i = 0; i < deferred.length; i++) {",
  35. Template.indent([
  36. runtimeTemplate.destructureArray(
  37. ["chunkIds", "fn", "priority"],
  38. "deferred[i]"
  39. ),
  40. `${runtimeTemplate.renderLet()} fulfilled = true;`,
  41. "for (var j = 0; j < chunkIds.length; j++) {",
  42. Template.indent([
  43. // Parenthesized: `&` binds looser than `===`, so `priority & 1 === 0`
  44. // is `priority & false` and gates every priority, not just the odd ones.
  45. `if (((priority & 1) === 0 || notFulfilled >= priority) && Object.keys(${
  46. RuntimeGlobals.onChunksLoaded
  47. }).every(${runtimeTemplate.returningFunction(
  48. `${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`,
  49. "key"
  50. )})) {`,
  51. Template.indent(["chunkIds.splice(j--, 1);"]),
  52. "} else {",
  53. Template.indent([
  54. "fulfilled = false;",
  55. "if(priority < notFulfilled) notFulfilled = priority;"
  56. ]),
  57. "}"
  58. ]),
  59. "}",
  60. "if(fulfilled) {",
  61. Template.indent([
  62. "deferred.splice(i--, 1)",
  63. `${runtimeTemplate.renderConst()} r = fn();`,
  64. "if (r !== undefined) result = r;"
  65. ]),
  66. "}"
  67. ]),
  68. "}",
  69. "return result;"
  70. ]
  71. )};`
  72. ]);
  73. }
  74. }
  75. module.exports = OnChunksLoadedRuntimeModule;