RuntimePlugin.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const RuntimeGlobals = require("./RuntimeGlobals");
  7. const { getChunkFilenameTemplate } = require("./css/CssModulesPlugin");
  8. const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
  9. const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
  10. const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
  11. const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
  12. const BaseUriRuntimeModule = require("./runtime/BaseUriRuntimeModule");
  13. const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
  14. const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
  15. const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
  16. const CreateScriptRuntimeModule = require("./runtime/CreateScriptRuntimeModule");
  17. const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule");
  18. const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
  19. const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule");
  20. const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule");
  21. const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule");
  22. const GetTrustedTypesPolicyRuntimeModule = require("./runtime/GetTrustedTypesPolicyRuntimeModule");
  23. const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule");
  24. const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule");
  25. const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
  26. const MakeDeferredNamespaceObjectRuntime = require("./runtime/MakeDeferredNamespaceObjectRuntime");
  27. const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
  28. const NonceRuntimeModule = require("./runtime/NonceRuntimeModule");
  29. const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule");
  30. const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
  31. const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule");
  32. const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
  33. const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
  34. const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
  35. const StringXor = require("./util/StringXor");
  36. const memoize = require("./util/memoize");
  37. /** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
  38. /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputNormalized */
  39. /** @typedef {import("./Chunk")} Chunk */
  40. /** @typedef {import("./Compiler")} Compiler */
  41. /** @typedef {import("./Module")} Module */
  42. /** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */
  43. const getJavascriptModulesPlugin = memoize(() =>
  44. require("./javascript/JavascriptModulesPlugin")
  45. );
  46. const getCssModulesPlugin = memoize(() => require("./css/CssModulesPlugin"));
  47. const GLOBALS_ON_REQUIRE = [
  48. RuntimeGlobals.chunkName,
  49. RuntimeGlobals.runtimeId,
  50. RuntimeGlobals.compatGetDefaultExport,
  51. RuntimeGlobals.createFakeNamespaceObject,
  52. RuntimeGlobals.createScript,
  53. RuntimeGlobals.createScriptUrl,
  54. RuntimeGlobals.getTrustedTypesPolicy,
  55. RuntimeGlobals.definePropertyGetters,
  56. RuntimeGlobals.ensureChunk,
  57. RuntimeGlobals.entryModuleId,
  58. RuntimeGlobals.getFullHash,
  59. RuntimeGlobals.global,
  60. RuntimeGlobals.makeNamespaceObject,
  61. RuntimeGlobals.moduleCache,
  62. RuntimeGlobals.moduleFactories,
  63. RuntimeGlobals.moduleFactoriesAddOnly,
  64. RuntimeGlobals.interceptModuleExecution,
  65. RuntimeGlobals.publicPath,
  66. RuntimeGlobals.baseURI,
  67. RuntimeGlobals.relativeUrl,
  68. // TODO webpack 6 - rename to nonce, because we use it for CSS too
  69. RuntimeGlobals.scriptNonce,
  70. RuntimeGlobals.uncaughtErrorHandler,
  71. RuntimeGlobals.asyncModule,
  72. RuntimeGlobals.wasmInstances,
  73. RuntimeGlobals.instantiateWasm,
  74. RuntimeGlobals.shareScopeMap,
  75. RuntimeGlobals.initializeSharing,
  76. RuntimeGlobals.loadScript,
  77. RuntimeGlobals.systemContext,
  78. RuntimeGlobals.onChunksLoaded,
  79. RuntimeGlobals.makeDeferredNamespaceObject
  80. ];
  81. const MODULE_DEPENDENCIES = {
  82. [RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
  83. [RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
  84. };
  85. const TREE_DEPENDENCIES = {
  86. [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
  87. [RuntimeGlobals.compatGetDefaultExport]: [
  88. RuntimeGlobals.definePropertyGetters
  89. ],
  90. [RuntimeGlobals.createFakeNamespaceObject]: [
  91. RuntimeGlobals.definePropertyGetters,
  92. RuntimeGlobals.makeNamespaceObject,
  93. RuntimeGlobals.require
  94. ],
  95. [RuntimeGlobals.makeDeferredNamespaceObject]: [
  96. RuntimeGlobals.definePropertyGetters,
  97. RuntimeGlobals.makeNamespaceObject,
  98. RuntimeGlobals.createFakeNamespaceObject,
  99. RuntimeGlobals.hasOwnProperty,
  100. RuntimeGlobals.require
  101. ],
  102. [RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
  103. [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
  104. };
  105. const PLUGIN_NAME = "RuntimePlugin";
  106. class RuntimePlugin {
  107. /**
  108. * @param {Compiler} compiler the Compiler
  109. * @returns {void}
  110. */
  111. apply(compiler) {
  112. compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
  113. const globalChunkLoading = compilation.outputOptions.chunkLoading;
  114. /**
  115. * @param {Chunk} chunk chunk
  116. * @returns {boolean} true, when chunk loading is disabled for the chunk
  117. */
  118. const isChunkLoadingDisabledForChunk = chunk => {
  119. const options = chunk.getEntryOptions();
  120. const chunkLoading =
  121. options && options.chunkLoading !== undefined
  122. ? options.chunkLoading
  123. : globalChunkLoading;
  124. return chunkLoading === false;
  125. };
  126. compilation.dependencyTemplates.set(
  127. RuntimeRequirementsDependency,
  128. new RuntimeRequirementsDependency.Template()
  129. );
  130. for (const req of GLOBALS_ON_REQUIRE) {
  131. compilation.hooks.runtimeRequirementInModule
  132. .for(req)
  133. .tap(PLUGIN_NAME, (module, set) => {
  134. set.add(RuntimeGlobals.requireScope);
  135. });
  136. compilation.hooks.runtimeRequirementInTree
  137. .for(req)
  138. .tap(PLUGIN_NAME, (module, set) => {
  139. set.add(RuntimeGlobals.requireScope);
  140. });
  141. }
  142. for (const req of Object.keys(TREE_DEPENDENCIES)) {
  143. const deps =
  144. TREE_DEPENDENCIES[/** @type {keyof TREE_DEPENDENCIES} */ (req)];
  145. compilation.hooks.runtimeRequirementInTree
  146. .for(req)
  147. .tap(PLUGIN_NAME, (chunk, set) => {
  148. for (const dep of deps) set.add(dep);
  149. });
  150. }
  151. for (const req of Object.keys(MODULE_DEPENDENCIES)) {
  152. const deps =
  153. MODULE_DEPENDENCIES[/** @type {keyof MODULE_DEPENDENCIES} */ (req)];
  154. compilation.hooks.runtimeRequirementInModule
  155. .for(req)
  156. .tap(PLUGIN_NAME, (chunk, set) => {
  157. for (const dep of deps) set.add(dep);
  158. });
  159. }
  160. compilation.hooks.runtimeRequirementInTree
  161. .for(RuntimeGlobals.definePropertyGetters)
  162. .tap(PLUGIN_NAME, chunk => {
  163. compilation.addRuntimeModule(
  164. chunk,
  165. new DefinePropertyGettersRuntimeModule()
  166. );
  167. return true;
  168. });
  169. compilation.hooks.runtimeRequirementInTree
  170. .for(RuntimeGlobals.makeNamespaceObject)
  171. .tap(PLUGIN_NAME, chunk => {
  172. compilation.addRuntimeModule(
  173. chunk,
  174. new MakeNamespaceObjectRuntimeModule()
  175. );
  176. return true;
  177. });
  178. compilation.hooks.runtimeRequirementInTree
  179. .for(RuntimeGlobals.createFakeNamespaceObject)
  180. .tap(PLUGIN_NAME, chunk => {
  181. compilation.addRuntimeModule(
  182. chunk,
  183. new CreateFakeNamespaceObjectRuntimeModule()
  184. );
  185. return true;
  186. });
  187. compilation.hooks.runtimeRequirementInTree
  188. .for(RuntimeGlobals.makeDeferredNamespaceObject)
  189. .tap("RuntimePlugin", (chunk, runtimeRequirement) => {
  190. compilation.addRuntimeModule(
  191. chunk,
  192. new MakeDeferredNamespaceObjectRuntime(
  193. runtimeRequirement.has(RuntimeGlobals.asyncModule)
  194. )
  195. );
  196. return true;
  197. });
  198. compilation.hooks.runtimeRequirementInTree
  199. .for(RuntimeGlobals.hasOwnProperty)
  200. .tap(PLUGIN_NAME, chunk => {
  201. compilation.addRuntimeModule(
  202. chunk,
  203. new HasOwnPropertyRuntimeModule()
  204. );
  205. return true;
  206. });
  207. compilation.hooks.runtimeRequirementInTree
  208. .for(RuntimeGlobals.compatGetDefaultExport)
  209. .tap(PLUGIN_NAME, chunk => {
  210. compilation.addRuntimeModule(
  211. chunk,
  212. new CompatGetDefaultExportRuntimeModule()
  213. );
  214. return true;
  215. });
  216. compilation.hooks.runtimeRequirementInTree
  217. .for(RuntimeGlobals.runtimeId)
  218. .tap(PLUGIN_NAME, chunk => {
  219. compilation.addRuntimeModule(chunk, new RuntimeIdRuntimeModule());
  220. return true;
  221. });
  222. compilation.hooks.runtimeRequirementInTree
  223. .for(RuntimeGlobals.publicPath)
  224. .tap(PLUGIN_NAME, (chunk, set) => {
  225. const { outputOptions } = compilation;
  226. const { publicPath: globalPublicPath, scriptType } = outputOptions;
  227. const entryOptions = chunk.getEntryOptions();
  228. const publicPath =
  229. entryOptions && entryOptions.publicPath !== undefined
  230. ? entryOptions.publicPath
  231. : globalPublicPath;
  232. if (publicPath === "auto") {
  233. const module = new AutoPublicPathRuntimeModule();
  234. if (scriptType !== "module") set.add(RuntimeGlobals.global);
  235. compilation.addRuntimeModule(chunk, module);
  236. } else {
  237. const module = new PublicPathRuntimeModule(publicPath);
  238. if (
  239. typeof publicPath !== "string" ||
  240. /\[(full)?hash\]/.test(publicPath)
  241. ) {
  242. module.fullHash = true;
  243. }
  244. compilation.addRuntimeModule(chunk, module);
  245. }
  246. return true;
  247. });
  248. compilation.hooks.runtimeRequirementInTree
  249. .for(RuntimeGlobals.global)
  250. .tap(PLUGIN_NAME, chunk => {
  251. compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
  252. return true;
  253. });
  254. compilation.hooks.runtimeRequirementInTree
  255. .for(RuntimeGlobals.asyncModule)
  256. .tap(PLUGIN_NAME, chunk => {
  257. const experiments = compilation.options.experiments;
  258. compilation.addRuntimeModule(
  259. chunk,
  260. new AsyncModuleRuntimeModule(experiments.deferImport)
  261. );
  262. return true;
  263. });
  264. compilation.hooks.runtimeRequirementInTree
  265. .for(RuntimeGlobals.systemContext)
  266. .tap(PLUGIN_NAME, chunk => {
  267. const entryOptions = chunk.getEntryOptions();
  268. const libraryType =
  269. entryOptions && entryOptions.library !== undefined
  270. ? entryOptions.library.type
  271. : /** @type {LibraryOptions} */
  272. (compilation.outputOptions.library).type;
  273. if (libraryType === "system") {
  274. compilation.addRuntimeModule(
  275. chunk,
  276. new SystemContextRuntimeModule()
  277. );
  278. }
  279. return true;
  280. });
  281. compilation.hooks.runtimeRequirementInTree
  282. .for(RuntimeGlobals.getChunkScriptFilename)
  283. .tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
  284. if (
  285. typeof compilation.outputOptions.chunkFilename === "string" &&
  286. /\[(full)?hash(:\d+)?\]/.test(
  287. compilation.outputOptions.chunkFilename
  288. )
  289. ) {
  290. set.add(RuntimeGlobals.getFullHash);
  291. }
  292. compilation.addRuntimeModule(
  293. chunk,
  294. new GetChunkFilenameRuntimeModule(
  295. "javascript",
  296. "javascript",
  297. RuntimeGlobals.getChunkScriptFilename,
  298. chunk =>
  299. getJavascriptModulesPlugin().chunkHasJs(chunk, chunkGraph) &&
  300. /** @type {TemplatePath} */ (
  301. chunk.filenameTemplate ||
  302. (chunk.canBeInitial()
  303. ? compilation.outputOptions.filename
  304. : compilation.outputOptions.chunkFilename)
  305. ),
  306. set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
  307. )
  308. );
  309. return true;
  310. });
  311. compilation.hooks.runtimeRequirementInTree
  312. .for(RuntimeGlobals.getChunkCssFilename)
  313. .tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
  314. if (
  315. typeof compilation.outputOptions.cssChunkFilename === "string" &&
  316. /\[(full)?hash(:\d+)?\]/.test(
  317. compilation.outputOptions.cssChunkFilename
  318. )
  319. ) {
  320. set.add(RuntimeGlobals.getFullHash);
  321. }
  322. compilation.addRuntimeModule(
  323. chunk,
  324. new GetChunkFilenameRuntimeModule(
  325. "css",
  326. "css",
  327. RuntimeGlobals.getChunkCssFilename,
  328. chunk =>
  329. getCssModulesPlugin().chunkHasCss(chunk, chunkGraph) &&
  330. getChunkFilenameTemplate(chunk, compilation.outputOptions),
  331. set.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
  332. )
  333. );
  334. return true;
  335. });
  336. compilation.hooks.runtimeRequirementInTree
  337. .for(RuntimeGlobals.getChunkUpdateScriptFilename)
  338. .tap(PLUGIN_NAME, (chunk, set) => {
  339. if (
  340. /\[(full)?hash(:\d+)?\]/.test(
  341. /** @type {NonNullable<OutputNormalized["hotUpdateChunkFilename"]>} */
  342. (compilation.outputOptions.hotUpdateChunkFilename)
  343. )
  344. ) {
  345. set.add(RuntimeGlobals.getFullHash);
  346. }
  347. compilation.addRuntimeModule(
  348. chunk,
  349. new GetChunkFilenameRuntimeModule(
  350. "javascript",
  351. "javascript update",
  352. RuntimeGlobals.getChunkUpdateScriptFilename,
  353. _chunk =>
  354. /** @type {NonNullable<OutputNormalized["hotUpdateChunkFilename"]>} */
  355. (compilation.outputOptions.hotUpdateChunkFilename),
  356. true
  357. )
  358. );
  359. return true;
  360. });
  361. compilation.hooks.runtimeRequirementInTree
  362. .for(RuntimeGlobals.getUpdateManifestFilename)
  363. .tap(PLUGIN_NAME, (chunk, set) => {
  364. if (
  365. /\[(full)?hash(:\d+)?\]/.test(
  366. /** @type {NonNullable<OutputNormalized["hotUpdateMainFilename"]>} */
  367. (compilation.outputOptions.hotUpdateMainFilename)
  368. )
  369. ) {
  370. set.add(RuntimeGlobals.getFullHash);
  371. }
  372. compilation.addRuntimeModule(
  373. chunk,
  374. new GetMainFilenameRuntimeModule(
  375. "update manifest",
  376. RuntimeGlobals.getUpdateManifestFilename,
  377. /** @type {NonNullable<OutputNormalized["hotUpdateMainFilename"]>} */
  378. (compilation.outputOptions.hotUpdateMainFilename)
  379. )
  380. );
  381. return true;
  382. });
  383. compilation.hooks.runtimeRequirementInTree
  384. .for(RuntimeGlobals.ensureChunk)
  385. .tap(PLUGIN_NAME, (chunk, set) => {
  386. const hasAsyncChunks = chunk.hasAsyncChunks();
  387. if (hasAsyncChunks) {
  388. set.add(RuntimeGlobals.ensureChunkHandlers);
  389. }
  390. compilation.addRuntimeModule(
  391. chunk,
  392. new EnsureChunkRuntimeModule(set)
  393. );
  394. return true;
  395. });
  396. compilation.hooks.runtimeRequirementInTree
  397. .for(RuntimeGlobals.ensureChunkIncludeEntries)
  398. .tap(PLUGIN_NAME, (chunk, set) => {
  399. set.add(RuntimeGlobals.ensureChunkHandlers);
  400. });
  401. compilation.hooks.runtimeRequirementInTree
  402. .for(RuntimeGlobals.shareScopeMap)
  403. .tap(PLUGIN_NAME, (chunk, set) => {
  404. compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
  405. return true;
  406. });
  407. compilation.hooks.runtimeRequirementInTree
  408. .for(RuntimeGlobals.loadScript)
  409. .tap(PLUGIN_NAME, (chunk, set) => {
  410. const withCreateScriptUrl = Boolean(
  411. compilation.outputOptions.trustedTypes
  412. );
  413. if (withCreateScriptUrl) {
  414. set.add(RuntimeGlobals.createScriptUrl);
  415. }
  416. const withFetchPriority = set.has(RuntimeGlobals.hasFetchPriority);
  417. compilation.addRuntimeModule(
  418. chunk,
  419. new LoadScriptRuntimeModule(withCreateScriptUrl, withFetchPriority)
  420. );
  421. return true;
  422. });
  423. compilation.hooks.runtimeRequirementInTree
  424. .for(RuntimeGlobals.createScript)
  425. .tap(PLUGIN_NAME, (chunk, set) => {
  426. if (compilation.outputOptions.trustedTypes) {
  427. set.add(RuntimeGlobals.getTrustedTypesPolicy);
  428. }
  429. compilation.addRuntimeModule(chunk, new CreateScriptRuntimeModule());
  430. return true;
  431. });
  432. compilation.hooks.runtimeRequirementInTree
  433. .for(RuntimeGlobals.createScriptUrl)
  434. .tap(PLUGIN_NAME, (chunk, set) => {
  435. if (compilation.outputOptions.trustedTypes) {
  436. set.add(RuntimeGlobals.getTrustedTypesPolicy);
  437. }
  438. compilation.addRuntimeModule(
  439. chunk,
  440. new CreateScriptUrlRuntimeModule()
  441. );
  442. return true;
  443. });
  444. compilation.hooks.runtimeRequirementInTree
  445. .for(RuntimeGlobals.getTrustedTypesPolicy)
  446. .tap(PLUGIN_NAME, (chunk, set) => {
  447. compilation.addRuntimeModule(
  448. chunk,
  449. new GetTrustedTypesPolicyRuntimeModule(set)
  450. );
  451. return true;
  452. });
  453. compilation.hooks.runtimeRequirementInTree
  454. .for(RuntimeGlobals.relativeUrl)
  455. .tap(PLUGIN_NAME, (chunk, _set) => {
  456. compilation.addRuntimeModule(chunk, new RelativeUrlRuntimeModule());
  457. return true;
  458. });
  459. compilation.hooks.runtimeRequirementInTree
  460. .for(RuntimeGlobals.onChunksLoaded)
  461. .tap(PLUGIN_NAME, (chunk, _set) => {
  462. compilation.addRuntimeModule(
  463. chunk,
  464. new OnChunksLoadedRuntimeModule()
  465. );
  466. return true;
  467. });
  468. compilation.hooks.runtimeRequirementInTree
  469. .for(RuntimeGlobals.baseURI)
  470. .tap(PLUGIN_NAME, chunk => {
  471. if (isChunkLoadingDisabledForChunk(chunk)) {
  472. compilation.addRuntimeModule(chunk, new BaseUriRuntimeModule());
  473. return true;
  474. }
  475. });
  476. compilation.hooks.runtimeRequirementInTree
  477. .for(RuntimeGlobals.scriptNonce)
  478. .tap(PLUGIN_NAME, chunk => {
  479. compilation.addRuntimeModule(chunk, new NonceRuntimeModule());
  480. return true;
  481. });
  482. // TODO webpack 6: remove CompatRuntimeModule
  483. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  484. PLUGIN_NAME,
  485. (chunk, _set) => {
  486. const { mainTemplate } = compilation;
  487. if (
  488. mainTemplate.hooks.bootstrap.isUsed() ||
  489. mainTemplate.hooks.localVars.isUsed() ||
  490. mainTemplate.hooks.requireEnsure.isUsed() ||
  491. mainTemplate.hooks.requireExtensions.isUsed()
  492. ) {
  493. compilation.addRuntimeModule(chunk, new CompatRuntimeModule());
  494. }
  495. }
  496. );
  497. JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
  498. PLUGIN_NAME,
  499. (chunk, hash, { chunkGraph }) => {
  500. const xor = new StringXor();
  501. for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
  502. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  503. }
  504. xor.updateHash(hash);
  505. }
  506. );
  507. });
  508. }
  509. }
  510. module.exports = RuntimePlugin;