ArrayPushCallbackChunkFormatPlugin.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { ConcatSource, PrefixSource, RawSource } = require("webpack-sources");
  7. const { RuntimeGlobals } = require("..");
  8. const HotUpdateChunk = require("../HotUpdateChunk");
  9. const Template = require("../Template");
  10. const { getCompilationHooks } = require("./JavascriptModulesPlugin");
  11. const {
  12. generateEntryStartup,
  13. updateHashForEntryStartup
  14. } = require("./StartupHelpers");
  15. /** @typedef {import("../Compiler")} Compiler */
  16. class ArrayPushCallbackChunkFormatPlugin {
  17. /**
  18. * Apply the plugin
  19. * @param {Compiler} compiler the compiler instance
  20. * @returns {void}
  21. */
  22. apply(compiler) {
  23. compiler.hooks.thisCompilation.tap(
  24. "ArrayPushCallbackChunkFormatPlugin",
  25. compilation => {
  26. compilation.hooks.additionalChunkRuntimeRequirements.tap(
  27. "ArrayPushCallbackChunkFormatPlugin",
  28. (chunk, set, { chunkGraph }) => {
  29. if (chunk.hasRuntime()) return;
  30. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
  31. set.add(RuntimeGlobals.onChunksLoaded);
  32. set.add(RuntimeGlobals.exports);
  33. set.add(RuntimeGlobals.require);
  34. }
  35. set.add(RuntimeGlobals.chunkCallback);
  36. }
  37. );
  38. const hooks = getCompilationHooks(compilation);
  39. hooks.renderChunk.tap(
  40. "ArrayPushCallbackChunkFormatPlugin",
  41. (modules, renderContext) => {
  42. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  43. const hotUpdateChunk =
  44. chunk instanceof HotUpdateChunk ? chunk : null;
  45. const globalObject = runtimeTemplate.globalObject;
  46. const source = new ConcatSource();
  47. const runtimeModules =
  48. chunkGraph.getChunkRuntimeModulesInOrder(chunk);
  49. if (hotUpdateChunk) {
  50. const hotUpdateGlobal =
  51. runtimeTemplate.outputOptions.hotUpdateGlobal;
  52. source.add(
  53. `${globalObject}[${JSON.stringify(hotUpdateGlobal)}](`
  54. );
  55. source.add(`${JSON.stringify(chunk.id)},`);
  56. source.add(modules);
  57. if (runtimeModules.length > 0) {
  58. source.add(",\n");
  59. const runtimePart = Template.renderChunkRuntimeModules(
  60. runtimeModules,
  61. renderContext
  62. );
  63. source.add(runtimePart);
  64. }
  65. source.add(")");
  66. } else {
  67. const chunkLoadingGlobal =
  68. runtimeTemplate.outputOptions.chunkLoadingGlobal;
  69. source.add(
  70. `(${globalObject}[${JSON.stringify(
  71. chunkLoadingGlobal
  72. )}] = ${globalObject}[${JSON.stringify(
  73. chunkLoadingGlobal
  74. )}] || []).push([`
  75. );
  76. source.add(`${JSON.stringify(chunk.ids)},`);
  77. source.add(modules);
  78. const entries = Array.from(
  79. chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
  80. );
  81. if (runtimeModules.length > 0 || entries.length > 0) {
  82. const runtime = new ConcatSource(
  83. (runtimeTemplate.supportsArrowFunction()
  84. ? `${RuntimeGlobals.require} =>`
  85. : `function(${RuntimeGlobals.require})`) +
  86. " { // webpackRuntimeModules\n"
  87. );
  88. if (runtimeModules.length > 0) {
  89. runtime.add(
  90. Template.renderRuntimeModules(runtimeModules, {
  91. ...renderContext,
  92. codeGenerationResults: compilation.codeGenerationResults
  93. })
  94. );
  95. }
  96. if (entries.length > 0) {
  97. const startupSource = new RawSource(
  98. generateEntryStartup(
  99. chunkGraph,
  100. runtimeTemplate,
  101. entries,
  102. chunk,
  103. true
  104. )
  105. );
  106. runtime.add(
  107. hooks.renderStartup.call(
  108. startupSource,
  109. entries[entries.length - 1][0],
  110. {
  111. ...renderContext,
  112. inlined: false
  113. }
  114. )
  115. );
  116. if (
  117. chunkGraph
  118. .getChunkRuntimeRequirements(chunk)
  119. .has(RuntimeGlobals.returnExportsFromRuntime)
  120. ) {
  121. runtime.add(`return ${RuntimeGlobals.exports};\n`);
  122. }
  123. }
  124. runtime.add("}\n");
  125. source.add(",\n");
  126. source.add(new PrefixSource("/******/ ", runtime));
  127. }
  128. source.add("])");
  129. }
  130. return source;
  131. }
  132. );
  133. hooks.chunkHash.tap(
  134. "ArrayPushCallbackChunkFormatPlugin",
  135. (chunk, hash, { chunkGraph, runtimeTemplate }) => {
  136. if (chunk.hasRuntime()) return;
  137. hash.update(
  138. `ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.globalObject}`
  139. );
  140. const entries = Array.from(
  141. chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
  142. );
  143. updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
  144. }
  145. );
  146. }
  147. );
  148. }
  149. }
  150. module.exports = ArrayPushCallbackChunkFormatPlugin;