RuntimePlugin.js 18 KB

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