Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

490 строки
17 KiB

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