RuntimePlugin.js 18 KB

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