RuntimePlugin.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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 {
  8. getPresentKinds,
  9. usesFullHashDigest
  10. } = require("./TemplatedPathPlugin");
  11. const CssModulesPlugin = require("./css/CssModulesPlugin");
  12. const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
  13. const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
  14. const StringXor = require("./util/StringXor");
  15. const lazyModule = require("./util/lazyModule");
  16. /** @import { LibraryOptions } from "../declarations/WebpackOptions" */
  17. /** @import Chunk from "./Chunk" */
  18. /** @import { RuntimeRequirements } from "./Module" */
  19. /** @import Compiler from "./Compiler" */
  20. /** @import RuntimeModule from "./RuntimeModule" */
  21. // Each runtime module below is loaded by `_attachPendingRuntimeModules`, so only
  22. // the builds that emit one pay for it — most reach ~10 of these 30.
  23. const getCssServerStylesRuntimeModule = lazyModule(() =>
  24. require("./css/CssServerStylesRuntimeModule")
  25. );
  26. const getAsyncModuleGeneratorRuntimeModule = lazyModule(() =>
  27. require("./runtime/AsyncModuleGeneratorRuntimeModule")
  28. );
  29. const getAsyncModuleRuntimeModule = lazyModule(() =>
  30. require("./runtime/AsyncModuleRuntimeModule")
  31. );
  32. const getAutoPublicPathRuntimeModule = lazyModule(() =>
  33. require("./runtime/AutoPublicPathRuntimeModule")
  34. );
  35. const getBaseUriRuntimeModule = lazyModule(() =>
  36. require("./runtime/BaseUriRuntimeModule")
  37. );
  38. const getCompatGetDefaultExportRuntimeModule = lazyModule(() =>
  39. require("./runtime/CompatGetDefaultExportRuntimeModule")
  40. );
  41. const getCompatRuntimeModule = lazyModule(() =>
  42. require("./runtime/CompatRuntimeModule")
  43. );
  44. const getConcatenationWrapRuntimeModule = lazyModule(() =>
  45. require("./runtime/ConcatenationWrapRuntimeModule")
  46. );
  47. const getConstructRequireRuntimeModule = lazyModule(() =>
  48. require("./runtime/ConstructRequireRuntimeModule")
  49. );
  50. const getCreateFakeNamespaceObjectRuntimeModule = lazyModule(() =>
  51. require("./runtime/CreateFakeNamespaceObjectRuntimeModule")
  52. );
  53. const getCreateScriptRuntimeModule = lazyModule(() =>
  54. require("./runtime/CreateScriptRuntimeModule")
  55. );
  56. const getCreateScriptUrlRuntimeModule = lazyModule(() =>
  57. require("./runtime/CreateScriptUrlRuntimeModule")
  58. );
  59. const getDefinePropertyGettersRuntimeModule = lazyModule(() =>
  60. require("./runtime/DefinePropertyGettersRuntimeModule")
  61. );
  62. const getEnsureChunkRuntimeModule = lazyModule(() =>
  63. require("./runtime/EnsureChunkRuntimeModule")
  64. );
  65. const getGetChunkFilenameRuntimeModule = lazyModule(() =>
  66. require("./runtime/GetChunkFilenameRuntimeModule")
  67. );
  68. const getGetMainFilenameRuntimeModule = lazyModule(() =>
  69. require("./runtime/GetMainFilenameRuntimeModule")
  70. );
  71. const getGetTrustedTypesPolicyRuntimeModule = lazyModule(() =>
  72. require("./runtime/GetTrustedTypesPolicyRuntimeModule")
  73. );
  74. const getGetWorkletBootstrapRuntimeModule = lazyModule(() =>
  75. require("./runtime/GetWorkletBootstrapRuntimeModule")
  76. );
  77. const getGlobalRuntimeModule = lazyModule(() =>
  78. require("./runtime/GlobalRuntimeModule")
  79. );
  80. const getHasOwnPropertyRuntimeModule = lazyModule(() =>
  81. require("./runtime/HasOwnPropertyRuntimeModule")
  82. );
  83. const getLoadScriptRuntimeModule = lazyModule(() =>
  84. require("./runtime/LoadScriptRuntimeModule")
  85. );
  86. const getMakeDeferredNamespaceObjectRuntimeModule = lazyModule(
  87. () =>
  88. require("./runtime/MakeDeferredNamespaceObjectRuntime")
  89. .MakeDeferredNamespaceObjectRuntimeModule
  90. );
  91. const getMakeOptimizedDeferredNamespaceObjectRuntimeModule = lazyModule(
  92. () =>
  93. require("./runtime/MakeDeferredNamespaceObjectRuntime")
  94. .MakeOptimizedDeferredNamespaceObjectRuntimeModule
  95. );
  96. const getMakeNamespaceObjectRuntimeModule = lazyModule(() =>
  97. require("./runtime/MakeNamespaceObjectRuntimeModule")
  98. );
  99. const getNonceRuntimeModule = lazyModule(() =>
  100. require("./runtime/NonceRuntimeModule")
  101. );
  102. const getOnChunksLoadedRuntimeModule = lazyModule(() =>
  103. require("./runtime/OnChunksLoadedRuntimeModule")
  104. );
  105. const getPublicPathRuntimeModule = lazyModule(() =>
  106. require("./runtime/PublicPathRuntimeModule")
  107. );
  108. const getRelativeUrlRuntimeModule = lazyModule(() =>
  109. require("./runtime/RelativeUrlRuntimeModule")
  110. );
  111. const getRuntimeIdRuntimeModule = lazyModule(() =>
  112. require("./runtime/RuntimeIdRuntimeModule")
  113. );
  114. const getSetAnonymousDefaultNameRuntimeModule = lazyModule(() =>
  115. require("./runtime/SetAnonymousDefaultNameRuntimeModule")
  116. );
  117. const getSystemContextRuntimeModule = lazyModule(() =>
  118. require("./runtime/SystemContextRuntimeModule")
  119. );
  120. const getToBinaryRuntimeModule = lazyModule(() =>
  121. require("./runtime/ToBinaryRuntimeModule")
  122. );
  123. const getWorkerRuntimeModule = lazyModule(() =>
  124. require("./runtime/WorkerRuntimeModule")
  125. );
  126. const getShareRuntimeModule = lazyModule(() =>
  127. require("./sharing/ShareRuntimeModule")
  128. );
  129. const GLOBALS_ON_REQUIRE = [
  130. RuntimeGlobals.chunkName,
  131. RuntimeGlobals.runtimeId,
  132. RuntimeGlobals.compatGetDefaultExport,
  133. RuntimeGlobals.createFakeNamespaceObject,
  134. RuntimeGlobals.createScript,
  135. RuntimeGlobals.createScriptUrl,
  136. RuntimeGlobals.getTrustedTypesPolicy,
  137. RuntimeGlobals.definePropertyGetters,
  138. RuntimeGlobals.ensureChunk,
  139. RuntimeGlobals.entryModuleId,
  140. RuntimeGlobals.getCssServerStyles,
  141. RuntimeGlobals.getFullHash,
  142. RuntimeGlobals.global,
  143. RuntimeGlobals.makeNamespaceObject,
  144. RuntimeGlobals.moduleCache,
  145. RuntimeGlobals.moduleFactories,
  146. RuntimeGlobals.moduleFactoriesAddOnly,
  147. RuntimeGlobals.interceptModuleExecution,
  148. RuntimeGlobals.publicPath,
  149. RuntimeGlobals.baseURI,
  150. RuntimeGlobals.prefetchAsset,
  151. RuntimeGlobals.preloadAsset,
  152. RuntimeGlobals.relativeUrl,
  153. // TODO webpack 6 - rename to nonce, because we use it for CSS too
  154. RuntimeGlobals.scriptNonce,
  155. RuntimeGlobals.uncaughtErrorHandler,
  156. RuntimeGlobals.asyncModule,
  157. RuntimeGlobals.asyncModuleGenerator,
  158. RuntimeGlobals.wasmInstances,
  159. RuntimeGlobals.instantiateWasm,
  160. RuntimeGlobals.shareScopeMap,
  161. RuntimeGlobals.initializeSharing,
  162. RuntimeGlobals.loadScript,
  163. RuntimeGlobals.setAnonymousDefaultName,
  164. RuntimeGlobals.systemContext,
  165. RuntimeGlobals.onChunksLoaded,
  166. RuntimeGlobals.makeOptimizedDeferredNamespaceObject,
  167. RuntimeGlobals.makeDeferredNamespaceObject,
  168. RuntimeGlobals.concatenationWrap,
  169. RuntimeGlobals.constructRequire
  170. ];
  171. const MODULE_DEPENDENCIES = {
  172. [RuntimeGlobals.moduleLoaded]: [RuntimeGlobals.module],
  173. [RuntimeGlobals.moduleId]: [RuntimeGlobals.module]
  174. };
  175. const TREE_DEPENDENCIES = {
  176. [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty],
  177. [RuntimeGlobals.compatGetDefaultExport]: [
  178. RuntimeGlobals.definePropertyGetters
  179. ],
  180. [RuntimeGlobals.createFakeNamespaceObject]: [
  181. RuntimeGlobals.definePropertyGetters,
  182. RuntimeGlobals.makeNamespaceObject,
  183. RuntimeGlobals.require
  184. ],
  185. [RuntimeGlobals.makeOptimizedDeferredNamespaceObject]: [
  186. RuntimeGlobals.require
  187. ],
  188. [RuntimeGlobals.makeDeferredNamespaceObject]: [
  189. RuntimeGlobals.createFakeNamespaceObject,
  190. RuntimeGlobals.require
  191. ],
  192. [RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
  193. [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty],
  194. [RuntimeGlobals.constructRequire]: [RuntimeGlobals.require]
  195. };
  196. // Tree runtime requirements whose only effect is attaching a zero-arg runtime
  197. // module to the chunk. Conditional / argument-taking ones stay as explicit taps.
  198. /** @type {[string, () => Promise<new () => RuntimeModule>][]} */
  199. const SIMPLE_TREE_RUNTIME_MODULES = [
  200. [RuntimeGlobals.makeNamespaceObject, getMakeNamespaceObjectRuntimeModule],
  201. [
  202. RuntimeGlobals.createFakeNamespaceObject,
  203. getCreateFakeNamespaceObjectRuntimeModule
  204. ],
  205. [RuntimeGlobals.hasOwnProperty, getHasOwnPropertyRuntimeModule],
  206. [
  207. RuntimeGlobals.compatGetDefaultExport,
  208. getCompatGetDefaultExportRuntimeModule
  209. ],
  210. [RuntimeGlobals.concatenationWrap, getConcatenationWrapRuntimeModule],
  211. [RuntimeGlobals.constructRequire, getConstructRequireRuntimeModule],
  212. [
  213. RuntimeGlobals.setAnonymousDefaultName,
  214. getSetAnonymousDefaultNameRuntimeModule
  215. ],
  216. [RuntimeGlobals.runtimeId, getRuntimeIdRuntimeModule],
  217. [RuntimeGlobals.global, getGlobalRuntimeModule],
  218. [RuntimeGlobals.shareScopeMap, getShareRuntimeModule],
  219. [RuntimeGlobals.relativeUrl, getRelativeUrlRuntimeModule],
  220. [RuntimeGlobals.worker, getWorkerRuntimeModule],
  221. [RuntimeGlobals.onChunksLoaded, getOnChunksLoadedRuntimeModule],
  222. [RuntimeGlobals.scriptNonce, getNonceRuntimeModule],
  223. [RuntimeGlobals.toBinary, getToBinaryRuntimeModule]
  224. ];
  225. /**
  226. * @param {string} template path template
  227. * @returns {boolean} true when it references the compilation `[fullhash]`/`[hash]`
  228. */
  229. const usesFullHash = (template) => {
  230. const kinds = getPresentKinds(template);
  231. return kinds.has("fullhash") || kinds.has("hash");
  232. };
  233. const PLUGIN_NAME = "RuntimePlugin";
  234. class RuntimePlugin {
  235. /**
  236. * Applies the plugin by registering its hooks on the compiler.
  237. * @param {Compiler} compiler the Compiler
  238. * @returns {void}
  239. */
  240. apply(compiler) {
  241. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  242. const globalChunkLoading = compilation.outputOptions.chunkLoading;
  243. /**
  244. * Checks whether this runtime plugin is chunk loading disabled for chunk.
  245. * @param {Chunk} chunk chunk
  246. * @returns {boolean} true, when chunk loading is disabled for the chunk
  247. */
  248. const isChunkLoadingDisabledForChunk = (chunk) => {
  249. const options = chunk.getEntryOptions();
  250. const chunkLoading =
  251. options && options.chunkLoading !== undefined
  252. ? options.chunkLoading
  253. : globalChunkLoading;
  254. return chunkLoading === false;
  255. };
  256. compilation.dependencyTemplates.set(
  257. RuntimeRequirementsDependency,
  258. new RuntimeRequirementsDependency.Template()
  259. );
  260. for (const req of GLOBALS_ON_REQUIRE) {
  261. compilation.hooks.runtimeRequirementInModule
  262. .for(req)
  263. .tap(PLUGIN_NAME, (module, set) => {
  264. set.add(RuntimeGlobals.requireScope);
  265. });
  266. compilation.hooks.runtimeRequirementInTree
  267. .for(req)
  268. .tap(PLUGIN_NAME, (module, set) => {
  269. set.add(RuntimeGlobals.requireScope);
  270. });
  271. }
  272. for (const req of Object.keys(TREE_DEPENDENCIES)) {
  273. const deps =
  274. TREE_DEPENDENCIES[/** @type {keyof TREE_DEPENDENCIES} */ (req)];
  275. compilation.hooks.runtimeRequirementInTree
  276. .for(req)
  277. .tap(PLUGIN_NAME, (chunk, set) => {
  278. for (const dep of deps) set.add(dep);
  279. });
  280. }
  281. for (const req of Object.keys(MODULE_DEPENDENCIES)) {
  282. const deps =
  283. MODULE_DEPENDENCIES[/** @type {keyof MODULE_DEPENDENCIES} */ (req)];
  284. compilation.hooks.runtimeRequirementInModule
  285. .for(req)
  286. .tap(PLUGIN_NAME, (chunk, set) => {
  287. for (const dep of deps) set.add(dep);
  288. });
  289. }
  290. for (const [
  291. runtimeGlobal,
  292. getRuntimeModule
  293. ] of SIMPLE_TREE_RUNTIME_MODULES) {
  294. compilation.hooks.runtimeRequirementInTree
  295. .for(runtimeGlobal)
  296. .tap(PLUGIN_NAME, (chunk) => {
  297. compilation.addLazyRuntimeModule(
  298. chunk,
  299. getRuntimeModule,
  300. (Ctor) => new Ctor()
  301. );
  302. return true;
  303. });
  304. }
  305. compilation.hooks.runtimeRequirementInTree
  306. .for(RuntimeGlobals.definePropertyGetters)
  307. .tap(PLUGIN_NAME, (chunk, runtimeRequirement) => {
  308. compilation.addLazyRuntimeModule(
  309. chunk,
  310. getDefinePropertyGettersRuntimeModule,
  311. (Ctor) => new Ctor(runtimeRequirement)
  312. );
  313. return true;
  314. });
  315. compilation.hooks.runtimeRequirementInTree
  316. .for(RuntimeGlobals.makeOptimizedDeferredNamespaceObject)
  317. .tap(PLUGIN_NAME, (chunk, runtimeRequirement) => {
  318. const asyncModule = runtimeRequirement.has(
  319. RuntimeGlobals.asyncModule
  320. );
  321. compilation.addLazyRuntimeModule(
  322. chunk,
  323. getMakeOptimizedDeferredNamespaceObjectRuntimeModule,
  324. (Ctor) => new Ctor(asyncModule)
  325. );
  326. return true;
  327. });
  328. compilation.hooks.runtimeRequirementInTree
  329. .for(RuntimeGlobals.makeDeferredNamespaceObject)
  330. .tap(PLUGIN_NAME, (chunk, runtimeRequirement) => {
  331. const asyncModule = runtimeRequirement.has(
  332. RuntimeGlobals.asyncModule
  333. );
  334. compilation.addLazyRuntimeModule(
  335. chunk,
  336. getMakeDeferredNamespaceObjectRuntimeModule,
  337. (Ctor) => new Ctor(asyncModule)
  338. );
  339. return true;
  340. });
  341. compilation.hooks.runtimeRequirementInTree
  342. .for(RuntimeGlobals.publicPath)
  343. .tap(PLUGIN_NAME, (chunk, set) => {
  344. const { outputOptions } = compilation;
  345. const { publicPath: globalPublicPath, scriptType } = outputOptions;
  346. const entryOptions = chunk.getEntryOptions();
  347. const publicPath =
  348. entryOptions && entryOptions.publicPath !== undefined
  349. ? entryOptions.publicPath
  350. : globalPublicPath;
  351. if (publicPath === "auto") {
  352. // A worklet chunk reads `import.meta.url`, so it needs neither the
  353. // worker-scope detection nor the `globalThis` polyfill.
  354. if (
  355. scriptType !== "module" &&
  356. !(entryOptions && entryOptions.worklet) &&
  357. !outputOptions.environment.globalThis
  358. ) {
  359. set.add(RuntimeGlobals.global);
  360. }
  361. compilation.addLazyRuntimeModule(
  362. chunk,
  363. getAutoPublicPathRuntimeModule,
  364. (Ctor) => new Ctor()
  365. );
  366. } else {
  367. const fullHash =
  368. typeof publicPath !== "string" || usesFullHash(publicPath);
  369. compilation.addLazyRuntimeModule(
  370. chunk,
  371. getPublicPathRuntimeModule,
  372. (Ctor) => {
  373. const module = new Ctor(publicPath);
  374. if (fullHash) module.fullHash = true;
  375. return module;
  376. }
  377. );
  378. }
  379. return true;
  380. });
  381. compilation.hooks.runtimeRequirementInTree
  382. .for(RuntimeGlobals.asyncModule)
  383. .tap(PLUGIN_NAME, (chunk) => {
  384. const experiments = compilation.options.experiments;
  385. compilation.addLazyRuntimeModule(
  386. chunk,
  387. getAsyncModuleRuntimeModule,
  388. (Ctor) => new Ctor(experiments.deferImport)
  389. );
  390. return true;
  391. });
  392. compilation.hooks.runtimeRequirementInTree
  393. .for(RuntimeGlobals.asyncModuleGenerator)
  394. .tap(PLUGIN_NAME, (chunk, set) => {
  395. set.add(RuntimeGlobals.asyncModule);
  396. compilation.addLazyRuntimeModule(
  397. chunk,
  398. getAsyncModuleGeneratorRuntimeModule,
  399. (Ctor) => new Ctor()
  400. );
  401. return true;
  402. });
  403. compilation.hooks.runtimeRequirementInTree
  404. .for(RuntimeGlobals.systemContext)
  405. .tap(PLUGIN_NAME, (chunk) => {
  406. const entryOptions = chunk.getEntryOptions();
  407. const libraryType =
  408. entryOptions && entryOptions.library !== undefined
  409. ? entryOptions.library.type
  410. : /** @type {LibraryOptions} */
  411. (compilation.outputOptions.library).type;
  412. if (libraryType === "system") {
  413. compilation.addLazyRuntimeModule(
  414. chunk,
  415. getSystemContextRuntimeModule,
  416. (Ctor) => new Ctor()
  417. );
  418. }
  419. return true;
  420. });
  421. compilation.hooks.runtimeRequirementInTree
  422. .for(RuntimeGlobals.getChunkScriptFilename)
  423. .tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
  424. if (
  425. typeof compilation.outputOptions.chunkFilename === "string" &&
  426. usesFullHash(compilation.outputOptions.chunkFilename)
  427. ) {
  428. set.add(RuntimeGlobals.getFullHash);
  429. }
  430. const hmr = set.has(RuntimeGlobals.hmrDownloadUpdateHandlers);
  431. const fullHashDigest =
  432. typeof compilation.outputOptions.chunkFilename === "string" &&
  433. usesFullHashDigest(compilation.outputOptions.chunkFilename);
  434. compilation.addLazyRuntimeModule(
  435. chunk,
  436. getGetChunkFilenameRuntimeModule,
  437. (Ctor) =>
  438. new Ctor(
  439. "javascript",
  440. "javascript",
  441. RuntimeGlobals.getChunkScriptFilename,
  442. (/** @type {Chunk} */ chunk) =>
  443. JavascriptModulesPlugin.chunkHasJs(chunk, chunkGraph) &&
  444. JavascriptModulesPlugin.getChunkFilenameTemplate(
  445. chunk,
  446. compilation.outputOptions
  447. ),
  448. hmr,
  449. fullHashDigest
  450. )
  451. );
  452. return true;
  453. });
  454. compilation.hooks.runtimeRequirementInTree
  455. .for(RuntimeGlobals.getWorkletBootstrap)
  456. .tap(PLUGIN_NAME, (chunk, set) => {
  457. set.add(RuntimeGlobals.baseURI);
  458. compilation.addLazyRuntimeModule(
  459. chunk,
  460. getGetWorkletBootstrapRuntimeModule,
  461. (Ctor) => new Ctor()
  462. );
  463. return true;
  464. });
  465. compilation.hooks.runtimeRequirementInTree
  466. .for(RuntimeGlobals.getChunkCssFilename)
  467. .tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
  468. if (
  469. typeof compilation.outputOptions.cssChunkFilename === "string" &&
  470. usesFullHash(compilation.outputOptions.cssChunkFilename)
  471. ) {
  472. set.add(RuntimeGlobals.getFullHash);
  473. }
  474. const hmr = set.has(RuntimeGlobals.hmrDownloadUpdateHandlers);
  475. const fullHashDigest =
  476. typeof compilation.outputOptions.cssChunkFilename === "string" &&
  477. usesFullHashDigest(compilation.outputOptions.cssChunkFilename);
  478. compilation.addLazyRuntimeModule(
  479. chunk,
  480. getGetChunkFilenameRuntimeModule,
  481. (Ctor) =>
  482. new Ctor(
  483. "css",
  484. "css",
  485. RuntimeGlobals.getChunkCssFilename,
  486. (/** @type {Chunk} */ chunk) => {
  487. const cssModulePlugin = CssModulesPlugin;
  488. return (
  489. cssModulePlugin.chunkHasCss(chunk, chunkGraph) &&
  490. cssModulePlugin.getChunkFilenameTemplate(
  491. chunk,
  492. compilation.outputOptions
  493. )
  494. );
  495. },
  496. hmr,
  497. fullHashDigest
  498. )
  499. );
  500. return true;
  501. });
  502. compilation.hooks.runtimeRequirementInTree
  503. .for(RuntimeGlobals.getChunkUpdateScriptFilename)
  504. .tap(PLUGIN_NAME, (chunk, set) => {
  505. if (usesFullHash(compilation.outputOptions.hotUpdateChunkFilename)) {
  506. set.add(RuntimeGlobals.getFullHash);
  507. }
  508. const fullHashDigest =
  509. typeof compilation.outputOptions.hotUpdateChunkFilename ===
  510. "string" &&
  511. usesFullHashDigest(
  512. compilation.outputOptions.hotUpdateChunkFilename
  513. );
  514. compilation.addLazyRuntimeModule(
  515. chunk,
  516. getGetChunkFilenameRuntimeModule,
  517. (Ctor) =>
  518. new Ctor(
  519. "javascript",
  520. "javascript update",
  521. RuntimeGlobals.getChunkUpdateScriptFilename,
  522. (/** @type {Chunk} */ _chunk) =>
  523. compilation.outputOptions.hotUpdateChunkFilename,
  524. true,
  525. fullHashDigest
  526. )
  527. );
  528. return true;
  529. });
  530. compilation.hooks.runtimeRequirementInTree
  531. .for(RuntimeGlobals.getCssServerStyles)
  532. .tap(PLUGIN_NAME, (chunk, set) => {
  533. // The registry lives on the global, reached via the polyfill when
  534. // the target has no `globalThis`.
  535. if (!compilation.outputOptions.environment.globalThis) {
  536. set.add(RuntimeGlobals.global);
  537. }
  538. compilation.addLazyRuntimeModule(
  539. chunk,
  540. getCssServerStylesRuntimeModule,
  541. (Ctor) => new Ctor()
  542. );
  543. return true;
  544. });
  545. compilation.hooks.runtimeRequirementInTree
  546. .for(RuntimeGlobals.getUpdateManifestFilename)
  547. .tap(PLUGIN_NAME, (chunk, set) => {
  548. if (usesFullHash(compilation.outputOptions.hotUpdateMainFilename)) {
  549. set.add(RuntimeGlobals.getFullHash);
  550. }
  551. compilation.addLazyRuntimeModule(
  552. chunk,
  553. getGetMainFilenameRuntimeModule,
  554. (Ctor) =>
  555. new Ctor(
  556. "update manifest",
  557. RuntimeGlobals.getUpdateManifestFilename,
  558. compilation.outputOptions.hotUpdateMainFilename
  559. )
  560. );
  561. return true;
  562. });
  563. /** @type {WeakSet<Chunk>} */
  564. const ensureChunkModuleAdded = new WeakSet();
  565. /**
  566. * The module carries the handler map as well as `ensureChunk`, and an
  567. * analyzable `import()` needs the map without the function around it.
  568. * @param {Chunk} chunk the chunk
  569. * @param {RuntimeRequirements} set the tree's requirements, filled in place
  570. */
  571. const addEnsureChunkRuntimeModule = (chunk, set) => {
  572. if (ensureChunkModuleAdded.has(chunk)) return;
  573. ensureChunkModuleAdded.add(chunk);
  574. compilation.addLazyRuntimeModule(
  575. chunk,
  576. getEnsureChunkRuntimeModule,
  577. (Ctor) => new Ctor(set)
  578. );
  579. };
  580. compilation.hooks.runtimeRequirementInTree
  581. .for(RuntimeGlobals.ensureChunk)
  582. .tap(PLUGIN_NAME, (chunk, set) => {
  583. const hasAsyncChunks = chunk.hasAsyncChunks();
  584. if (hasAsyncChunks) {
  585. set.add(RuntimeGlobals.ensureChunkHandlers);
  586. }
  587. addEnsureChunkRuntimeModule(chunk, set);
  588. return true;
  589. });
  590. compilation.hooks.runtimeRequirementInTree
  591. .for(RuntimeGlobals.ensureChunkHandlers)
  592. .tap(PLUGIN_NAME, (chunk, set) => {
  593. // No bail: every other plugin attaching a handler taps this same key.
  594. addEnsureChunkRuntimeModule(chunk, set);
  595. });
  596. compilation.hooks.runtimeRequirementInTree
  597. .for(RuntimeGlobals.ensureChunkIncludeEntries)
  598. .tap(PLUGIN_NAME, (chunk, set) => {
  599. set.add(RuntimeGlobals.ensureChunkHandlers);
  600. });
  601. compilation.hooks.runtimeRequirementInTree
  602. .for(RuntimeGlobals.loadScript)
  603. .tap(PLUGIN_NAME, (chunk, set) => {
  604. const withCreateScriptUrl = Boolean(
  605. compilation.outputOptions.trustedTypes
  606. );
  607. if (withCreateScriptUrl) {
  608. set.add(RuntimeGlobals.createScriptUrl);
  609. }
  610. const withFetchPriority = set.has(RuntimeGlobals.hasFetchPriority);
  611. compilation.addLazyRuntimeModule(
  612. chunk,
  613. getLoadScriptRuntimeModule,
  614. (Ctor) => new Ctor(withCreateScriptUrl, withFetchPriority)
  615. );
  616. return true;
  617. });
  618. compilation.hooks.runtimeRequirementInTree
  619. .for(RuntimeGlobals.createScript)
  620. .tap(PLUGIN_NAME, (chunk, set) => {
  621. if (compilation.outputOptions.trustedTypes) {
  622. set.add(RuntimeGlobals.getTrustedTypesPolicy);
  623. }
  624. compilation.addLazyRuntimeModule(
  625. chunk,
  626. getCreateScriptRuntimeModule,
  627. (Ctor) => new Ctor()
  628. );
  629. return true;
  630. });
  631. compilation.hooks.runtimeRequirementInTree
  632. .for(RuntimeGlobals.createScriptUrl)
  633. .tap(PLUGIN_NAME, (chunk, set) => {
  634. if (compilation.outputOptions.trustedTypes) {
  635. set.add(RuntimeGlobals.getTrustedTypesPolicy);
  636. }
  637. compilation.addLazyRuntimeModule(
  638. chunk,
  639. getCreateScriptUrlRuntimeModule,
  640. (Ctor) => new Ctor()
  641. );
  642. return true;
  643. });
  644. compilation.hooks.runtimeRequirementInTree
  645. .for(RuntimeGlobals.getTrustedTypesPolicy)
  646. .tap(PLUGIN_NAME, (chunk, set) => {
  647. compilation.addLazyRuntimeModule(
  648. chunk,
  649. getGetTrustedTypesPolicyRuntimeModule,
  650. (Ctor) => new Ctor(set)
  651. );
  652. return true;
  653. });
  654. compilation.hooks.runtimeRequirementInTree
  655. .for(RuntimeGlobals.baseURI)
  656. .tap(PLUGIN_NAME, (chunk) => {
  657. if (isChunkLoadingDisabledForChunk(chunk)) {
  658. compilation.addLazyRuntimeModule(
  659. chunk,
  660. getBaseUriRuntimeModule,
  661. (Ctor) => new Ctor()
  662. );
  663. return true;
  664. }
  665. });
  666. // TODO webpack 6: remove CompatRuntimeModule
  667. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  668. PLUGIN_NAME,
  669. (chunk, _set) => {
  670. const { mainTemplate } = compilation;
  671. if (
  672. mainTemplate.hooks.bootstrap.isUsed() ||
  673. mainTemplate.hooks.localVars.isUsed() ||
  674. mainTemplate.hooks.requireEnsure.isUsed() ||
  675. mainTemplate.hooks.requireExtensions.isUsed()
  676. ) {
  677. compilation.addLazyRuntimeModule(
  678. chunk,
  679. getCompatRuntimeModule,
  680. (Ctor) => new Ctor()
  681. );
  682. }
  683. }
  684. );
  685. JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(
  686. PLUGIN_NAME,
  687. (chunk, hash, { chunkGraph }) => {
  688. const xor = new StringXor();
  689. for (const m of chunkGraph.getChunkRuntimeModulesIterable(chunk)) {
  690. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  691. }
  692. xor.updateHash(hash);
  693. }
  694. );
  695. });
  696. }
  697. }
  698. module.exports = RuntimePlugin;