JavascriptModulesPlugin.js 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const vm = require("vm");
  7. const eslintScope = require("eslint-scope");
  8. const { SyncBailHook, SyncHook, SyncWaterfallHook } = require("tapable");
  9. const {
  10. CachedSource,
  11. ConcatSource,
  12. OriginalSource,
  13. PrefixSource,
  14. RawSource,
  15. ReplaceSource
  16. } = require("webpack-sources");
  17. const Compilation = require("../Compilation");
  18. const { tryRunOrWebpackError } = require("../HookWebpackError");
  19. const HotUpdateChunk = require("../HotUpdateChunk");
  20. const InitFragment = require("../InitFragment");
  21. const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
  22. const {
  23. JAVASCRIPT_MODULE_TYPE_AUTO,
  24. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  25. JAVASCRIPT_MODULE_TYPE_ESM,
  26. WEBPACK_MODULE_TYPE_RUNTIME
  27. } = require("../ModuleTypeConstants");
  28. const NormalModule = require("../NormalModule");
  29. const RuntimeGlobals = require("../RuntimeGlobals");
  30. const Template = require("../Template");
  31. const { last, someInIterable } = require("../util/IterableHelpers");
  32. const StringXor = require("../util/StringXor");
  33. const { compareModulesByIdOrIdentifier } = require("../util/comparators");
  34. const {
  35. RESERVED_NAMES,
  36. addScopeSymbols,
  37. findNewName,
  38. getAllReferences,
  39. getPathInAst,
  40. getUsedNamesInScopeInfo
  41. } = require("../util/concatenate");
  42. const createHash = require("../util/createHash");
  43. const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
  44. const removeBOM = require("../util/removeBOM");
  45. const { intersectRuntime } = require("../util/runtime");
  46. const JavascriptGenerator = require("./JavascriptGenerator");
  47. const JavascriptParser = require("./JavascriptParser");
  48. /** @typedef {import("eslint-scope").Reference} Reference */
  49. /** @typedef {import("eslint-scope").Scope} Scope */
  50. /** @typedef {import("eslint-scope").Variable} Variable */
  51. /** @typedef {import("estree").Program} Program */
  52. /** @typedef {import("webpack-sources").Source} Source */
  53. /** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
  54. /** @typedef {import("../Chunk")} Chunk */
  55. /** @typedef {import("../ChunkGraph")} ChunkGraph */
  56. /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
  57. /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
  58. /** @typedef {import("../Compilation").ExecuteModuleObject} ExecuteModuleObject */
  59. /** @typedef {import("../Compiler")} Compiler */
  60. /** @typedef {import("../DependencyTemplates")} DependencyTemplates */
  61. /** @typedef {import("../Entrypoint")} Entrypoint */
  62. /** @typedef {import("../Module")} Module */
  63. /** @typedef {import("../Module").BuildInfo} BuildInfo */
  64. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  65. /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
  66. /** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
  67. /** @typedef {import("../WebpackError")} WebpackError */
  68. /** @typedef {import("../javascript/JavascriptParser").Range} Range */
  69. /** @typedef {import("../util/Hash")} Hash */
  70. /**
  71. * @param {Chunk} chunk a chunk
  72. * @param {ChunkGraph} chunkGraph the chunk graph
  73. * @returns {boolean} true, when a JS file is needed for this chunk
  74. */
  75. const chunkHasJs = (chunk, chunkGraph) => {
  76. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) return true;
  77. return Boolean(
  78. chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
  79. );
  80. };
  81. /**
  82. * @param {Chunk} chunk a chunk
  83. * @param {ChunkGraph} chunkGraph the chunk graph
  84. * @returns {boolean} true, when a JS file is needed for this chunk
  85. */
  86. const chunkHasRuntimeOrJs = (chunk, chunkGraph) => {
  87. if (
  88. chunkGraph.getChunkModulesIterableBySourceType(
  89. chunk,
  90. WEBPACK_MODULE_TYPE_RUNTIME
  91. )
  92. ) {
  93. return true;
  94. }
  95. return Boolean(
  96. chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
  97. );
  98. };
  99. /**
  100. * @param {Module} module a module
  101. * @param {string} code the code
  102. * @returns {string} generated code for the stack
  103. */
  104. const printGeneratedCodeForStack = (module, code) => {
  105. const lines = code.split("\n");
  106. const n = `${lines.length}`.length;
  107. return `\n\nGenerated code for ${module.identifier()}\n${lines
  108. .map(
  109. /**
  110. * @param {string} line the line
  111. * @param {number} i the index
  112. * @param {string[]} _lines the lines
  113. * @returns {string} the line with line number
  114. */
  115. (line, i, _lines) => {
  116. const iStr = `${i + 1}`;
  117. return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`;
  118. }
  119. )
  120. .join("\n")}`;
  121. };
  122. /**
  123. * @typedef {object} RenderContext
  124. * @property {Chunk} chunk the chunk
  125. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  126. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  127. * @property {ModuleGraph} moduleGraph the module graph
  128. * @property {ChunkGraph} chunkGraph the chunk graph
  129. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  130. * @property {boolean | undefined} strictMode rendering in strict context
  131. */
  132. /**
  133. * @typedef {object} MainRenderContext
  134. * @property {Chunk} chunk the chunk
  135. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  136. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  137. * @property {ModuleGraph} moduleGraph the module graph
  138. * @property {ChunkGraph} chunkGraph the chunk graph
  139. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  140. * @property {string} hash hash to be used for render call
  141. * @property {boolean | undefined} strictMode rendering in strict context
  142. */
  143. /**
  144. * @typedef {object} ChunkRenderContext
  145. * @property {Chunk} chunk the chunk
  146. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  147. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  148. * @property {ModuleGraph} moduleGraph the module graph
  149. * @property {ChunkGraph} chunkGraph the chunk graph
  150. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  151. * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
  152. * @property {boolean | undefined} strictMode rendering in strict context
  153. */
  154. /**
  155. * @typedef {object} RenderBootstrapContext
  156. * @property {Chunk} chunk the chunk
  157. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  158. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  159. * @property {ModuleGraph} moduleGraph the module graph
  160. * @property {ChunkGraph} chunkGraph the chunk graph
  161. * @property {string} hash hash to be used for render call
  162. */
  163. /**
  164. * @typedef {object} StartupRenderContext
  165. * @property {Chunk} chunk the chunk
  166. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  167. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  168. * @property {ModuleGraph} moduleGraph the module graph
  169. * @property {ChunkGraph} chunkGraph the chunk graph
  170. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  171. * @property {boolean | undefined} strictMode rendering in strict context
  172. * @property {boolean} inlined inlined
  173. * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE
  174. */
  175. /**
  176. * @typedef {object} ModuleRenderContext
  177. * @property {Chunk} chunk the chunk
  178. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  179. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  180. * @property {ModuleGraph} moduleGraph the module graph
  181. * @property {ChunkGraph} chunkGraph the chunk graph
  182. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  183. * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
  184. * @property {boolean | undefined} strictMode rendering in strict context
  185. * @property {boolean} factory true: renders as factory method, false: pure module content
  186. * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE, existing only when `factory` is set to false
  187. * @property {boolean=} renderInObject render module in object container
  188. */
  189. /**
  190. * @typedef {object} CompilationHooks
  191. * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContent
  192. * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContainer
  193. * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModulePackage
  194. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
  195. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
  196. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent
  197. * @property {SyncWaterfallHook<[Source, RenderContext]>} render
  198. * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup
  199. * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire
  200. * @property {SyncBailHook<[Module, Partial<RenderBootstrapContext>], string | void>} inlineInRuntimeBailout
  201. * @property {SyncBailHook<[Module, RenderContext], string | void>} embedInRuntimeBailout
  202. * @property {SyncBailHook<[RenderContext], string | void>} strictRuntimeBailout
  203. * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
  204. * @property {SyncBailHook<[Chunk, RenderContext], boolean | void>} useSourceMap
  205. */
  206. /** @type {WeakMap<Compilation, CompilationHooks>} */
  207. const compilationHooksMap = new WeakMap();
  208. const PLUGIN_NAME = "JavascriptModulesPlugin";
  209. /** @typedef {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} Bootstrap */
  210. class JavascriptModulesPlugin {
  211. /**
  212. * @param {Compilation} compilation the compilation
  213. * @returns {CompilationHooks} the attached hooks
  214. */
  215. static getCompilationHooks(compilation) {
  216. if (!(compilation instanceof Compilation)) {
  217. throw new TypeError(
  218. "The 'compilation' argument must be an instance of Compilation"
  219. );
  220. }
  221. let hooks = compilationHooksMap.get(compilation);
  222. if (hooks === undefined) {
  223. hooks = {
  224. renderModuleContent: new SyncWaterfallHook([
  225. "source",
  226. "module",
  227. "moduleRenderContext"
  228. ]),
  229. renderModuleContainer: new SyncWaterfallHook([
  230. "source",
  231. "module",
  232. "moduleRenderContext"
  233. ]),
  234. renderModulePackage: new SyncWaterfallHook([
  235. "source",
  236. "module",
  237. "moduleRenderContext"
  238. ]),
  239. render: new SyncWaterfallHook(["source", "renderContext"]),
  240. renderContent: new SyncWaterfallHook(["source", "renderContext"]),
  241. renderStartup: new SyncWaterfallHook([
  242. "source",
  243. "module",
  244. "startupRenderContext"
  245. ]),
  246. renderChunk: new SyncWaterfallHook(["source", "renderContext"]),
  247. renderMain: new SyncWaterfallHook(["source", "renderContext"]),
  248. renderRequire: new SyncWaterfallHook(["code", "renderContext"]),
  249. inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  250. embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  251. strictRuntimeBailout: new SyncBailHook(["renderContext"]),
  252. chunkHash: new SyncHook(["chunk", "hash", "context"]),
  253. useSourceMap: new SyncBailHook(["chunk", "renderContext"])
  254. };
  255. compilationHooksMap.set(compilation, hooks);
  256. }
  257. return hooks;
  258. }
  259. constructor(options = {}) {
  260. this.options = options;
  261. /** @type {WeakMap<Source, { source: Source, needModule:boolean, needExports: boolean, needRequire: boolean, needThisAsExports: boolean, needStrict: boolean | undefined, renderShorthand: boolean }>} */
  262. this._moduleFactoryCache = new WeakMap();
  263. }
  264. /**
  265. * Apply the plugin
  266. * @param {Compiler} compiler the compiler instance
  267. * @returns {void}
  268. */
  269. apply(compiler) {
  270. compiler.hooks.compilation.tap(
  271. PLUGIN_NAME,
  272. (compilation, { normalModuleFactory }) => {
  273. const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
  274. for (const type of [
  275. JAVASCRIPT_MODULE_TYPE_AUTO,
  276. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  277. JAVASCRIPT_MODULE_TYPE_ESM
  278. ]) {
  279. normalModuleFactory.hooks.createParser
  280. .for(type)
  281. .tap(PLUGIN_NAME, (options) => {
  282. switch (type) {
  283. case JAVASCRIPT_MODULE_TYPE_AUTO: {
  284. return new JavascriptParser("auto", { parse: options.parse });
  285. }
  286. case JAVASCRIPT_MODULE_TYPE_DYNAMIC: {
  287. return new JavascriptParser("script", {
  288. parse: options.parse
  289. });
  290. }
  291. case JAVASCRIPT_MODULE_TYPE_ESM: {
  292. return new JavascriptParser("module", {
  293. parse: options.parse
  294. });
  295. }
  296. }
  297. });
  298. normalModuleFactory.hooks.createGenerator
  299. .for(type)
  300. .tap(PLUGIN_NAME, () => new JavascriptGenerator());
  301. NormalModule.getCompilationHooks(compilation).processResult.tap(
  302. PLUGIN_NAME,
  303. (result, module) => {
  304. if (module.type === type) {
  305. const [source, ...rest] = result;
  306. return [removeBOM(source), ...rest];
  307. }
  308. return result;
  309. }
  310. );
  311. }
  312. compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
  313. const {
  314. hash,
  315. chunk,
  316. chunkGraph,
  317. moduleGraph,
  318. runtimeTemplate,
  319. dependencyTemplates,
  320. outputOptions,
  321. codeGenerationResults
  322. } = options;
  323. const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
  324. const filenameTemplate =
  325. JavascriptModulesPlugin.getChunkFilenameTemplate(
  326. chunk,
  327. outputOptions
  328. );
  329. let render;
  330. if (hotUpdateChunk) {
  331. render = () =>
  332. this.renderChunk(
  333. {
  334. chunk,
  335. dependencyTemplates,
  336. runtimeTemplate,
  337. moduleGraph,
  338. chunkGraph,
  339. codeGenerationResults,
  340. strictMode: runtimeTemplate.isModule()
  341. },
  342. hooks
  343. );
  344. } else if (chunk.hasRuntime()) {
  345. if (!chunkHasRuntimeOrJs(chunk, chunkGraph)) {
  346. return result;
  347. }
  348. render = () =>
  349. this.renderMain(
  350. {
  351. hash,
  352. chunk,
  353. dependencyTemplates,
  354. runtimeTemplate,
  355. moduleGraph,
  356. chunkGraph,
  357. codeGenerationResults,
  358. strictMode: runtimeTemplate.isModule()
  359. },
  360. hooks,
  361. compilation
  362. );
  363. } else {
  364. if (!chunkHasJs(chunk, chunkGraph)) {
  365. return result;
  366. }
  367. render = () =>
  368. this.renderChunk(
  369. {
  370. chunk,
  371. dependencyTemplates,
  372. runtimeTemplate,
  373. moduleGraph,
  374. chunkGraph,
  375. codeGenerationResults,
  376. strictMode: runtimeTemplate.isModule()
  377. },
  378. hooks
  379. );
  380. }
  381. result.push({
  382. render,
  383. filenameTemplate,
  384. pathOptions: {
  385. hash,
  386. runtime: chunk.runtime,
  387. chunk,
  388. contentHashType: "javascript"
  389. },
  390. info: {
  391. javascriptModule: compilation.runtimeTemplate.isModule()
  392. },
  393. identifier: hotUpdateChunk
  394. ? `hotupdatechunk${chunk.id}`
  395. : `chunk${chunk.id}`,
  396. hash: chunk.contentHash.javascript
  397. });
  398. return result;
  399. });
  400. compilation.hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, context) => {
  401. hooks.chunkHash.call(chunk, hash, context);
  402. if (chunk.hasRuntime()) {
  403. this.updateHashWithBootstrap(
  404. hash,
  405. {
  406. hash: "0000",
  407. chunk,
  408. codeGenerationResults: context.codeGenerationResults,
  409. chunkGraph: context.chunkGraph,
  410. moduleGraph: context.moduleGraph,
  411. runtimeTemplate: context.runtimeTemplate
  412. },
  413. hooks
  414. );
  415. }
  416. });
  417. compilation.hooks.contentHash.tap(PLUGIN_NAME, (chunk) => {
  418. const {
  419. chunkGraph,
  420. moduleGraph,
  421. runtimeTemplate,
  422. outputOptions: {
  423. hashSalt,
  424. hashDigest,
  425. hashDigestLength,
  426. hashFunction
  427. }
  428. } = compilation;
  429. const codeGenerationResults =
  430. /** @type {CodeGenerationResults} */
  431. (compilation.codeGenerationResults);
  432. const hash = createHash(hashFunction);
  433. if (hashSalt) hash.update(hashSalt);
  434. if (chunk.hasRuntime()) {
  435. this.updateHashWithBootstrap(
  436. hash,
  437. {
  438. hash: "0000",
  439. chunk,
  440. codeGenerationResults,
  441. chunkGraph: compilation.chunkGraph,
  442. moduleGraph: compilation.moduleGraph,
  443. runtimeTemplate: compilation.runtimeTemplate
  444. },
  445. hooks
  446. );
  447. } else {
  448. hash.update(`${chunk.id} `);
  449. hash.update(chunk.ids ? chunk.ids.join(",") : "");
  450. }
  451. hooks.chunkHash.call(chunk, hash, {
  452. chunkGraph,
  453. codeGenerationResults,
  454. moduleGraph,
  455. runtimeTemplate
  456. });
  457. const modules = chunkGraph.getChunkModulesIterableBySourceType(
  458. chunk,
  459. JAVASCRIPT_TYPE
  460. );
  461. if (modules) {
  462. const xor = new StringXor();
  463. for (const m of modules) {
  464. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  465. }
  466. xor.updateHash(hash);
  467. }
  468. const runtimeModules = chunkGraph.getChunkModulesIterableBySourceType(
  469. chunk,
  470. WEBPACK_MODULE_TYPE_RUNTIME
  471. );
  472. if (runtimeModules) {
  473. const xor = new StringXor();
  474. for (const m of runtimeModules) {
  475. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  476. }
  477. xor.updateHash(hash);
  478. }
  479. const digest = hash.digest(hashDigest);
  480. chunk.contentHash.javascript = nonNumericOnlyHash(
  481. digest,
  482. hashDigestLength
  483. );
  484. });
  485. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  486. PLUGIN_NAME,
  487. (chunk, set, { chunkGraph }) => {
  488. if (
  489. !set.has(RuntimeGlobals.startupNoDefault) &&
  490. chunkGraph.hasChunkEntryDependentChunks(chunk)
  491. ) {
  492. set.add(RuntimeGlobals.onChunksLoaded);
  493. set.add(RuntimeGlobals.exports);
  494. set.add(RuntimeGlobals.require);
  495. }
  496. }
  497. );
  498. compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
  499. const source =
  500. options.codeGenerationResult.sources.get(JAVASCRIPT_TYPE);
  501. if (source === undefined) return;
  502. const { module } = options;
  503. const code = source.source();
  504. const fn = vm.runInThisContext(
  505. `(function(${module.moduleArgument}, ${module.exportsArgument}, ${RuntimeGlobals.require}) {\n${code}\n/**/})`,
  506. {
  507. filename: module.identifier(),
  508. lineOffset: -1
  509. }
  510. );
  511. const moduleObject =
  512. /** @type {ExecuteModuleObject} */
  513. (options.moduleObject);
  514. try {
  515. fn.call(
  516. moduleObject.exports,
  517. moduleObject,
  518. moduleObject.exports,
  519. context.__webpack_require__
  520. );
  521. } catch (err) {
  522. /** @type {Error} */
  523. (err).stack += printGeneratedCodeForStack(
  524. options.module,
  525. /** @type {string} */ (code)
  526. );
  527. throw err;
  528. }
  529. });
  530. compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
  531. const source = options.codeGenerationResult.sources.get("runtime");
  532. if (source === undefined) return;
  533. let code = source.source();
  534. if (typeof code !== "string") code = code.toString();
  535. const fn = vm.runInThisContext(
  536. `(function(${RuntimeGlobals.require}) {\n${code}\n/**/})`,
  537. {
  538. filename: options.module.identifier(),
  539. lineOffset: -1
  540. }
  541. );
  542. try {
  543. // eslint-disable-next-line no-useless-call
  544. fn.call(null, context.__webpack_require__);
  545. } catch (err) {
  546. /** @type {Error} */
  547. (err).stack += printGeneratedCodeForStack(options.module, code);
  548. throw err;
  549. }
  550. });
  551. }
  552. );
  553. }
  554. /**
  555. * @param {Chunk} chunk chunk
  556. * @param {OutputOptions} outputOptions output options
  557. * @returns {TemplatePath} used filename template
  558. */
  559. static getChunkFilenameTemplate(chunk, outputOptions) {
  560. if (chunk.filenameTemplate) {
  561. return chunk.filenameTemplate;
  562. } else if (chunk instanceof HotUpdateChunk) {
  563. return outputOptions.hotUpdateChunkFilename;
  564. } else if (chunk.canBeInitial()) {
  565. return outputOptions.filename;
  566. }
  567. return outputOptions.chunkFilename;
  568. }
  569. /**
  570. * @param {Module} module the rendered module
  571. * @param {ModuleRenderContext} renderContext options object
  572. * @param {CompilationHooks} hooks hooks
  573. * @returns {Source | null} the newly generated source from rendering
  574. */
  575. renderModule(module, renderContext, hooks) {
  576. const {
  577. chunk,
  578. chunkGraph,
  579. runtimeTemplate,
  580. codeGenerationResults,
  581. strictMode,
  582. factory,
  583. renderInObject
  584. } = renderContext;
  585. try {
  586. const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
  587. const moduleSource = codeGenResult.sources.get(JAVASCRIPT_TYPE);
  588. if (!moduleSource) return null;
  589. if (codeGenResult.data !== undefined) {
  590. const chunkInitFragments = codeGenResult.data.get("chunkInitFragments");
  591. if (chunkInitFragments) {
  592. for (const i of chunkInitFragments) {
  593. renderContext.chunkInitFragments.push(i);
  594. }
  595. }
  596. }
  597. const moduleSourcePostContent = tryRunOrWebpackError(
  598. () =>
  599. hooks.renderModuleContent.call(moduleSource, module, renderContext),
  600. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContent"
  601. );
  602. let moduleSourcePostContainer;
  603. if (factory) {
  604. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  605. module,
  606. chunk.runtime
  607. );
  608. const needModule = runtimeRequirements.has(RuntimeGlobals.module);
  609. const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
  610. const needRequire =
  611. runtimeRequirements.has(RuntimeGlobals.require) ||
  612. runtimeRequirements.has(RuntimeGlobals.requireScope);
  613. const needThisAsExports = runtimeRequirements.has(
  614. RuntimeGlobals.thisAsExports
  615. );
  616. const needStrict =
  617. /** @type {BuildInfo} */
  618. (module.buildInfo).strict && !strictMode;
  619. const cacheEntry = this._moduleFactoryCache.get(
  620. moduleSourcePostContent
  621. );
  622. const renderShorthand =
  623. renderInObject === true && runtimeTemplate.supportsMethodShorthand();
  624. let source;
  625. if (
  626. cacheEntry &&
  627. cacheEntry.needModule === needModule &&
  628. cacheEntry.needExports === needExports &&
  629. cacheEntry.needRequire === needRequire &&
  630. cacheEntry.needThisAsExports === needThisAsExports &&
  631. cacheEntry.needStrict === needStrict &&
  632. cacheEntry.renderShorthand === renderShorthand
  633. ) {
  634. source = cacheEntry.source;
  635. } else {
  636. const factorySource = new ConcatSource();
  637. const args = [];
  638. if (needExports || needRequire || needModule) {
  639. args.push(
  640. needModule
  641. ? module.moduleArgument
  642. : `__unused_webpack_${module.moduleArgument}`
  643. );
  644. }
  645. if (needExports || needRequire) {
  646. args.push(
  647. needExports
  648. ? module.exportsArgument
  649. : `__unused_webpack_${module.exportsArgument}`
  650. );
  651. }
  652. if (needRequire) args.push(RuntimeGlobals.require);
  653. if (renderShorthand) {
  654. // we can optimize function to methodShorthand if render module factory in object
  655. factorySource.add(`(${args.join(", ")}) {\n\n`);
  656. } else if (
  657. !needThisAsExports &&
  658. runtimeTemplate.supportsArrowFunction()
  659. ) {
  660. factorySource.add(`/***/ ((${args.join(", ")}) => {\n\n`);
  661. } else {
  662. factorySource.add(`/***/ (function(${args.join(", ")}) {\n\n`);
  663. }
  664. if (needStrict) {
  665. factorySource.add('"use strict";\n');
  666. }
  667. factorySource.add(moduleSourcePostContent);
  668. factorySource.add(`\n\n/***/ }${renderShorthand ? "" : ")"}`);
  669. source = new CachedSource(factorySource);
  670. this._moduleFactoryCache.set(moduleSourcePostContent, {
  671. source,
  672. needModule,
  673. needExports,
  674. needRequire,
  675. needThisAsExports,
  676. needStrict,
  677. renderShorthand
  678. });
  679. }
  680. moduleSourcePostContainer = tryRunOrWebpackError(
  681. () => hooks.renderModuleContainer.call(source, module, renderContext),
  682. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer"
  683. );
  684. } else {
  685. moduleSourcePostContainer = moduleSourcePostContent;
  686. }
  687. return tryRunOrWebpackError(
  688. () =>
  689. hooks.renderModulePackage.call(
  690. moduleSourcePostContainer,
  691. module,
  692. renderContext
  693. ),
  694. "JavascriptModulesPlugin.getCompilationHooks().renderModulePackage"
  695. );
  696. } catch (err) {
  697. /** @type {WebpackError} */
  698. (err).module = module;
  699. throw err;
  700. }
  701. }
  702. /**
  703. * @param {RenderContext} renderContext the render context
  704. * @param {CompilationHooks} hooks hooks
  705. * @returns {Source} the rendered source
  706. */
  707. renderChunk(renderContext, hooks) {
  708. const { chunk, chunkGraph } = renderContext;
  709. const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
  710. chunk,
  711. JAVASCRIPT_TYPE,
  712. compareModulesByIdOrIdentifier(chunkGraph)
  713. );
  714. const allModules = modules ? [...modules] : [];
  715. let strictHeader;
  716. let allStrict = renderContext.strictMode;
  717. if (
  718. !allStrict &&
  719. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
  720. ) {
  721. const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
  722. strictHeader = strictBailout
  723. ? `// runtime can't be in strict mode because ${strictBailout}.\n`
  724. : '"use strict";\n';
  725. if (!strictBailout) allStrict = true;
  726. }
  727. /** @type {ChunkRenderContext} */
  728. const chunkRenderContext = {
  729. ...renderContext,
  730. chunkInitFragments: [],
  731. strictMode: allStrict
  732. };
  733. const moduleSources =
  734. Template.renderChunkModules(
  735. chunkRenderContext,
  736. allModules,
  737. (module, renderInObject) =>
  738. this.renderModule(
  739. module,
  740. { ...chunkRenderContext, factory: true, renderInObject },
  741. hooks
  742. )
  743. ) || new RawSource("{}");
  744. let source = tryRunOrWebpackError(
  745. () => hooks.renderChunk.call(moduleSources, chunkRenderContext),
  746. "JavascriptModulesPlugin.getCompilationHooks().renderChunk"
  747. );
  748. source = tryRunOrWebpackError(
  749. () => hooks.renderContent.call(source, chunkRenderContext),
  750. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  751. );
  752. if (!source) {
  753. throw new Error(
  754. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  755. );
  756. }
  757. source = InitFragment.addToSource(
  758. source,
  759. chunkRenderContext.chunkInitFragments,
  760. chunkRenderContext
  761. );
  762. source = tryRunOrWebpackError(
  763. () => hooks.render.call(source, chunkRenderContext),
  764. "JavascriptModulesPlugin.getCompilationHooks().render"
  765. );
  766. if (!source) {
  767. throw new Error(
  768. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  769. );
  770. }
  771. chunk.rendered = true;
  772. return strictHeader
  773. ? new ConcatSource(strictHeader, source, ";")
  774. : renderContext.runtimeTemplate.isModule()
  775. ? source
  776. : new ConcatSource(source, ";");
  777. }
  778. /**
  779. * @param {MainRenderContext} renderContext options object
  780. * @param {CompilationHooks} hooks hooks
  781. * @param {Compilation} compilation the compilation
  782. * @returns {Source} the newly generated source from rendering
  783. */
  784. renderMain(renderContext, hooks, compilation) {
  785. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  786. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  787. const iife = runtimeTemplate.isIIFE();
  788. const bootstrap = this.renderBootstrap(renderContext, hooks);
  789. const useSourceMap = hooks.useSourceMap.call(chunk, renderContext);
  790. /** @type {Module[]} */
  791. const allModules = [
  792. ...(chunkGraph.getOrderedChunkModulesIterableBySourceType(
  793. chunk,
  794. JAVASCRIPT_TYPE,
  795. compareModulesByIdOrIdentifier(chunkGraph)
  796. ) || [])
  797. ];
  798. const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0;
  799. /** @type {Set<Module> | undefined} */
  800. let inlinedModules;
  801. if (bootstrap.allowInlineStartup && hasEntryModules) {
  802. inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
  803. }
  804. const source = new ConcatSource();
  805. let prefix;
  806. if (iife) {
  807. if (runtimeTemplate.supportsArrowFunction()) {
  808. source.add("/******/ (() => { // webpackBootstrap\n");
  809. } else {
  810. source.add("/******/ (function() { // webpackBootstrap\n");
  811. }
  812. prefix = "/******/ \t";
  813. } else {
  814. prefix = "/******/ ";
  815. }
  816. let allStrict = renderContext.strictMode;
  817. if (
  818. !allStrict &&
  819. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
  820. ) {
  821. const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
  822. if (strictBailout) {
  823. source.add(
  824. `${
  825. prefix
  826. }// runtime can't be in strict mode because ${strictBailout}.\n`
  827. );
  828. } else {
  829. allStrict = true;
  830. source.add(`${prefix}"use strict";\n`);
  831. }
  832. }
  833. /** @type {ChunkRenderContext} */
  834. const chunkRenderContext = {
  835. ...renderContext,
  836. chunkInitFragments: [],
  837. strictMode: allStrict
  838. };
  839. const chunkModules = Template.renderChunkModules(
  840. chunkRenderContext,
  841. inlinedModules
  842. ? allModules.filter(
  843. (m) => !(/** @type {Set<Module>} */ (inlinedModules).has(m))
  844. )
  845. : allModules,
  846. (module, renderInObject) =>
  847. this.renderModule(
  848. module,
  849. { ...chunkRenderContext, factory: true, renderInObject },
  850. hooks
  851. ),
  852. prefix
  853. );
  854. if (
  855. chunkModules ||
  856. runtimeRequirements.has(RuntimeGlobals.moduleFactories) ||
  857. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) ||
  858. runtimeRequirements.has(RuntimeGlobals.require)
  859. ) {
  860. source.add(`${prefix}var __webpack_modules__ = (`);
  861. source.add(chunkModules || "{}");
  862. source.add(");\n");
  863. source.add(
  864. "/************************************************************************/\n"
  865. );
  866. }
  867. if (bootstrap.header.length > 0) {
  868. const header = `${Template.asString(bootstrap.header)}\n`;
  869. source.add(
  870. new PrefixSource(
  871. prefix,
  872. useSourceMap
  873. ? new OriginalSource(header, "webpack/bootstrap")
  874. : new RawSource(header)
  875. )
  876. );
  877. source.add(
  878. "/************************************************************************/\n"
  879. );
  880. }
  881. const runtimeModules =
  882. renderContext.chunkGraph.getChunkRuntimeModulesInOrder(chunk);
  883. if (runtimeModules.length > 0) {
  884. source.add(
  885. new PrefixSource(
  886. prefix,
  887. Template.renderRuntimeModules(runtimeModules, chunkRenderContext)
  888. )
  889. );
  890. source.add(
  891. "/************************************************************************/\n"
  892. );
  893. // runtimeRuntimeModules calls codeGeneration
  894. for (const module of runtimeModules) {
  895. compilation.codeGeneratedModules.add(module);
  896. }
  897. }
  898. if (inlinedModules) {
  899. if (bootstrap.beforeStartup.length > 0) {
  900. const beforeStartup = `${Template.asString(bootstrap.beforeStartup)}\n`;
  901. source.add(
  902. new PrefixSource(
  903. prefix,
  904. useSourceMap
  905. ? new OriginalSource(beforeStartup, "webpack/before-startup")
  906. : new RawSource(beforeStartup)
  907. )
  908. );
  909. }
  910. const lastInlinedModule = /** @type {Module} */ (last(inlinedModules));
  911. const startupSource = new ConcatSource();
  912. if (runtimeRequirements.has(RuntimeGlobals.exports)) {
  913. startupSource.add(`var ${RuntimeGlobals.exports} = {};\n`);
  914. }
  915. const avoidEntryIife = compilation.options.optimization.avoidEntryIife;
  916. /** @type {Map<Module, Source> | false} */
  917. let renamedInlinedModule = false;
  918. let inlinedInIIFE = false;
  919. if (avoidEntryIife) {
  920. renamedInlinedModule = this._getRenamedInlineModule(
  921. compilation,
  922. allModules,
  923. renderContext,
  924. inlinedModules,
  925. chunkRenderContext,
  926. hooks,
  927. allStrict,
  928. Boolean(chunkModules)
  929. );
  930. }
  931. for (const m of inlinedModules) {
  932. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  933. m,
  934. chunk.runtime
  935. );
  936. const exports = runtimeRequirements.has(RuntimeGlobals.exports);
  937. const webpackExports =
  938. exports && m.exportsArgument === RuntimeGlobals.exports;
  939. const innerStrict =
  940. !allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict;
  941. const iife = innerStrict
  942. ? "it needs to be in strict mode."
  943. : inlinedModules.size > 1
  944. ? // TODO check globals and top-level declarations of other entries and chunk modules
  945. // to make a better decision
  946. "it needs to be isolated against other entry modules."
  947. : chunkModules && !renamedInlinedModule
  948. ? "it needs to be isolated against other modules in the chunk."
  949. : exports && !webpackExports
  950. ? `it uses a non-standard name for the exports (${m.exportsArgument}).`
  951. : hooks.embedInRuntimeBailout.call(m, renderContext);
  952. if (iife) {
  953. inlinedInIIFE = true;
  954. }
  955. const renderedModule = renamedInlinedModule
  956. ? renamedInlinedModule.get(m)
  957. : this.renderModule(
  958. m,
  959. {
  960. ...chunkRenderContext,
  961. factory: false,
  962. inlinedInIIFE
  963. },
  964. hooks
  965. );
  966. if (renderedModule) {
  967. let footer;
  968. if (iife !== undefined) {
  969. startupSource.add(
  970. `// This entry needs to be wrapped in an IIFE because ${iife}\n`
  971. );
  972. const arrow = runtimeTemplate.supportsArrowFunction();
  973. if (arrow) {
  974. startupSource.add("(() => {\n");
  975. footer = "\n})();\n\n";
  976. } else {
  977. startupSource.add("!function() {\n");
  978. footer = "\n}();\n";
  979. }
  980. if (innerStrict) startupSource.add('"use strict";\n');
  981. } else {
  982. footer = "\n";
  983. }
  984. if (exports) {
  985. if (m !== lastInlinedModule) {
  986. startupSource.add(`var ${m.exportsArgument} = {};\n`);
  987. } else if (m.exportsArgument !== RuntimeGlobals.exports) {
  988. startupSource.add(
  989. `var ${m.exportsArgument} = ${RuntimeGlobals.exports};\n`
  990. );
  991. }
  992. }
  993. startupSource.add(renderedModule);
  994. startupSource.add(footer);
  995. }
  996. }
  997. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  998. startupSource.add(
  999. `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});\n`
  1000. );
  1001. }
  1002. source.add(
  1003. hooks.renderStartup.call(startupSource, lastInlinedModule, {
  1004. ...renderContext,
  1005. inlined: true,
  1006. inlinedInIIFE
  1007. })
  1008. );
  1009. if (bootstrap.afterStartup.length > 0) {
  1010. const afterStartup = `${Template.asString(bootstrap.afterStartup)}\n`;
  1011. source.add(
  1012. new PrefixSource(
  1013. prefix,
  1014. useSourceMap
  1015. ? new OriginalSource(afterStartup, "webpack/after-startup")
  1016. : new RawSource(afterStartup)
  1017. )
  1018. );
  1019. }
  1020. } else {
  1021. const lastEntryModule =
  1022. /** @type {Module} */
  1023. (last(chunkGraph.getChunkEntryModulesIterable(chunk)));
  1024. /** @type {(content: string[], name: string) => Source} */
  1025. const toSource = useSourceMap
  1026. ? (content, name) =>
  1027. new OriginalSource(Template.asString(content), name)
  1028. : (content) => new RawSource(Template.asString(content));
  1029. source.add(
  1030. new PrefixSource(
  1031. prefix,
  1032. new ConcatSource(
  1033. toSource(bootstrap.beforeStartup, "webpack/before-startup"),
  1034. "\n",
  1035. hooks.renderStartup.call(
  1036. toSource([...bootstrap.startup, ""], "webpack/startup"),
  1037. lastEntryModule,
  1038. {
  1039. ...renderContext,
  1040. inlined: false
  1041. }
  1042. ),
  1043. toSource(bootstrap.afterStartup, "webpack/after-startup"),
  1044. "\n"
  1045. )
  1046. )
  1047. );
  1048. }
  1049. if (
  1050. hasEntryModules &&
  1051. runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)
  1052. ) {
  1053. source.add(`${prefix}return ${RuntimeGlobals.exports};\n`);
  1054. }
  1055. if (iife) {
  1056. source.add("/******/ })()\n");
  1057. }
  1058. /** @type {Source} */
  1059. let finalSource = tryRunOrWebpackError(
  1060. () => hooks.renderMain.call(source, renderContext),
  1061. "JavascriptModulesPlugin.getCompilationHooks().renderMain"
  1062. );
  1063. if (!finalSource) {
  1064. throw new Error(
  1065. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something"
  1066. );
  1067. }
  1068. finalSource = tryRunOrWebpackError(
  1069. () => hooks.renderContent.call(finalSource, renderContext),
  1070. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  1071. );
  1072. if (!finalSource) {
  1073. throw new Error(
  1074. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  1075. );
  1076. }
  1077. finalSource = InitFragment.addToSource(
  1078. finalSource,
  1079. chunkRenderContext.chunkInitFragments,
  1080. chunkRenderContext
  1081. );
  1082. finalSource = tryRunOrWebpackError(
  1083. () => hooks.render.call(finalSource, renderContext),
  1084. "JavascriptModulesPlugin.getCompilationHooks().render"
  1085. );
  1086. if (!finalSource) {
  1087. throw new Error(
  1088. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  1089. );
  1090. }
  1091. chunk.rendered = true;
  1092. return iife ? new ConcatSource(finalSource, ";") : finalSource;
  1093. }
  1094. /**
  1095. * @param {Hash} hash the hash to be updated
  1096. * @param {RenderBootstrapContext} renderContext options object
  1097. * @param {CompilationHooks} hooks hooks
  1098. */
  1099. updateHashWithBootstrap(hash, renderContext, hooks) {
  1100. const bootstrap = this.renderBootstrap(renderContext, hooks);
  1101. for (const _k of Object.keys(bootstrap)) {
  1102. const key = /** @type {keyof Bootstrap} */ (_k);
  1103. hash.update(key);
  1104. if (Array.isArray(bootstrap[key])) {
  1105. for (const line of bootstrap[key]) {
  1106. hash.update(line);
  1107. }
  1108. } else {
  1109. hash.update(JSON.stringify(bootstrap[key]));
  1110. }
  1111. }
  1112. }
  1113. /**
  1114. * @param {RenderBootstrapContext} renderContext options object
  1115. * @param {CompilationHooks} hooks hooks
  1116. * @returns {Bootstrap} the generated source of the bootstrap code
  1117. */
  1118. renderBootstrap(renderContext, hooks) {
  1119. const {
  1120. chunkGraph,
  1121. codeGenerationResults,
  1122. moduleGraph,
  1123. chunk,
  1124. runtimeTemplate
  1125. } = renderContext;
  1126. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1127. const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
  1128. const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
  1129. const moduleFactories = runtimeRequirements.has(
  1130. RuntimeGlobals.moduleFactories
  1131. );
  1132. const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
  1133. const requireScopeUsed = runtimeRequirements.has(
  1134. RuntimeGlobals.requireScope
  1135. );
  1136. const interceptModuleExecution = runtimeRequirements.has(
  1137. RuntimeGlobals.interceptModuleExecution
  1138. );
  1139. const useRequire =
  1140. requireFunction || interceptModuleExecution || moduleUsed;
  1141. /**
  1142. * @type {{startup: string[], beforeStartup: string[], header: string[], afterStartup: string[], allowInlineStartup: boolean}}
  1143. */
  1144. const result = {
  1145. header: [],
  1146. beforeStartup: [],
  1147. startup: [],
  1148. afterStartup: [],
  1149. allowInlineStartup: true
  1150. };
  1151. const { header: buf, startup, beforeStartup, afterStartup } = result;
  1152. if (result.allowInlineStartup && moduleFactories) {
  1153. startup.push(
  1154. "// module factories are used so entry inlining is disabled"
  1155. );
  1156. result.allowInlineStartup = false;
  1157. }
  1158. if (result.allowInlineStartup && moduleCache) {
  1159. startup.push("// module cache are used so entry inlining is disabled");
  1160. result.allowInlineStartup = false;
  1161. }
  1162. if (result.allowInlineStartup && interceptModuleExecution) {
  1163. startup.push(
  1164. "// module execution is intercepted so entry inlining is disabled"
  1165. );
  1166. result.allowInlineStartup = false;
  1167. }
  1168. if (useRequire || moduleCache) {
  1169. buf.push("// The module cache");
  1170. buf.push("var __webpack_module_cache__ = {};");
  1171. buf.push("");
  1172. }
  1173. if (runtimeRequirements.has(RuntimeGlobals.makeDeferredNamespaceObject)) {
  1174. // in order to optimize of DeferredNamespaceObject, we remove all proxy handlers after the module initialize
  1175. // (see MakeDeferredNamespaceObjectRuntimeModule)
  1176. // This requires all deferred imports to a module can get the module export object before the module
  1177. // is evaluated.
  1178. buf.push("// The deferred module cache");
  1179. buf.push("var __webpack_module_deferred_exports__ = {};");
  1180. buf.push("");
  1181. }
  1182. if (useRequire) {
  1183. buf.push("// The require function");
  1184. buf.push(`function ${RuntimeGlobals.require}(moduleId) {`);
  1185. buf.push(Template.indent(this.renderRequire(renderContext, hooks)));
  1186. buf.push("}");
  1187. buf.push("");
  1188. } else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
  1189. buf.push("// The require scope");
  1190. buf.push(`var ${RuntimeGlobals.require} = {};`);
  1191. buf.push("");
  1192. }
  1193. if (
  1194. moduleFactories ||
  1195. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
  1196. ) {
  1197. buf.push("// expose the modules object (__webpack_modules__)");
  1198. buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
  1199. buf.push("");
  1200. }
  1201. if (moduleCache) {
  1202. buf.push("// expose the module cache");
  1203. buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
  1204. buf.push("");
  1205. }
  1206. if (interceptModuleExecution) {
  1207. buf.push("// expose the module execution interceptor");
  1208. buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
  1209. buf.push("");
  1210. }
  1211. if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
  1212. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
  1213. /** @type {string[]} */
  1214. const buf2 = [];
  1215. const runtimeRequirements =
  1216. chunkGraph.getTreeRuntimeRequirements(chunk);
  1217. buf2.push("// Load entry module and return exports");
  1218. let i = chunkGraph.getNumberOfEntryModules(chunk);
  1219. for (const [
  1220. entryModule,
  1221. entrypoint
  1222. ] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
  1223. if (
  1224. !chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
  1225. ) {
  1226. i--;
  1227. continue;
  1228. }
  1229. const chunks =
  1230. /** @type {Entrypoint} */
  1231. (entrypoint).chunks.filter((c) => c !== chunk);
  1232. if (result.allowInlineStartup && chunks.length > 0) {
  1233. buf2.push(
  1234. "// This entry module depends on other loaded chunks and execution need to be delayed"
  1235. );
  1236. result.allowInlineStartup = false;
  1237. }
  1238. if (
  1239. result.allowInlineStartup &&
  1240. someInIterable(
  1241. moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
  1242. ([originModule, connections]) =>
  1243. originModule &&
  1244. connections.some((c) => c.isTargetActive(chunk.runtime)) &&
  1245. someInIterable(
  1246. chunkGraph.getModuleRuntimes(originModule),
  1247. (runtime) =>
  1248. intersectRuntime(runtime, chunk.runtime) !== undefined
  1249. )
  1250. )
  1251. ) {
  1252. buf2.push(
  1253. "// This entry module is referenced by other modules so it can't be inlined"
  1254. );
  1255. result.allowInlineStartup = false;
  1256. }
  1257. let data;
  1258. if (codeGenerationResults.has(entryModule, chunk.runtime)) {
  1259. const result = codeGenerationResults.get(
  1260. entryModule,
  1261. chunk.runtime
  1262. );
  1263. data = result.data;
  1264. }
  1265. if (
  1266. result.allowInlineStartup &&
  1267. (!data || !data.get("topLevelDeclarations")) &&
  1268. (!entryModule.buildInfo ||
  1269. !entryModule.buildInfo.topLevelDeclarations)
  1270. ) {
  1271. buf2.push(
  1272. "// This entry module doesn't tell about it's top-level declarations so it can't be inlined"
  1273. );
  1274. result.allowInlineStartup = false;
  1275. }
  1276. if (result.allowInlineStartup) {
  1277. const bailout = hooks.inlineInRuntimeBailout.call(
  1278. entryModule,
  1279. renderContext
  1280. );
  1281. if (bailout !== undefined) {
  1282. buf2.push(
  1283. `// This entry module can't be inlined because ${bailout}`
  1284. );
  1285. result.allowInlineStartup = false;
  1286. }
  1287. }
  1288. i--;
  1289. const moduleId = chunkGraph.getModuleId(entryModule);
  1290. const entryRuntimeRequirements =
  1291. chunkGraph.getModuleRuntimeRequirements(entryModule, chunk.runtime);
  1292. let moduleIdExpr = JSON.stringify(moduleId);
  1293. if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
  1294. moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
  1295. }
  1296. if (
  1297. result.allowInlineStartup &&
  1298. entryRuntimeRequirements.has(RuntimeGlobals.module)
  1299. ) {
  1300. result.allowInlineStartup = false;
  1301. buf2.push(
  1302. "// This entry module used 'module' so it can't be inlined"
  1303. );
  1304. }
  1305. if (
  1306. result.allowInlineStartup &&
  1307. entryRuntimeRequirements.has(RuntimeGlobals.thisAsExports)
  1308. ) {
  1309. buf2.push(
  1310. "// This entry module used `this` as exports so it can't be inlined"
  1311. );
  1312. result.allowInlineStartup = false;
  1313. }
  1314. if (chunks.length > 0) {
  1315. buf2.push(
  1316. `${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${
  1317. RuntimeGlobals.onChunksLoaded
  1318. }(undefined, ${JSON.stringify(
  1319. chunks.map((c) => c.id)
  1320. )}, ${runtimeTemplate.returningFunction(
  1321. `${RuntimeGlobals.require}(${moduleIdExpr})`
  1322. )})`
  1323. );
  1324. } else if (useRequire) {
  1325. buf2.push(
  1326. `${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${
  1327. RuntimeGlobals.require
  1328. }(${moduleIdExpr});`
  1329. );
  1330. } else {
  1331. if (i === 0) buf2.push(`var ${RuntimeGlobals.exports} = {};`);
  1332. const needThisAsExports = entryRuntimeRequirements.has(
  1333. RuntimeGlobals.thisAsExports
  1334. );
  1335. /** @type {string[]} */
  1336. const args = [];
  1337. if (
  1338. requireScopeUsed ||
  1339. entryRuntimeRequirements.has(RuntimeGlobals.exports)
  1340. ) {
  1341. const exportsArg = i === 0 ? RuntimeGlobals.exports : "{}";
  1342. args.push("0", exportsArg);
  1343. if (requireScopeUsed) {
  1344. args.push(RuntimeGlobals.require);
  1345. }
  1346. }
  1347. buf2.push(
  1348. Template.asString(
  1349. (() => {
  1350. if (needThisAsExports) {
  1351. const comma = args.length ? "," : "";
  1352. return `__webpack_modules__[${moduleIdExpr}].call(${RuntimeGlobals.exports}${comma}${args.join(",")});`;
  1353. }
  1354. return `__webpack_modules__[${moduleIdExpr}](${args.join(",")});`;
  1355. })()
  1356. )
  1357. );
  1358. }
  1359. }
  1360. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  1361. buf2.push(
  1362. `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});`
  1363. );
  1364. }
  1365. if (
  1366. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1367. (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) &&
  1368. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter))
  1369. ) {
  1370. result.allowInlineStartup = false;
  1371. buf.push("// the startup function");
  1372. buf.push(
  1373. `${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction("", [
  1374. ...buf2,
  1375. `return ${RuntimeGlobals.exports};`
  1376. ])};`
  1377. );
  1378. buf.push("");
  1379. startup.push("// run startup");
  1380. startup.push(
  1381. `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
  1382. );
  1383. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) {
  1384. buf.push("// the startup function");
  1385. buf.push(
  1386. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1387. );
  1388. beforeStartup.push("// run runtime startup");
  1389. beforeStartup.push(`${RuntimeGlobals.startup}();`);
  1390. startup.push("// startup");
  1391. startup.push(Template.asString(buf2));
  1392. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)) {
  1393. buf.push("// the startup function");
  1394. buf.push(
  1395. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1396. );
  1397. startup.push("// startup");
  1398. startup.push(Template.asString(buf2));
  1399. afterStartup.push("// run runtime startup");
  1400. afterStartup.push(`${RuntimeGlobals.startup}();`);
  1401. } else {
  1402. startup.push("// startup");
  1403. startup.push(Template.asString(buf2));
  1404. }
  1405. } else if (
  1406. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1407. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1408. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1409. ) {
  1410. buf.push(
  1411. "// the startup function",
  1412. "// It's empty as no entry modules are in this chunk",
  1413. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`,
  1414. ""
  1415. );
  1416. }
  1417. } else if (
  1418. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1419. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1420. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1421. ) {
  1422. result.allowInlineStartup = false;
  1423. buf.push(
  1424. "// the startup function",
  1425. "// It's empty as some runtime module handles the default behavior",
  1426. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1427. );
  1428. startup.push("// run startup");
  1429. startup.push(
  1430. `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
  1431. );
  1432. }
  1433. return result;
  1434. }
  1435. /**
  1436. * @param {RenderBootstrapContext} renderContext options object
  1437. * @param {CompilationHooks} hooks hooks
  1438. * @returns {string} the generated source of the require function
  1439. */
  1440. renderRequire(renderContext, hooks) {
  1441. const {
  1442. chunk,
  1443. chunkGraph,
  1444. runtimeTemplate: { outputOptions }
  1445. } = renderContext;
  1446. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1447. const moduleExecution = runtimeRequirements.has(
  1448. RuntimeGlobals.interceptModuleExecution
  1449. )
  1450. ? Template.asString([
  1451. `var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`,
  1452. `${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
  1453. "module = execOptions.module;",
  1454. "execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
  1455. ])
  1456. : runtimeRequirements.has(RuntimeGlobals.thisAsExports)
  1457. ? Template.asString([
  1458. `__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});`
  1459. ])
  1460. : Template.asString([
  1461. `__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});`
  1462. ]);
  1463. const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
  1464. const needModuleLoaded = runtimeRequirements.has(
  1465. RuntimeGlobals.moduleLoaded
  1466. );
  1467. const needModuleDefer = runtimeRequirements.has(
  1468. RuntimeGlobals.makeDeferredNamespaceObject
  1469. );
  1470. const content = Template.asString([
  1471. "// Check if module is in cache",
  1472. "var cachedModule = __webpack_module_cache__[moduleId];",
  1473. "if (cachedModule !== undefined) {",
  1474. outputOptions.strictModuleErrorHandling
  1475. ? Template.indent([
  1476. "if (cachedModule.error !== undefined) throw cachedModule.error;",
  1477. "return cachedModule.exports;"
  1478. ])
  1479. : Template.indent("return cachedModule.exports;"),
  1480. "}",
  1481. // Add helpful error message in development mode when module is not found
  1482. ...(outputOptions.pathinfo
  1483. ? [
  1484. "// Check if module exists (development only)",
  1485. "if (__webpack_modules__[moduleId] === undefined) {",
  1486. Template.indent([
  1487. 'var e = new Error("Cannot find module \'" + moduleId + "\'");',
  1488. "e.code = 'MODULE_NOT_FOUND';",
  1489. "throw e;"
  1490. ]),
  1491. "}"
  1492. ]
  1493. : []),
  1494. "// Create a new module (and put it into the cache)",
  1495. "var module = __webpack_module_cache__[moduleId] = {",
  1496. Template.indent([
  1497. needModuleId ? "id: moduleId," : "// no module.id needed",
  1498. needModuleLoaded ? "loaded: false," : "// no module.loaded needed",
  1499. needModuleDefer
  1500. ? "exports: __webpack_module_deferred_exports__[moduleId] || {}"
  1501. : "exports: {}"
  1502. ]),
  1503. "};",
  1504. "",
  1505. outputOptions.strictModuleExceptionHandling
  1506. ? Template.asString([
  1507. "// Execute the module function",
  1508. "var threw = true;",
  1509. "try {",
  1510. Template.indent([
  1511. moduleExecution,
  1512. "threw = false;",
  1513. ...(needModuleDefer
  1514. ? ["delete __webpack_module_deferred_exports__[moduleId];"]
  1515. : [])
  1516. ]),
  1517. "} finally {",
  1518. Template.indent([
  1519. "if(threw) delete __webpack_module_cache__[moduleId];"
  1520. ]),
  1521. "}"
  1522. ])
  1523. : outputOptions.strictModuleErrorHandling
  1524. ? Template.asString([
  1525. "// Execute the module function",
  1526. "try {",
  1527. Template.indent(
  1528. needModuleDefer
  1529. ? [
  1530. moduleExecution,
  1531. "delete __webpack_module_deferred_exports__[moduleId];"
  1532. ]
  1533. : moduleExecution
  1534. ),
  1535. "} catch(e) {",
  1536. Template.indent(["module.error = e;", "throw e;"]),
  1537. "}"
  1538. ])
  1539. : Template.asString([
  1540. "// Execute the module function",
  1541. moduleExecution,
  1542. ...(needModuleDefer
  1543. ? ["delete __webpack_module_deferred_exports__[moduleId];"]
  1544. : [])
  1545. ]),
  1546. needModuleLoaded
  1547. ? Template.asString([
  1548. "",
  1549. "// Flag the module as loaded",
  1550. `${RuntimeGlobals.moduleLoaded} = true;`,
  1551. ""
  1552. ])
  1553. : "",
  1554. "// Return the exports of the module",
  1555. "return module.exports;"
  1556. ]);
  1557. return tryRunOrWebpackError(
  1558. () => hooks.renderRequire.call(content, renderContext),
  1559. "JavascriptModulesPlugin.getCompilationHooks().renderRequire"
  1560. );
  1561. }
  1562. /**
  1563. * @param {Compilation} compilation compilation
  1564. * @param {Module[]} allModules allModules
  1565. * @param {MainRenderContext} renderContext renderContext
  1566. * @param {Set<Module>} inlinedModules inlinedModules
  1567. * @param {ChunkRenderContext} chunkRenderContext chunkRenderContext
  1568. * @param {CompilationHooks} hooks hooks
  1569. * @param {boolean | undefined} allStrict allStrict
  1570. * @param {boolean} hasChunkModules hasChunkModules
  1571. * @returns {Map<Module, Source> | false} renamed inlined modules
  1572. */
  1573. _getRenamedInlineModule(
  1574. compilation,
  1575. allModules,
  1576. renderContext,
  1577. inlinedModules,
  1578. chunkRenderContext,
  1579. hooks,
  1580. allStrict,
  1581. hasChunkModules
  1582. ) {
  1583. const innerStrict =
  1584. !allStrict &&
  1585. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict);
  1586. const isMultipleEntries = inlinedModules.size > 1;
  1587. const singleEntryWithModules = inlinedModules.size === 1 && hasChunkModules;
  1588. // TODO:
  1589. // This step is before the IIFE reason calculation. Ideally, it should only be executed when this function can optimize the
  1590. // IIFE reason. Otherwise, it should directly return false. There are four reasons now, we have skipped two already, the left
  1591. // one is 'it uses a non-standard name for the exports'.
  1592. if (isMultipleEntries || innerStrict || !singleEntryWithModules) {
  1593. return false;
  1594. }
  1595. /** @type {Map<Module, Source>} */
  1596. const renamedInlinedModules = new Map();
  1597. const { runtimeTemplate } = renderContext;
  1598. /** @typedef {{ source: Source, module: Module, ast: Program, variables: Set<Variable>, through: Set<Reference>, usedInNonInlined: Set<Variable>, moduleScope: Scope }} Info */
  1599. /** @type {Map<Module, Info>} */
  1600. const inlinedModulesToInfo = new Map();
  1601. /** @type {Set<string>} */
  1602. const nonInlinedModuleThroughIdentifiers = new Set();
  1603. for (const m of allModules) {
  1604. const isInlinedModule = inlinedModules && inlinedModules.has(m);
  1605. const moduleSource = this.renderModule(
  1606. m,
  1607. {
  1608. ...chunkRenderContext,
  1609. factory: !isInlinedModule,
  1610. inlinedInIIFE: false
  1611. },
  1612. hooks
  1613. );
  1614. if (!moduleSource) continue;
  1615. const code = /** @type {string} */ (moduleSource.source());
  1616. const { ast } = JavascriptParser._parse(
  1617. code,
  1618. {
  1619. sourceType: "auto",
  1620. ranges: true
  1621. },
  1622. JavascriptParser._getModuleParseFunction(compilation, m)
  1623. );
  1624. const scopeManager = eslintScope.analyze(ast, {
  1625. ecmaVersion: 6,
  1626. sourceType: "module",
  1627. optimistic: true,
  1628. ignoreEval: true
  1629. });
  1630. const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast));
  1631. if (inlinedModules && inlinedModules.has(m)) {
  1632. const moduleScope = globalScope.childScopes[0];
  1633. inlinedModulesToInfo.set(m, {
  1634. source: moduleSource,
  1635. ast,
  1636. module: m,
  1637. variables: new Set(moduleScope.variables),
  1638. through: new Set(moduleScope.through),
  1639. usedInNonInlined: new Set(),
  1640. moduleScope
  1641. });
  1642. } else {
  1643. for (const ref of globalScope.through) {
  1644. nonInlinedModuleThroughIdentifiers.add(ref.identifier.name);
  1645. }
  1646. }
  1647. }
  1648. for (const [, { variables, usedInNonInlined }] of inlinedModulesToInfo) {
  1649. for (const variable of variables) {
  1650. if (
  1651. nonInlinedModuleThroughIdentifiers.has(variable.name) ||
  1652. RESERVED_NAMES.has(variable.name)
  1653. ) {
  1654. usedInNonInlined.add(variable);
  1655. }
  1656. }
  1657. }
  1658. for (const [m, moduleInfo] of inlinedModulesToInfo) {
  1659. const { ast, source: _source, usedInNonInlined } = moduleInfo;
  1660. const source = new ReplaceSource(_source);
  1661. if (usedInNonInlined.size === 0) {
  1662. renamedInlinedModules.set(m, source);
  1663. continue;
  1664. }
  1665. const info = /** @type {Info} */ (inlinedModulesToInfo.get(m));
  1666. const allUsedNames = new Set(
  1667. Array.from(info.through, (v) => v.identifier.name)
  1668. );
  1669. for (const variable of usedInNonInlined) {
  1670. allUsedNames.add(variable.name);
  1671. }
  1672. for (const variable of info.variables) {
  1673. const usedNamesInScopeInfo = new Map();
  1674. const ignoredScopes = new Set();
  1675. const name = variable.name;
  1676. const { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo(
  1677. usedNamesInScopeInfo,
  1678. info.module.identifier(),
  1679. name
  1680. );
  1681. if (allUsedNames.has(name) || usedNames.has(name)) {
  1682. const references = getAllReferences(variable);
  1683. const allIdentifiers = new Set([
  1684. ...references.map((r) => r.identifier),
  1685. ...variable.identifiers
  1686. ]);
  1687. for (const ref of references) {
  1688. addScopeSymbols(
  1689. ref.from,
  1690. usedNames,
  1691. alreadyCheckedScopes,
  1692. ignoredScopes
  1693. );
  1694. }
  1695. const newName = findNewName(
  1696. variable.name,
  1697. allUsedNames,
  1698. usedNames,
  1699. m.readableIdentifier(runtimeTemplate.requestShortener)
  1700. );
  1701. allUsedNames.add(newName);
  1702. for (const identifier of allIdentifiers) {
  1703. const r = /** @type {Range} */ (identifier.range);
  1704. const path = getPathInAst(ast, identifier);
  1705. if (path && path.length > 1) {
  1706. const maybeProperty =
  1707. path[1].type === "AssignmentPattern" && path[1].left === path[0]
  1708. ? path[2]
  1709. : path[1];
  1710. if (
  1711. maybeProperty.type === "Property" &&
  1712. maybeProperty.shorthand
  1713. ) {
  1714. source.insert(r[1], `: ${newName}`);
  1715. continue;
  1716. }
  1717. }
  1718. source.replace(r[0], r[1] - 1, newName);
  1719. }
  1720. }
  1721. allUsedNames.add(name);
  1722. }
  1723. renamedInlinedModules.set(m, source);
  1724. }
  1725. return renamedInlinedModules;
  1726. }
  1727. }
  1728. module.exports = JavascriptModulesPlugin;
  1729. module.exports.chunkHasJs = chunkHasJs;