JavascriptModulesPlugin.js 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346
  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 { SyncBailHook, SyncHook, SyncWaterfallHook } = require("tapable");
  8. const {
  9. CachedSource,
  10. ConcatSource,
  11. OriginalSource,
  12. PrefixSource,
  13. RawSource,
  14. ReplaceSource
  15. } = require("webpack-sources");
  16. /**
  17. * @import Compilation, {
  18. * ChunkHashContext,
  19. * ExecuteModuleObject,
  20. * WebpackRequire
  21. * } from "../Compilation"
  22. */
  23. const HotUpdateChunk = require("../HotUpdateChunk");
  24. const InitFragment = require("../InitFragment");
  25. const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
  26. const {
  27. JAVASCRIPT_MODULE_TYPE_AUTO,
  28. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  29. JAVASCRIPT_MODULE_TYPE_ESM,
  30. WEBPACK_MODULE_TYPE_RUNTIME
  31. } = require("../ModuleTypeConstants");
  32. const NormalModule = require("../NormalModule");
  33. const RuntimeGlobals = require("../RuntimeGlobals");
  34. const Template = require("../Template");
  35. const { tryRunOrWebpackError } = require("../errors/HookWebpackError");
  36. const { last, someInIterable } = require("../util/IterableHelpers");
  37. const StringXor = require("../util/StringXor");
  38. const { compareModulesByFullName } = require("../util/comparators");
  39. const {
  40. CHUNK_RUNTIME_DECLARATIONS,
  41. RESERVED_NAMES,
  42. addScopeSymbols,
  43. findNewName,
  44. getAllReferences,
  45. getPathInAst,
  46. getUsedNamesInScopeInfo
  47. } = require("../util/concatenate");
  48. const createHash = require("../util/createHash");
  49. const createHooksRegistry = require("../util/createHooksRegistry");
  50. const { digestNonNumericOnlyWithFull } = require("../util/nonNumericOnlyHash");
  51. const removeBOM = require("../util/removeBOM");
  52. const { intersectRuntime } = require("../util/runtime");
  53. const { getAllChunks } = require("./ChunkHelpers");
  54. const JavascriptGenerator = require("./JavascriptGenerator");
  55. const JavascriptModule = require("./JavascriptModule");
  56. const JavascriptParser = require("./JavascriptParser");
  57. const analyzeScope = require("./ScopeAnalyzer");
  58. /**
  59. * @import {
  60. * Program,
  61. * Node,
  62. * Identifier,
  63. * CatchClause,
  64. * ClassDeclaration,
  65. * ClassExpression,
  66. * FunctionDeclaration,
  67. * FunctionExpression,
  68. * ArrowFunctionExpression,
  69. * VariableDeclarator,
  70. * VariableDeclaration,
  71. * ImportDeclaration,
  72. * ImportSpecifier,
  73. * ImportDefaultSpecifier,
  74. * ImportNamespaceSpecifier,
  75. * AssignmentExpression,
  76. * ForInStatement,
  77. * ForOfStatement
  78. * } from "estree"
  79. */
  80. /** @import { Source } from "webpack-sources" */
  81. /**
  82. * @import {
  83. * OutputNormalizedWithDefaults as OutputOptions
  84. * } from "../config/defaults"
  85. */
  86. /** @import Chunk, { ChunkFilenameTemplate } from "../Chunk" */
  87. /** @import ChunkGraph, { EntryModuleWithChunkGroup } from "../ChunkGraph" */
  88. /** @import CodeGenerationResults from "../CodeGenerationResults" */
  89. /** @import Compiler from "../Compiler" */
  90. /** @import DependencyTemplates from "../DependencyTemplates" */
  91. /** @import Entrypoint from "../Entrypoint" */
  92. /** @import Module, { BuildInfo, CodeGenerationResultData } from "../Module" */
  93. /** @import { RuntimeSpec } from "../util/runtime" */
  94. /** @import ModuleGraph from "../ModuleGraph" */
  95. /** @import RuntimeTemplate from "../RuntimeTemplate" */
  96. /** @import WebpackError from "../errors/WebpackError" */
  97. /** @import { Range } from "../javascript/JavascriptParser" */
  98. /** @import Hash from "../util/Hash" */
  99. /** @import { ScopeSet, UsedNamesInScopeInfo } from "../util/concatenate" */
  100. /** @typedef {import("./ScopeAnalyzer").Scope} Scope */
  101. /** @typedef {import("./ScopeAnalyzer").Variable} Variable */
  102. /** @typedef {import("./ScopeAnalyzer").Reference} Reference */
  103. /** @type {WeakMap<ChunkGraph, WeakMap<Chunk, boolean>>} */
  104. const chunkHasJsCache = new WeakMap();
  105. /**
  106. * Returns true, when a JS file is needed for this chunk.
  107. * @param {Chunk} chunk a chunk
  108. * @param {ChunkGraph} chunkGraph the chunk graph
  109. * @returns {boolean} true, when a JS file is needed for this chunk
  110. */
  111. const _chunkHasJs = (chunk, chunkGraph) => {
  112. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
  113. for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
  114. if (chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
  115. return true;
  116. }
  117. }
  118. }
  119. return Boolean(
  120. chunkGraph.getChunkModulesIterableBySourceType(chunk, JAVASCRIPT_TYPE)
  121. );
  122. };
  123. /**
  124. * Returns true, when a JS file is needed for this chunk.
  125. * @param {Chunk} chunk a chunk
  126. * @param {ChunkGraph} chunkGraph the chunk graph
  127. * @returns {boolean} true, when a JS file is needed for this chunk
  128. */
  129. const chunkHasJs = (chunk, chunkGraph) => {
  130. let innerCache = chunkHasJsCache.get(chunkGraph);
  131. if (innerCache === undefined) {
  132. innerCache = new WeakMap();
  133. chunkHasJsCache.set(chunkGraph, innerCache);
  134. }
  135. const cachedResult = innerCache.get(chunk);
  136. if (cachedResult !== undefined) {
  137. return cachedResult;
  138. }
  139. const result = _chunkHasJs(chunk, chunkGraph);
  140. innerCache.set(chunk, result);
  141. return result;
  142. };
  143. /**
  144. * Chunk has runtime or js.
  145. * @param {Chunk} chunk a chunk
  146. * @param {ChunkGraph} chunkGraph the chunk graph
  147. * @returns {boolean} true, when a JS file is needed for this chunk
  148. */
  149. const chunkHasRuntimeOrJs = (chunk, chunkGraph) => {
  150. if (chunkHasJs(chunk, chunkGraph)) {
  151. return true;
  152. }
  153. if (
  154. chunkGraph.getChunkModulesIterableBySourceType(
  155. chunk,
  156. WEBPACK_MODULE_TYPE_RUNTIME
  157. )
  158. ) {
  159. for (const chunkGroup of chunk.groupsIterable) {
  160. for (const c of chunkGroup.chunks) {
  161. if (chunkHasJs(c, chunkGraph)) return true;
  162. }
  163. }
  164. return false;
  165. }
  166. return false;
  167. };
  168. /**
  169. * Print generated code for stack.
  170. * @param {Module} module a module
  171. * @param {string} code the code
  172. * @returns {string} generated code for the stack
  173. */
  174. const printGeneratedCodeForStack = (module, code) => {
  175. const lines = code.split("\n");
  176. const n = `${lines.length}`.length;
  177. return `\n\nGenerated code for ${module.identifier()}\n${lines
  178. .map(
  179. /**
  180. * Handles the callback logic for this hook.
  181. * @param {string} line the line
  182. * @param {number} i the index
  183. * @param {string[]} _lines the lines
  184. * @returns {string} the line with line number
  185. */
  186. (line, i, _lines) => {
  187. const iStr = `${i + 1}`;
  188. return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`;
  189. }
  190. )
  191. .join("\n")}`;
  192. };
  193. /**
  194. * Defines the render context type used by this module.
  195. * @typedef {object} RenderContext
  196. * @property {Chunk} chunk the chunk
  197. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  198. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  199. * @property {ModuleGraph} moduleGraph the module graph
  200. * @property {ChunkGraph} chunkGraph the chunk graph
  201. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  202. * @property {boolean | undefined} strictMode rendering in strict context
  203. */
  204. /**
  205. * Defines the main render context type used by this module.
  206. * @typedef {object} MainRenderContext
  207. * @property {Chunk} chunk the chunk
  208. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  209. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  210. * @property {ModuleGraph} moduleGraph the module graph
  211. * @property {ChunkGraph} chunkGraph the chunk graph
  212. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  213. * @property {string} hash hash to be used for render call
  214. * @property {boolean | undefined} strictMode rendering in strict context
  215. */
  216. /**
  217. * Defines the chunk render context type used by this module.
  218. * @typedef {object} ChunkRenderContext
  219. * @property {Chunk} chunk the chunk
  220. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  221. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  222. * @property {ModuleGraph} moduleGraph the module graph
  223. * @property {ChunkGraph} chunkGraph the chunk graph
  224. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  225. * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
  226. * @property {boolean | undefined} strictMode rendering in strict context
  227. * @property {Module=} inlinedEntryModule entry module inlined at the chunk top level instead of the registry
  228. * @property {Source=} inlinedEntrySource rendered body of the inlined entry module
  229. */
  230. /**
  231. * Defines the render bootstrap context type used by this module.
  232. * @typedef {object} RenderBootstrapContext
  233. * @property {Chunk} chunk the chunk
  234. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  235. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  236. * @property {ModuleGraph} moduleGraph the module graph
  237. * @property {ChunkGraph} chunkGraph the chunk graph
  238. * @property {string} hash hash to be used for render call
  239. */
  240. /**
  241. * Defines the startup render context type used by this module.
  242. * @typedef {object} StartupRenderContext
  243. * @property {Chunk} chunk the chunk
  244. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  245. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  246. * @property {ModuleGraph} moduleGraph the module graph
  247. * @property {ChunkGraph} chunkGraph the chunk graph
  248. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  249. * @property {boolean | undefined} strictMode rendering in strict context
  250. * @property {boolean=} inlined inlined
  251. * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE
  252. * @property {boolean=} needExportsDeclaration whether the top-level exports declaration needs to be generated
  253. */
  254. /**
  255. * Defines the module render context type used by this module.
  256. * @typedef {object} ModuleRenderContext
  257. * @property {Chunk} chunk the chunk
  258. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  259. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  260. * @property {ModuleGraph} moduleGraph the module graph
  261. * @property {ChunkGraph} chunkGraph the chunk graph
  262. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  263. * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
  264. * @property {boolean | undefined} strictMode rendering in strict context
  265. * @property {boolean} factory true: renders as factory method, false: pure module content
  266. * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE, existing only when `factory` is set to false
  267. * @property {boolean=} renderInObject render module in object container
  268. */
  269. const createCompilationHooks = () => ({
  270. /**
  271. * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}
  272. */
  273. renderModuleContent: new SyncWaterfallHook([
  274. "source",
  275. "module",
  276. "moduleRenderContext"
  277. ]),
  278. /**
  279. * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}
  280. */
  281. renderModuleContainer: new SyncWaterfallHook([
  282. "source",
  283. "module",
  284. "moduleRenderContext"
  285. ]),
  286. /**
  287. * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}
  288. */
  289. renderModulePackage: new SyncWaterfallHook([
  290. "source",
  291. "module",
  292. "moduleRenderContext"
  293. ]),
  294. /**
  295. * @type {SyncWaterfallHook<[Source, RenderContext]>}
  296. */
  297. render: new SyncWaterfallHook(["source", "renderContext"]),
  298. /**
  299. * @type {SyncWaterfallHook<[Source, RenderContext]>}
  300. * @since 5.41.0
  301. */
  302. renderContent: new SyncWaterfallHook(["source", "renderContext"]),
  303. /**
  304. * @type {SyncWaterfallHook<[Source, Module, StartupRenderContext]>}
  305. * @since 5.22.0
  306. */
  307. renderStartup: new SyncWaterfallHook([
  308. "source",
  309. "module",
  310. "startupRenderContext"
  311. ]),
  312. /**
  313. * @type {SyncWaterfallHook<[Source, RenderContext]>}
  314. */
  315. renderChunk: new SyncWaterfallHook(["source", "renderContext"]),
  316. /**
  317. * @type {SyncWaterfallHook<[Source, RenderContext]>}
  318. */
  319. renderMain: new SyncWaterfallHook(["source", "renderContext"]),
  320. /**
  321. * @type {SyncWaterfallHook<[string, RenderBootstrapContext]>}
  322. */
  323. renderRequire: new SyncWaterfallHook(["code", "renderContext"]),
  324. /**
  325. * @type {SyncBailHook<[Module, Partial<RenderBootstrapContext>], string | void>}
  326. * @since 5.22.0
  327. */
  328. inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  329. /**
  330. * Offers a module's rendered export-definition call to a consumer that can place
  331. * it better — a library whose entry exports the same bindings natively takes it
  332. * over and emits it only where the module is wrapped. Return true to take it.
  333. * @type {SyncBailHook<[Module, RuntimeSpec, string, boolean], boolean | void>}
  334. */
  335. onDemandExportsGeneration: new SyncBailHook([
  336. "module",
  337. "runtime",
  338. "source",
  339. "placeAtEnd"
  340. ]),
  341. /**
  342. * @type {SyncBailHook<[Module, RenderContext], string | void>}
  343. * @since 5.22.0
  344. */
  345. embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  346. /**
  347. * @type {SyncBailHook<[RenderContext], string | void>}
  348. * @since 5.26.1
  349. */
  350. strictRuntimeBailout: new SyncBailHook(["renderContext"]),
  351. /**
  352. * @type {SyncHook<[Chunk, Hash, ChunkHashContext]>}
  353. */
  354. chunkHash: new SyncHook(["chunk", "hash", "context"]),
  355. /**
  356. * @type {SyncBailHook<[Chunk, RenderContext], boolean | void>}
  357. * @since 5.2.1
  358. */
  359. useSourceMap: new SyncBailHook(["chunk", "renderContext"])
  360. });
  361. /**
  362. * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks
  363. */
  364. /**
  365. * Renames an inlined module's top-level declaration (and all its references) when
  366. * its name is already taken in the shared startup scope, recording the chosen name
  367. * in `allUsedNames`. Lets inlined modules be emitted without a per-entry/per-chunk
  368. * IIFE by resolving name collisions instead of isolating each module.
  369. * @param {InstanceType<typeof import("webpack-sources").ReplaceSource>} source the module source to edit
  370. * @param {Program} ast the parsed module AST
  371. * @param {Variable} variable the top-level variable to check/rename
  372. * @param {string} moduleIdentifier the module identifier (for scope caching)
  373. * @param {string} readableIdentifier the readable module identifier (for new names)
  374. * @param {Set<string>} allUsedNames names already used in the shared scope (mutated)
  375. * @returns {void}
  376. */
  377. const renameInlinedModuleVariable = (
  378. source,
  379. ast,
  380. variable,
  381. moduleIdentifier,
  382. readableIdentifier,
  383. allUsedNames
  384. ) => {
  385. /** @type {UsedNamesInScopeInfo} */
  386. const usedNamesInScopeInfo = new Map();
  387. /** @type {ScopeSet} */
  388. const ignoredScopes = new Set();
  389. const name = variable.name;
  390. const { usedNames, alreadyCheckedScopes } = getUsedNamesInScopeInfo(
  391. usedNamesInScopeInfo,
  392. moduleIdentifier,
  393. name
  394. );
  395. if (allUsedNames.has(name) || usedNames.has(name)) {
  396. const references = getAllReferences(variable);
  397. const allIdentifiers = new Set([
  398. ...references.map((r) => r.identifier),
  399. ...variable.identifiers
  400. ]);
  401. for (const ref of references) {
  402. addScopeSymbols(ref.from, usedNames, alreadyCheckedScopes, ignoredScopes);
  403. }
  404. const newName = findNewName(
  405. name,
  406. allUsedNames,
  407. usedNames,
  408. readableIdentifier
  409. );
  410. allUsedNames.add(newName);
  411. for (const identifier of allIdentifiers) {
  412. const r = /** @type {Range} */ (identifier.range);
  413. const path = getPathInAst(ast, identifier);
  414. if (path && path.length > 1) {
  415. const maybeProperty =
  416. path[1].type === "AssignmentPattern" && path[1].left === path[0]
  417. ? path[2]
  418. : path[1];
  419. if (maybeProperty.type === "Property" && maybeProperty.shorthand) {
  420. source.insert(r[1], `: ${newName}`);
  421. continue;
  422. }
  423. }
  424. source.replace(r[0], r[1] - 1, newName);
  425. }
  426. }
  427. allUsedNames.add(name);
  428. };
  429. const PLUGIN_NAME = "JavascriptModulesPlugin";
  430. /** @typedef {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} Bootstrap */
  431. class JavascriptModulesPlugin {
  432. constructor(options = {}) {
  433. this.options = options;
  434. /** @type {WeakMap<Source, { source: Source, needModule: boolean, needExports: boolean, needRequire: boolean, needThisAsExports: boolean, needStrict: boolean | undefined, renderShorthand: boolean }>} */
  435. this._moduleFactoryCache = new WeakMap();
  436. }
  437. /**
  438. * Applies the plugin by registering its hooks on the compiler.
  439. * @param {Compiler} compiler the compiler instance
  440. * @returns {void}
  441. */
  442. apply(compiler) {
  443. compiler.hooks.compilation.tap(
  444. PLUGIN_NAME,
  445. (compilation, { normalModuleFactory }) => {
  446. const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
  447. for (const type of [
  448. JAVASCRIPT_MODULE_TYPE_AUTO,
  449. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  450. JAVASCRIPT_MODULE_TYPE_ESM
  451. ]) {
  452. normalModuleFactory.hooks.createModuleClass
  453. .for(type)
  454. .tap(
  455. PLUGIN_NAME,
  456. (createData, _resolveData) => new JavascriptModule(createData)
  457. );
  458. normalModuleFactory.hooks.createParser
  459. .for(type)
  460. .tap(PLUGIN_NAME, (options) => {
  461. switch (type) {
  462. case JAVASCRIPT_MODULE_TYPE_AUTO: {
  463. return new JavascriptParser("auto", {
  464. parse: options.parse,
  465. typescript: options.typescript,
  466. importPhases: Boolean(
  467. options.deferImport || options.sourceImport
  468. ),
  469. strictModeViolations: options.strictModeViolations
  470. });
  471. }
  472. case JAVASCRIPT_MODULE_TYPE_DYNAMIC: {
  473. return new JavascriptParser("script", {
  474. parse: options.parse,
  475. typescript: options.typescript,
  476. importPhases: Boolean(
  477. options.deferImport || options.sourceImport
  478. ),
  479. strictModeViolations: options.strictModeViolations
  480. });
  481. }
  482. case JAVASCRIPT_MODULE_TYPE_ESM: {
  483. return new JavascriptParser("module", {
  484. parse: options.parse,
  485. typescript: options.typescript,
  486. importPhases: Boolean(
  487. options.deferImport || options.sourceImport
  488. ),
  489. strictModeViolations: options.strictModeViolations
  490. });
  491. }
  492. }
  493. });
  494. normalModuleFactory.hooks.createGenerator
  495. .for(type)
  496. .tap(PLUGIN_NAME, () => new JavascriptGenerator());
  497. NormalModule.getCompilationHooks(compilation).processResult.tap(
  498. PLUGIN_NAME,
  499. (result, module) => {
  500. if (module.type === type) {
  501. const [source, ...rest] = result;
  502. return [removeBOM(source), ...rest];
  503. }
  504. return result;
  505. }
  506. );
  507. }
  508. compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
  509. const {
  510. hash,
  511. chunk,
  512. chunkGraph,
  513. moduleGraph,
  514. runtimeTemplate,
  515. dependencyTemplates,
  516. outputOptions,
  517. codeGenerationResults
  518. } = options;
  519. const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
  520. const filenameTemplate =
  521. JavascriptModulesPlugin.getChunkFilenameTemplate(
  522. chunk,
  523. outputOptions
  524. );
  525. /** @type {() => Source} */
  526. let render;
  527. if (hotUpdateChunk) {
  528. render = () =>
  529. this.renderChunk(
  530. {
  531. chunk,
  532. dependencyTemplates,
  533. runtimeTemplate,
  534. moduleGraph,
  535. chunkGraph,
  536. codeGenerationResults,
  537. strictMode: runtimeTemplate.isModule()
  538. },
  539. hooks
  540. );
  541. } else if (chunk.hasRuntime()) {
  542. if (!chunkHasRuntimeOrJs(chunk, chunkGraph)) {
  543. return result;
  544. }
  545. render = () =>
  546. this.renderMain(
  547. {
  548. hash,
  549. chunk,
  550. dependencyTemplates,
  551. runtimeTemplate,
  552. moduleGraph,
  553. chunkGraph,
  554. codeGenerationResults,
  555. strictMode: runtimeTemplate.isModule()
  556. },
  557. hooks,
  558. compilation
  559. );
  560. } else {
  561. if (!chunkHasJs(chunk, chunkGraph)) {
  562. return result;
  563. }
  564. render = () =>
  565. this.renderChunk(
  566. {
  567. chunk,
  568. dependencyTemplates,
  569. runtimeTemplate,
  570. moduleGraph,
  571. chunkGraph,
  572. codeGenerationResults,
  573. strictMode: runtimeTemplate.isModule()
  574. },
  575. hooks
  576. );
  577. }
  578. result.push({
  579. render,
  580. filenameTemplate,
  581. pathOptions: {
  582. hash,
  583. runtime: chunk.runtime,
  584. chunk,
  585. contentHashType: "javascript"
  586. },
  587. info: {
  588. javascriptModule: compilation.runtimeTemplate.isModule()
  589. },
  590. identifier: hotUpdateChunk
  591. ? `hotupdatechunk${chunk.id}`
  592. : `chunk${chunk.id}`,
  593. hash: chunk.contentHash.javascript
  594. });
  595. return result;
  596. });
  597. compilation.hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, context) => {
  598. hooks.chunkHash.call(chunk, hash, context);
  599. if (chunk.hasRuntime()) {
  600. this.updateHashWithBootstrap(
  601. hash,
  602. {
  603. hash: "0000",
  604. chunk,
  605. codeGenerationResults: context.codeGenerationResults,
  606. chunkGraph: context.chunkGraph,
  607. moduleGraph: context.moduleGraph,
  608. runtimeTemplate: context.runtimeTemplate
  609. },
  610. hooks
  611. );
  612. }
  613. });
  614. compilation.hooks.contentHash.tap(PLUGIN_NAME, (chunk) => {
  615. const {
  616. chunkGraph,
  617. moduleGraph,
  618. runtimeTemplate,
  619. outputOptions: {
  620. hashSalt,
  621. hashDigest,
  622. hashDigestLength,
  623. hashFunction
  624. }
  625. } = compilation;
  626. const codeGenerationResults =
  627. /** @type {CodeGenerationResults} */
  628. (compilation.codeGenerationResults);
  629. const hash = createHash(hashFunction);
  630. if (hashSalt) hash.update(hashSalt);
  631. if (chunk.hasRuntime()) {
  632. this.updateHashWithBootstrap(
  633. hash,
  634. {
  635. hash: "0000",
  636. chunk,
  637. codeGenerationResults,
  638. chunkGraph: compilation.chunkGraph,
  639. moduleGraph: compilation.moduleGraph,
  640. runtimeTemplate: compilation.runtimeTemplate
  641. },
  642. hooks
  643. );
  644. } else {
  645. hash.update(`${chunk.id} `);
  646. hash.update(chunk.ids ? chunk.ids.join(",") : "");
  647. }
  648. hooks.chunkHash.call(chunk, hash, {
  649. chunkGraph,
  650. codeGenerationResults,
  651. moduleGraph,
  652. runtimeTemplate
  653. });
  654. const modules = chunkGraph.getChunkModulesIterableBySourceType(
  655. chunk,
  656. JAVASCRIPT_TYPE
  657. );
  658. if (modules) {
  659. const xor = new StringXor();
  660. for (const m of modules) {
  661. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  662. }
  663. xor.updateHash(hash);
  664. }
  665. const runtimeModules = chunkGraph.getChunkModulesIterableBySourceType(
  666. chunk,
  667. WEBPACK_MODULE_TYPE_RUNTIME
  668. );
  669. if (runtimeModules) {
  670. const xor = new StringXor();
  671. for (const m of runtimeModules) {
  672. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  673. }
  674. xor.updateHash(hash);
  675. }
  676. [chunk.contentHash.javascript, chunk.contentHashFull.javascript] =
  677. digestNonNumericOnlyWithFull(hash, hashDigest, hashDigestLength);
  678. });
  679. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  680. PLUGIN_NAME,
  681. (chunk, set, { chunkGraph }) => {
  682. if (
  683. !set.has(RuntimeGlobals.startupNoDefault) &&
  684. chunkGraph.hasChunkEntryDependentChunks(chunk)
  685. ) {
  686. set.add(RuntimeGlobals.onChunksLoaded);
  687. set.add(RuntimeGlobals.exports);
  688. set.add(RuntimeGlobals.require);
  689. }
  690. }
  691. );
  692. compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
  693. const source =
  694. options.codeGenerationResult.sources.get(JAVASCRIPT_TYPE);
  695. if (source === undefined) return;
  696. const { module } = options;
  697. const code = source.source();
  698. /** @type {(this: ExecuteModuleObject["exports"], exports: ExecuteModuleObject["exports"], moduleObject: ExecuteModuleObject, webpackRequire: WebpackRequire) => void} */
  699. const fn = vm.runInThisContext(
  700. `(function(${module.moduleArgument}, ${module.exportsArgument}, ${RuntimeGlobals.require}) {\n${code}\n/**/})`,
  701. {
  702. filename: module.identifier(),
  703. lineOffset: -1
  704. }
  705. );
  706. const moduleObject =
  707. /** @type {ExecuteModuleObject} */
  708. (options.moduleObject);
  709. try {
  710. fn.call(
  711. moduleObject.exports,
  712. moduleObject,
  713. moduleObject.exports,
  714. /** @type {WebpackRequire} */
  715. (context.__webpack_require__)
  716. );
  717. } catch (err) {
  718. /** @type {Error} */
  719. (err).stack += printGeneratedCodeForStack(
  720. options.module,
  721. /** @type {string} */ (code)
  722. );
  723. throw err;
  724. }
  725. });
  726. compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => {
  727. const source = options.codeGenerationResult.sources.get("runtime");
  728. if (source === undefined) return;
  729. let code = source.source();
  730. if (typeof code !== "string") code = code.toString();
  731. /** @type {(this: null, webpackRequire: WebpackRequire) => void} */
  732. const fn = vm.runInThisContext(
  733. `(function(${RuntimeGlobals.require}) {\n${code}\n/**/})`,
  734. {
  735. filename: options.module.identifier(),
  736. lineOffset: -1
  737. }
  738. );
  739. try {
  740. // eslint-disable-next-line no-useless-call
  741. fn.call(
  742. null,
  743. /** @type {WebpackRequire} */
  744. (context.__webpack_require__)
  745. );
  746. } catch (err) {
  747. /** @type {Error} */
  748. (err).stack += printGeneratedCodeForStack(options.module, code);
  749. throw err;
  750. }
  751. });
  752. }
  753. );
  754. }
  755. /**
  756. * Gets chunk filename template.
  757. * @param {Chunk} chunk chunk
  758. * @param {OutputOptions} outputOptions output options
  759. * @returns {ChunkFilenameTemplate} used filename template
  760. */
  761. static getChunkFilenameTemplate(chunk, outputOptions) {
  762. if (chunk.filenameTemplate) {
  763. return chunk.filenameTemplate;
  764. } else if (chunk instanceof HotUpdateChunk) {
  765. return outputOptions.hotUpdateChunkFilename;
  766. }
  767. const entryOptions = chunk.getEntryOptions();
  768. // A worker entry (`new Worker` or `entry.worker`) uses workerChunkFilename;
  769. // chunks it loads internally keep `chunkFilename`
  770. if (entryOptions !== undefined && entryOptions.worker) {
  771. return outputOptions.workerChunkFilename;
  772. } else if (chunk.canBeInitial()) {
  773. return outputOptions.filename;
  774. }
  775. return outputOptions.chunkFilename;
  776. }
  777. /**
  778. * Renders the newly generated source from rendering.
  779. * @param {Module} module the rendered module
  780. * @param {ModuleRenderContext} renderContext options object
  781. * @param {CompilationHooks} hooks hooks
  782. * @returns {Source | null} the newly generated source from rendering
  783. */
  784. renderModule(module, renderContext, hooks) {
  785. const {
  786. chunk,
  787. chunkGraph,
  788. runtimeTemplate,
  789. codeGenerationResults,
  790. strictMode,
  791. factory,
  792. renderInObject
  793. } = renderContext;
  794. try {
  795. const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
  796. const moduleSource = codeGenResult.sources.get(JAVASCRIPT_TYPE);
  797. if (!moduleSource) return null;
  798. if (codeGenResult.data !== undefined) {
  799. const chunkInitFragments = codeGenResult.data.get("chunkInitFragments");
  800. if (chunkInitFragments) {
  801. for (const i of chunkInitFragments) {
  802. renderContext.chunkInitFragments.push(i);
  803. }
  804. }
  805. }
  806. const moduleSourcePostContent = tryRunOrWebpackError(
  807. () =>
  808. hooks.renderModuleContent.call(moduleSource, module, renderContext),
  809. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContent"
  810. );
  811. /** @type {Source} */
  812. let moduleSourcePostContainer;
  813. if (factory) {
  814. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  815. module,
  816. chunk.runtime
  817. );
  818. const needModule = runtimeRequirements.has(RuntimeGlobals.module);
  819. const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
  820. const needRequire =
  821. runtimeRequirements.has(RuntimeGlobals.require) ||
  822. runtimeRequirements.has(RuntimeGlobals.requireScope);
  823. const needThisAsExports = runtimeRequirements.has(
  824. RuntimeGlobals.thisAsExports
  825. );
  826. const needStrict =
  827. /** @type {BuildInfo} */
  828. (module.buildInfo).strict && !strictMode;
  829. const cacheEntry = this._moduleFactoryCache.get(
  830. moduleSourcePostContent
  831. );
  832. const renderShorthand =
  833. renderInObject === true && runtimeTemplate.supportsMethodShorthand();
  834. /** @type {Source} */
  835. let source;
  836. if (
  837. cacheEntry &&
  838. cacheEntry.needModule === needModule &&
  839. cacheEntry.needExports === needExports &&
  840. cacheEntry.needRequire === needRequire &&
  841. cacheEntry.needThisAsExports === needThisAsExports &&
  842. cacheEntry.needStrict === needStrict &&
  843. cacheEntry.renderShorthand === renderShorthand
  844. ) {
  845. source = cacheEntry.source;
  846. } else {
  847. const factorySource = new ConcatSource();
  848. /** @type {string[]} */
  849. const args = [];
  850. if (needExports || needRequire || needModule) {
  851. args.push(
  852. needModule
  853. ? module.moduleArgument
  854. : `__unused_webpack_${module.moduleArgument}`
  855. );
  856. }
  857. if (needExports || needRequire) {
  858. args.push(
  859. needExports
  860. ? module.exportsArgument
  861. : `__unused_webpack_${module.exportsArgument}`
  862. );
  863. }
  864. if (needRequire) args.push(RuntimeGlobals.require);
  865. if (renderShorthand) {
  866. // we can optimize function to methodShorthand if render module factory in object
  867. factorySource.add(`(${args.join(", ")}) {\n\n`);
  868. } else if (
  869. !needThisAsExports &&
  870. runtimeTemplate.supportsArrowFunction()
  871. ) {
  872. factorySource.add(`/***/ ((${args.join(", ")}) => {\n\n`);
  873. } else {
  874. factorySource.add(`/***/ (function(${args.join(", ")}) {\n\n`);
  875. }
  876. if (needStrict) {
  877. factorySource.add('"use strict";\n');
  878. }
  879. factorySource.add(moduleSourcePostContent);
  880. factorySource.add(`\n\n/***/ }${renderShorthand ? "" : ")"}`);
  881. source = new CachedSource(factorySource);
  882. this._moduleFactoryCache.set(moduleSourcePostContent, {
  883. source,
  884. needModule,
  885. needExports,
  886. needRequire,
  887. needThisAsExports,
  888. needStrict,
  889. renderShorthand
  890. });
  891. }
  892. moduleSourcePostContainer = tryRunOrWebpackError(
  893. () => hooks.renderModuleContainer.call(source, module, renderContext),
  894. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer"
  895. );
  896. } else {
  897. moduleSourcePostContainer = moduleSourcePostContent;
  898. }
  899. return tryRunOrWebpackError(
  900. () =>
  901. hooks.renderModulePackage.call(
  902. moduleSourcePostContainer,
  903. module,
  904. renderContext
  905. ),
  906. "JavascriptModulesPlugin.getCompilationHooks().renderModulePackage"
  907. );
  908. } catch (err) {
  909. /** @type {WebpackError} */
  910. (err).module = module;
  911. throw err;
  912. }
  913. }
  914. /**
  915. * Renders the rendered source.
  916. * @param {RenderContext} renderContext the render context
  917. * @param {CompilationHooks} hooks hooks
  918. * @returns {Source} the rendered source
  919. */
  920. renderChunk(renderContext, hooks) {
  921. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  922. const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
  923. chunk,
  924. JAVASCRIPT_TYPE,
  925. compareModulesByFullName(runtimeTemplate.compilation.compiler)
  926. );
  927. const allModules = modules ? [...modules] : [];
  928. /** @type {undefined | string} */
  929. let strictHeader;
  930. let allStrict = renderContext.strictMode;
  931. if (
  932. !allStrict &&
  933. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
  934. ) {
  935. const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
  936. strictHeader = strictBailout
  937. ? `// runtime can't be in strict mode because ${strictBailout}.\n`
  938. : '"use strict";\n';
  939. if (!strictBailout) allStrict = true;
  940. }
  941. /** @type {ChunkRenderContext} */
  942. const chunkRenderContext = {
  943. ...renderContext,
  944. chunkInitFragments: [],
  945. strictMode: allStrict
  946. };
  947. // ESM entry chunk whose runtime lives in a separate chunk: inline the
  948. // single entry module at the top level (instead of the module registry)
  949. // so its own top-level declarations stay live ESM bindings for consumers.
  950. const inlinedEntryModule = this._getEsmEntryModuleToInline(
  951. renderContext,
  952. allModules
  953. );
  954. let registryModules = allModules;
  955. if (inlinedEntryModule) {
  956. const inlinedEntrySource = this.renderModule(
  957. inlinedEntryModule,
  958. { ...chunkRenderContext, factory: false },
  959. hooks
  960. );
  961. if (inlinedEntrySource) {
  962. registryModules = allModules.filter((m) => m !== inlinedEntryModule);
  963. chunkRenderContext.inlinedEntryModule = inlinedEntryModule;
  964. chunkRenderContext.inlinedEntrySource = inlinedEntrySource;
  965. }
  966. }
  967. const moduleSources =
  968. Template.renderChunkModules(
  969. chunkRenderContext,
  970. registryModules,
  971. (module, renderInObject) =>
  972. this.renderModule(
  973. module,
  974. { ...chunkRenderContext, factory: true, renderInObject },
  975. hooks
  976. )
  977. ) || new RawSource("{}");
  978. let source = tryRunOrWebpackError(
  979. () => hooks.renderChunk.call(moduleSources, chunkRenderContext),
  980. "JavascriptModulesPlugin.getCompilationHooks().renderChunk"
  981. );
  982. source = tryRunOrWebpackError(
  983. () => hooks.renderContent.call(source, chunkRenderContext),
  984. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  985. );
  986. if (!source) {
  987. throw new Error(
  988. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  989. );
  990. }
  991. source = InitFragment.addToSource(
  992. source,
  993. chunkRenderContext.chunkInitFragments,
  994. chunkRenderContext
  995. );
  996. source = tryRunOrWebpackError(
  997. () => hooks.render.call(source, chunkRenderContext),
  998. "JavascriptModulesPlugin.getCompilationHooks().render"
  999. );
  1000. if (!source) {
  1001. throw new Error(
  1002. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  1003. );
  1004. }
  1005. chunk.rendered = true;
  1006. return strictHeader
  1007. ? new ConcatSource(strictHeader, source, ";")
  1008. : renderContext.runtimeTemplate.isModule()
  1009. ? source
  1010. : new ConcatSource(source, ";");
  1011. }
  1012. /**
  1013. * Returns the chunk's single entry module when it can be inlined at the top
  1014. * level of an ESM output chunk (instead of the module registry), which keeps
  1015. * its exports as live ESM bindings. Only a self-contained ESM entry whose
  1016. * top-level declarations can be lifted into the chunk scope qualifies;
  1017. * otherwise `undefined` is returned and the registry path is used.
  1018. * @param {RenderContext} renderContext render context
  1019. * @param {Module[]} allModules all javascript modules of the chunk
  1020. * @returns {Module | undefined} the entry module to inline, if any
  1021. */
  1022. _getEsmEntryModuleToInline(renderContext, allModules) {
  1023. const {
  1024. chunk,
  1025. chunkGraph,
  1026. moduleGraph,
  1027. runtimeTemplate,
  1028. codeGenerationResults
  1029. } = renderContext;
  1030. // Only a single ESM entry whose runtime lives in a separate chunk.
  1031. if (
  1032. !runtimeTemplate.isModule() ||
  1033. chunk.hasRuntime() ||
  1034. chunkGraph.getNumberOfEntryModules(chunk) !== 1
  1035. ) {
  1036. return undefined;
  1037. }
  1038. const [entryEntry] =
  1039. chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk);
  1040. const [entryModule, entrypoint] = /** @type {[Module, Entrypoint]} */ (
  1041. entryEntry
  1042. );
  1043. // Module-local safety: the body is lifted verbatim, so it must use the
  1044. // standard exports binding (not `module`/`this`) and expose top-level
  1045. // declarations whose names can't collide with runtime/startup identifiers.
  1046. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  1047. entryModule,
  1048. chunk.runtime
  1049. );
  1050. if (
  1051. entryModule.exportsArgument !== RuntimeGlobals.exports ||
  1052. runtimeRequirements.has(RuntimeGlobals.module) ||
  1053. runtimeRequirements.has(RuntimeGlobals.thisAsExports)
  1054. ) {
  1055. return undefined;
  1056. }
  1057. const topLevelDeclarations =
  1058. codeGenerationResults.getData(
  1059. entryModule,
  1060. chunk.runtime,
  1061. "topLevelDeclarations"
  1062. ) ||
  1063. (entryModule.buildInfo && entryModule.buildInfo.topLevelDeclarations);
  1064. if (!topLevelDeclarations || topLevelDeclarations.size === 0) {
  1065. return undefined;
  1066. }
  1067. for (const name of topLevelDeclarations) {
  1068. if (RESERVED_NAMES.has(name) || name.startsWith("__webpack_")) {
  1069. return undefined;
  1070. }
  1071. }
  1072. // Self-contained: the entry must not be imported by another module (which
  1073. // needs it in the registry), and must not require other chunks or
  1074. // `dependOn` parents to execute first.
  1075. if (
  1076. entrypoint.getParents().length > 0 ||
  1077. getAllChunks(entrypoint, chunk, entrypoint.getRuntimeChunk()).size > 0
  1078. ) {
  1079. return undefined;
  1080. }
  1081. const referenced = someInIterable(
  1082. moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
  1083. ([originModule, connections]) =>
  1084. originModule &&
  1085. originModule !== entryModule &&
  1086. connections.some((c) => c.isTargetActive(chunk.runtime)) &&
  1087. someInIterable(
  1088. chunkGraph.getModuleRuntimes(originModule),
  1089. (runtime) => intersectRuntime(runtime, chunk.runtime) !== undefined
  1090. )
  1091. );
  1092. return referenced ? undefined : entryModule;
  1093. }
  1094. /**
  1095. * Renders the newly generated source from rendering.
  1096. * @param {MainRenderContext} renderContext options object
  1097. * @param {CompilationHooks} hooks hooks
  1098. * @param {Compilation} compilation the compilation
  1099. * @returns {Source} the newly generated source from rendering
  1100. */
  1101. renderMain(renderContext, hooks, compilation) {
  1102. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  1103. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1104. const iife = runtimeTemplate.isIIFE();
  1105. const bootstrap = this.renderBootstrap(renderContext, hooks);
  1106. const useSourceMap = hooks.useSourceMap.call(chunk, renderContext);
  1107. /** @type {Module[]} */
  1108. const allModules = [
  1109. ...(chunkGraph.getOrderedChunkModulesIterableBySourceType(
  1110. chunk,
  1111. JAVASCRIPT_TYPE,
  1112. compareModulesByFullName(runtimeTemplate.compilation.compiler)
  1113. ) || [])
  1114. ];
  1115. const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0;
  1116. /** @type {Set<Module> | undefined} */
  1117. let inlinedModules;
  1118. if (bootstrap.allowInlineStartup && hasEntryModules) {
  1119. inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
  1120. }
  1121. const source = new ConcatSource();
  1122. /** @type {string} */
  1123. let prefix;
  1124. if (iife) {
  1125. if (runtimeTemplate.supportsArrowFunction()) {
  1126. source.add("/******/ (() => { // webpackBootstrap\n");
  1127. } else {
  1128. source.add("/******/ (function() { // webpackBootstrap\n");
  1129. }
  1130. prefix = "/******/ \t";
  1131. } else {
  1132. prefix = "/******/ ";
  1133. }
  1134. let allStrict = renderContext.strictMode;
  1135. if (
  1136. !allStrict &&
  1137. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict)
  1138. ) {
  1139. // a non-arrow bootstrap IIFE is called without a receiver, so in strict
  1140. // mode the `this` that `output.globalObject` reads would be undefined
  1141. const globalObjectNeedsThis =
  1142. iife &&
  1143. !runtimeTemplate.supportsArrowFunction() &&
  1144. runtimeTemplate.globalObjectUsesThis();
  1145. const strictBailout =
  1146. hooks.strictRuntimeBailout.call(renderContext) ||
  1147. (globalObjectNeedsThis
  1148. ? "'output.globalObject' reads 'this'"
  1149. : undefined);
  1150. if (strictBailout) {
  1151. source.add(
  1152. `${prefix}// runtime can't be in strict mode because ${strictBailout}.\n`
  1153. );
  1154. } else {
  1155. allStrict = true;
  1156. source.add(`${prefix}"use strict";\n`);
  1157. }
  1158. }
  1159. /** @type {ChunkRenderContext} */
  1160. const chunkRenderContext = {
  1161. ...renderContext,
  1162. chunkInitFragments: [],
  1163. strictMode: allStrict
  1164. };
  1165. const chunkModules = Template.renderChunkModules(
  1166. chunkRenderContext,
  1167. inlinedModules
  1168. ? allModules.filter(
  1169. (m) => !(/** @type {Set<Module>} */ (inlinedModules).has(m))
  1170. )
  1171. : allModules,
  1172. (module, renderInObject) =>
  1173. this.renderModule(
  1174. module,
  1175. { ...chunkRenderContext, factory: true, renderInObject },
  1176. hooks
  1177. ),
  1178. prefix
  1179. );
  1180. if (
  1181. chunkModules ||
  1182. runtimeRequirements.has(RuntimeGlobals.moduleFactories) ||
  1183. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) ||
  1184. runtimeRequirements.has(RuntimeGlobals.require)
  1185. ) {
  1186. source.add(`${prefix}var __webpack_modules__ = (`);
  1187. source.add(chunkModules || "{}");
  1188. source.add(");\n");
  1189. source.add(
  1190. "/************************************************************************/\n"
  1191. );
  1192. }
  1193. if (bootstrap.header.length > 0) {
  1194. const header = `${Template.asString(bootstrap.header)}\n`;
  1195. source.add(
  1196. new PrefixSource(
  1197. prefix,
  1198. useSourceMap
  1199. ? new OriginalSource(header, "webpack/bootstrap")
  1200. : new RawSource(header)
  1201. )
  1202. );
  1203. source.add(
  1204. "/************************************************************************/\n"
  1205. );
  1206. }
  1207. const runtimeModules =
  1208. renderContext.chunkGraph.getChunkRuntimeModulesInOrder(chunk);
  1209. if (runtimeModules.length > 0) {
  1210. source.add(
  1211. new PrefixSource(
  1212. prefix,
  1213. Template.renderRuntimeModules(runtimeModules, chunkRenderContext)
  1214. )
  1215. );
  1216. source.add(
  1217. "/************************************************************************/\n"
  1218. );
  1219. // runtimeRuntimeModules calls codeGeneration
  1220. for (const module of runtimeModules) {
  1221. compilation.codeGeneratedModules.add(module);
  1222. }
  1223. }
  1224. if (inlinedModules) {
  1225. if (bootstrap.beforeStartup.length > 0) {
  1226. const beforeStartup = `${Template.asString(bootstrap.beforeStartup)}\n`;
  1227. source.add(
  1228. new PrefixSource(
  1229. prefix,
  1230. useSourceMap
  1231. ? new OriginalSource(beforeStartup, "webpack/before-startup")
  1232. : new RawSource(beforeStartup)
  1233. )
  1234. );
  1235. }
  1236. const lastInlinedModule = /** @type {Module} */ (last(inlinedModules));
  1237. const startupSource = new ConcatSource();
  1238. const avoidEntryIife = compilation.options.optimization.avoidEntryIife;
  1239. /** @type {Map<Module, Source> | false} */
  1240. let renamedInlinedModule = false;
  1241. let inlinedInIIFE = false;
  1242. if (avoidEntryIife) {
  1243. renamedInlinedModule = this._getRenamedInlineModule(
  1244. compilation,
  1245. allModules,
  1246. renderContext,
  1247. inlinedModules,
  1248. chunkRenderContext,
  1249. hooks,
  1250. allStrict,
  1251. Boolean(chunkModules)
  1252. );
  1253. }
  1254. for (const m of inlinedModules) {
  1255. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  1256. m,
  1257. chunk.runtime
  1258. );
  1259. const exports = runtimeRequirements.has(RuntimeGlobals.exports);
  1260. const webpackExports =
  1261. exports && m.exportsArgument === RuntimeGlobals.exports;
  1262. const innerStrict =
  1263. !allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict;
  1264. const iife = innerStrict
  1265. ? "it needs to be in strict mode."
  1266. : inlinedModules.size > 1 && !renamedInlinedModule
  1267. ? "it needs to be isolated against other entry modules."
  1268. : chunkModules && !renamedInlinedModule
  1269. ? "it needs to be isolated against other modules in the chunk."
  1270. : exports && !webpackExports
  1271. ? `it uses a non-standard name for the exports (${m.exportsArgument}).`
  1272. : hooks.embedInRuntimeBailout.call(m, renderContext);
  1273. if (iife) {
  1274. inlinedInIIFE = true;
  1275. }
  1276. const renderedModule = renamedInlinedModule
  1277. ? renamedInlinedModule.get(m)
  1278. : this.renderModule(
  1279. m,
  1280. {
  1281. ...chunkRenderContext,
  1282. factory: false,
  1283. inlinedInIIFE
  1284. },
  1285. hooks
  1286. );
  1287. if (renderedModule) {
  1288. /** @type {string} */
  1289. let footer;
  1290. if (iife !== undefined) {
  1291. startupSource.add(
  1292. `// This entry needs to be wrapped in an IIFE because ${iife}\n`
  1293. );
  1294. const arrow = runtimeTemplate.supportsArrowFunction();
  1295. if (arrow) {
  1296. startupSource.add("(() => {\n");
  1297. footer = "\n})();\n\n";
  1298. } else {
  1299. startupSource.add("!function() {\n");
  1300. footer = "\n}();\n";
  1301. }
  1302. if (innerStrict) startupSource.add('"use strict";\n');
  1303. } else {
  1304. footer = "\n";
  1305. }
  1306. if (exports) {
  1307. if (m !== lastInlinedModule) {
  1308. startupSource.add(
  1309. `${runtimeTemplate.renderLet()} ${m.exportsArgument} = {};\n`
  1310. );
  1311. } else if (m.exportsArgument !== RuntimeGlobals.exports) {
  1312. startupSource.add(
  1313. `${runtimeTemplate.renderLet()} ${m.exportsArgument} = ${
  1314. RuntimeGlobals.exports
  1315. };\n`
  1316. );
  1317. }
  1318. }
  1319. startupSource.add(renderedModule);
  1320. startupSource.add(footer);
  1321. }
  1322. }
  1323. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  1324. startupSource.add(
  1325. `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});\n`
  1326. );
  1327. }
  1328. /** @type {StartupRenderContext} */
  1329. const startupRenderContext = {
  1330. ...renderContext,
  1331. inlined: true,
  1332. inlinedInIIFE,
  1333. needExportsDeclaration: runtimeRequirements.has(RuntimeGlobals.exports)
  1334. };
  1335. let renderedStartup = hooks.renderStartup.call(
  1336. startupSource,
  1337. lastInlinedModule,
  1338. startupRenderContext
  1339. );
  1340. const lastInlinedModuleRequirements =
  1341. chunkGraph.getModuleRuntimeRequirements(
  1342. lastInlinedModule,
  1343. chunk.runtime
  1344. );
  1345. if (
  1346. // `onChunksLoaded` reads and reassigns `__webpack_exports__`
  1347. runtimeRequirements.has(RuntimeGlobals.onChunksLoaded) ||
  1348. // Top-level `__webpack_exports__` will be returned
  1349. runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime) ||
  1350. // Custom exports argument aliases from `__webpack_exports__`
  1351. (lastInlinedModuleRequirements.has(RuntimeGlobals.exports) &&
  1352. lastInlinedModule.exportsArgument !== RuntimeGlobals.exports)
  1353. ) {
  1354. startupRenderContext.needExportsDeclaration = true;
  1355. }
  1356. if (startupRenderContext.needExportsDeclaration) {
  1357. renderedStartup = new ConcatSource(
  1358. `${runtimeTemplate.renderLet()} ${RuntimeGlobals.exports} = {};\n`,
  1359. renderedStartup
  1360. );
  1361. }
  1362. source.add(renderedStartup);
  1363. if (bootstrap.afterStartup.length > 0) {
  1364. const afterStartup = `${Template.asString(bootstrap.afterStartup)}\n`;
  1365. source.add(
  1366. new PrefixSource(
  1367. prefix,
  1368. useSourceMap
  1369. ? new OriginalSource(afterStartup, "webpack/after-startup")
  1370. : new RawSource(afterStartup)
  1371. )
  1372. );
  1373. }
  1374. } else {
  1375. const lastEntryModule =
  1376. /** @type {Module} */
  1377. (last(chunkGraph.getChunkEntryModulesIterable(chunk)));
  1378. /** @type {(content: string[], name: string) => Source} */
  1379. const toSource = useSourceMap
  1380. ? (content, name) =>
  1381. new OriginalSource(Template.asString(content), name)
  1382. : (content) => new RawSource(Template.asString(content));
  1383. source.add(
  1384. new PrefixSource(
  1385. prefix,
  1386. new ConcatSource(
  1387. toSource(bootstrap.beforeStartup, "webpack/before-startup"),
  1388. "\n",
  1389. hooks.renderStartup.call(
  1390. toSource([...bootstrap.startup, ""], "webpack/startup"),
  1391. lastEntryModule,
  1392. {
  1393. ...renderContext,
  1394. inlined: false,
  1395. needExportsDeclaration: true
  1396. }
  1397. ),
  1398. toSource(bootstrap.afterStartup, "webpack/after-startup"),
  1399. "\n"
  1400. )
  1401. )
  1402. );
  1403. }
  1404. if (
  1405. hasEntryModules &&
  1406. runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)
  1407. ) {
  1408. source.add(`${prefix}return ${RuntimeGlobals.exports};\n`);
  1409. }
  1410. if (iife) {
  1411. source.add("/******/ })()\n");
  1412. }
  1413. /** @type {Source} */
  1414. let finalSource = tryRunOrWebpackError(
  1415. () => hooks.renderMain.call(source, renderContext),
  1416. "JavascriptModulesPlugin.getCompilationHooks().renderMain"
  1417. );
  1418. if (!finalSource) {
  1419. throw new Error(
  1420. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something"
  1421. );
  1422. }
  1423. finalSource = tryRunOrWebpackError(
  1424. () => hooks.renderContent.call(finalSource, renderContext),
  1425. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  1426. );
  1427. if (!finalSource) {
  1428. throw new Error(
  1429. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  1430. );
  1431. }
  1432. finalSource = InitFragment.addToSource(
  1433. finalSource,
  1434. chunkRenderContext.chunkInitFragments,
  1435. chunkRenderContext
  1436. );
  1437. finalSource = tryRunOrWebpackError(
  1438. () => hooks.render.call(finalSource, renderContext),
  1439. "JavascriptModulesPlugin.getCompilationHooks().render"
  1440. );
  1441. if (!finalSource) {
  1442. throw new Error(
  1443. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  1444. );
  1445. }
  1446. chunk.rendered = true;
  1447. return iife ? new ConcatSource(finalSource, ";") : finalSource;
  1448. }
  1449. /**
  1450. * Updates hash with bootstrap.
  1451. * @param {Hash} hash the hash to be updated
  1452. * @param {RenderBootstrapContext} renderContext options object
  1453. * @param {CompilationHooks} hooks hooks
  1454. */
  1455. updateHashWithBootstrap(hash, renderContext, hooks) {
  1456. const bootstrap = this.renderBootstrap(renderContext, hooks);
  1457. for (const _k of Object.keys(bootstrap)) {
  1458. const key = /** @type {keyof Bootstrap} */ (_k);
  1459. hash.update(key);
  1460. if (Array.isArray(bootstrap[key])) {
  1461. for (const line of bootstrap[key]) {
  1462. hash.update(line);
  1463. }
  1464. } else {
  1465. hash.update(JSON.stringify(bootstrap[key]));
  1466. }
  1467. }
  1468. }
  1469. /**
  1470. * Renders the generated source of the bootstrap code.
  1471. * @param {RenderBootstrapContext} renderContext options object
  1472. * @param {CompilationHooks} hooks hooks
  1473. * @returns {Bootstrap} the generated source of the bootstrap code
  1474. */
  1475. renderBootstrap(renderContext, hooks) {
  1476. const {
  1477. chunkGraph,
  1478. codeGenerationResults,
  1479. moduleGraph,
  1480. chunk,
  1481. runtimeTemplate
  1482. } = renderContext;
  1483. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1484. const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
  1485. const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
  1486. const moduleFactories = runtimeRequirements.has(
  1487. RuntimeGlobals.moduleFactories
  1488. );
  1489. const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
  1490. const requireScopeUsed = runtimeRequirements.has(
  1491. RuntimeGlobals.requireScope
  1492. );
  1493. const interceptModuleExecution = runtimeRequirements.has(
  1494. RuntimeGlobals.interceptModuleExecution
  1495. );
  1496. const useRequire =
  1497. requireFunction || interceptModuleExecution || moduleUsed;
  1498. /**
  1499. * @type {{ startup: string[], beforeStartup: string[], header: string[], afterStartup: string[], allowInlineStartup: boolean }}
  1500. */
  1501. const result = {
  1502. header: [],
  1503. beforeStartup: [],
  1504. startup: [],
  1505. afterStartup: [],
  1506. allowInlineStartup: true
  1507. };
  1508. const { header: buf, startup, beforeStartup, afterStartup } = result;
  1509. if (result.allowInlineStartup && moduleFactories) {
  1510. startup.push(
  1511. "// module factories are used so entry inlining is disabled"
  1512. );
  1513. result.allowInlineStartup = false;
  1514. }
  1515. if (result.allowInlineStartup && moduleCache) {
  1516. startup.push("// module cache are used so entry inlining is disabled");
  1517. result.allowInlineStartup = false;
  1518. }
  1519. if (result.allowInlineStartup && interceptModuleExecution) {
  1520. startup.push(
  1521. "// module execution is intercepted so entry inlining is disabled"
  1522. );
  1523. result.allowInlineStartup = false;
  1524. }
  1525. const bootstrapCst = runtimeTemplate.renderConst();
  1526. if (useRequire || moduleCache) {
  1527. buf.push("// The module cache");
  1528. buf.push(`${bootstrapCst} __webpack_module_cache__ = {};`);
  1529. buf.push("");
  1530. }
  1531. if (runtimeRequirements.has(RuntimeGlobals.makeDeferredNamespaceObject)) {
  1532. // in order to optimize of DeferredNamespaceObject, we remove all proxy handlers after the module initialize
  1533. // (see MakeDeferredNamespaceObjectRuntimeModule)
  1534. // This requires all deferred imports to a module can get the module export object before the module
  1535. // is evaluated.
  1536. buf.push("// The deferred module cache");
  1537. buf.push(`${bootstrapCst} __webpack_module_deferred_exports__ = {};`);
  1538. // Per the TC39 import-defer spec, every defer-import call site for
  1539. // the same module must yield the same Deferred Module Namespace
  1540. // Exotic Object (and a distinct one from any eager namespace).
  1541. // Cache the deferred namespace proxy here so calls from different
  1542. // files share identity.
  1543. buf.push("// The deferred namespace cache");
  1544. buf.push(
  1545. `${bootstrapCst} __webpack_module_deferred_namespace_cache__ = {};`
  1546. );
  1547. buf.push("");
  1548. }
  1549. if (useRequire) {
  1550. buf.push("// The require function");
  1551. buf.push(`function ${RuntimeGlobals.require}(moduleId) {`);
  1552. buf.push(Template.indent(this.renderRequire(renderContext, hooks)));
  1553. buf.push("}");
  1554. buf.push("");
  1555. } else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
  1556. buf.push("// The require scope");
  1557. buf.push(`${bootstrapCst} ${RuntimeGlobals.require} = {};`);
  1558. buf.push("");
  1559. }
  1560. if (
  1561. moduleFactories ||
  1562. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
  1563. ) {
  1564. buf.push("// expose the modules object (__webpack_modules__)");
  1565. buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
  1566. buf.push("");
  1567. }
  1568. if (moduleCache) {
  1569. buf.push("// expose the module cache");
  1570. buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
  1571. buf.push("");
  1572. }
  1573. if (interceptModuleExecution) {
  1574. buf.push("// expose the module execution interceptor");
  1575. buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
  1576. buf.push("");
  1577. }
  1578. if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
  1579. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
  1580. /** @type {string[]} */
  1581. const buf2 = [];
  1582. const runtimeRequirements =
  1583. chunkGraph.getTreeRuntimeRequirements(chunk);
  1584. buf2.push("// Load entry module and return exports");
  1585. /** @type {EntryModuleWithChunkGroup[]} */
  1586. const jsEntries = [];
  1587. for (const [
  1588. entryModule,
  1589. entrypoint
  1590. ] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
  1591. if (
  1592. chunkGraph.getModuleSourceTypes(entryModule).has(JAVASCRIPT_TYPE)
  1593. ) {
  1594. jsEntries.push([entryModule, entrypoint]);
  1595. continue;
  1596. }
  1597. }
  1598. let i = jsEntries.length;
  1599. for (const [entryModule, entrypoint] of jsEntries) {
  1600. const chunks =
  1601. /** @type {Entrypoint} */
  1602. (entrypoint).chunks.filter((c) => c !== chunk);
  1603. if (result.allowInlineStartup && chunks.length > 0) {
  1604. buf2.push(
  1605. "// This entry module depends on other loaded chunks and execution need to be delayed"
  1606. );
  1607. result.allowInlineStartup = false;
  1608. }
  1609. if (
  1610. result.allowInlineStartup &&
  1611. someInIterable(
  1612. moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
  1613. ([originModule, connections]) =>
  1614. originModule &&
  1615. connections.some((c) => c.isTargetActive(chunk.runtime)) &&
  1616. someInIterable(
  1617. chunkGraph.getModuleRuntimes(originModule),
  1618. (runtime) =>
  1619. intersectRuntime(runtime, chunk.runtime) !== undefined
  1620. )
  1621. )
  1622. ) {
  1623. buf2.push(
  1624. "// This entry module is referenced by other modules so it can't be inlined"
  1625. );
  1626. result.allowInlineStartup = false;
  1627. }
  1628. /** @type {undefined | CodeGenerationResultData} */
  1629. let data;
  1630. if (codeGenerationResults.has(entryModule, chunk.runtime)) {
  1631. const result = codeGenerationResults.get(
  1632. entryModule,
  1633. chunk.runtime
  1634. );
  1635. data = result.data;
  1636. }
  1637. if (
  1638. result.allowInlineStartup &&
  1639. (!data || !data.get("topLevelDeclarations")) &&
  1640. (!entryModule.buildInfo ||
  1641. !entryModule.buildInfo.topLevelDeclarations)
  1642. ) {
  1643. buf2.push(
  1644. "// This entry module doesn't tell about it's top-level declarations so it can't be inlined"
  1645. );
  1646. result.allowInlineStartup = false;
  1647. }
  1648. if (result.allowInlineStartup) {
  1649. // the bail-out above already established that one of the two
  1650. // sources carries them
  1651. const topLevelDeclarations =
  1652. (data && data.get("topLevelDeclarations")) ||
  1653. /** @type {BuildInfo} */ (entryModule.buildInfo)
  1654. .topLevelDeclarations;
  1655. for (const name of CHUNK_RUNTIME_DECLARATIONS) {
  1656. if (/** @type {Set<string>} */ (topLevelDeclarations).has(name)) {
  1657. buf2.push(
  1658. `// This entry module declares '${name}' on top-level, which the runtime also declares, so it can't be inlined`
  1659. );
  1660. result.allowInlineStartup = false;
  1661. break;
  1662. }
  1663. }
  1664. }
  1665. if (result.allowInlineStartup) {
  1666. const bailout = hooks.inlineInRuntimeBailout.call(
  1667. entryModule,
  1668. renderContext
  1669. );
  1670. if (bailout !== undefined) {
  1671. buf2.push(
  1672. `// This entry module can't be inlined because ${bailout}`
  1673. );
  1674. result.allowInlineStartup = false;
  1675. }
  1676. }
  1677. i--;
  1678. const moduleId = chunkGraph.getModuleId(entryModule);
  1679. const entryRuntimeRequirements =
  1680. chunkGraph.getModuleRuntimeRequirements(entryModule, chunk.runtime);
  1681. let moduleIdExpr = JSON.stringify(moduleId);
  1682. if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
  1683. moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
  1684. }
  1685. if (
  1686. result.allowInlineStartup &&
  1687. entryRuntimeRequirements.has(RuntimeGlobals.module)
  1688. ) {
  1689. result.allowInlineStartup = false;
  1690. buf2.push(
  1691. "// This entry module used 'module' so it can't be inlined"
  1692. );
  1693. }
  1694. if (
  1695. result.allowInlineStartup &&
  1696. entryRuntimeRequirements.has(RuntimeGlobals.thisAsExports)
  1697. ) {
  1698. buf2.push(
  1699. "// This entry module used `this` as exports so it can't be inlined"
  1700. );
  1701. result.allowInlineStartup = false;
  1702. }
  1703. // `__webpack_exports__` may be reassigned later — by the
  1704. // `onChunksLoaded` wrapper below, by an inlined entry
  1705. // module that uses top-level `await` (the emitted
  1706. // bridge reassigns `__webpack_exports__` to the awaited
  1707. // value), or by other downstream codegen. Always declare
  1708. // with `let` (or `var` if `let` is unsupported) so
  1709. // reassignment is allowed.
  1710. const exportsDecl = runtimeTemplate.renderLet();
  1711. if (chunks.length > 0) {
  1712. buf2.push(
  1713. `${i === 0 ? `${exportsDecl} ${RuntimeGlobals.exports} = ` : ""}${
  1714. RuntimeGlobals.onChunksLoaded
  1715. }(undefined, ${JSON.stringify(
  1716. chunks.map((c) => c.id)
  1717. )}, ${runtimeTemplate.returningFunction(
  1718. `${RuntimeGlobals.require}(${moduleIdExpr})`
  1719. )})`
  1720. );
  1721. } else if (useRequire) {
  1722. buf2.push(
  1723. `${i === 0 ? `${exportsDecl} ${RuntimeGlobals.exports} = ` : ""}${
  1724. RuntimeGlobals.require
  1725. }(${moduleIdExpr});`
  1726. );
  1727. } else {
  1728. if (i === 0) {
  1729. buf2.push(`${exportsDecl} ${RuntimeGlobals.exports} = {};`);
  1730. }
  1731. const needThisAsExports = entryRuntimeRequirements.has(
  1732. RuntimeGlobals.thisAsExports
  1733. );
  1734. /** @type {string[]} */
  1735. const args = [];
  1736. if (
  1737. requireScopeUsed ||
  1738. entryRuntimeRequirements.has(RuntimeGlobals.exports)
  1739. ) {
  1740. const exportsArg = i === 0 ? RuntimeGlobals.exports : "{}";
  1741. args.push("0", exportsArg);
  1742. if (requireScopeUsed) {
  1743. args.push(RuntimeGlobals.require);
  1744. }
  1745. }
  1746. buf2.push(
  1747. Template.asString(
  1748. (() => {
  1749. if (needThisAsExports) {
  1750. const comma = args.length ? "," : "";
  1751. return `__webpack_modules__[${moduleIdExpr}].call(${
  1752. RuntimeGlobals.exports
  1753. }${comma}${args.join(",")});`;
  1754. }
  1755. return `__webpack_modules__[${moduleIdExpr}](${args.join(
  1756. ","
  1757. )});`;
  1758. })()
  1759. )
  1760. );
  1761. }
  1762. }
  1763. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  1764. buf2.push(
  1765. `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});`
  1766. );
  1767. }
  1768. if (
  1769. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1770. (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) &&
  1771. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter))
  1772. ) {
  1773. result.allowInlineStartup = false;
  1774. buf.push("// the startup function");
  1775. buf.push(
  1776. `${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction("", [
  1777. ...buf2,
  1778. `return ${RuntimeGlobals.exports};`
  1779. ])};`
  1780. );
  1781. buf.push("");
  1782. startup.push("// run startup");
  1783. startup.push(
  1784. `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
  1785. );
  1786. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) {
  1787. buf.push("// the startup function");
  1788. buf.push(
  1789. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1790. );
  1791. beforeStartup.push("// run runtime startup");
  1792. beforeStartup.push(`${RuntimeGlobals.startup}();`);
  1793. startup.push("// startup");
  1794. startup.push(Template.asString(buf2));
  1795. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)) {
  1796. buf.push("// the startup function");
  1797. buf.push(
  1798. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1799. );
  1800. startup.push("// startup");
  1801. startup.push(Template.asString(buf2));
  1802. afterStartup.push("// run runtime startup");
  1803. afterStartup.push(`${RuntimeGlobals.startup}();`);
  1804. } else {
  1805. startup.push("// startup");
  1806. startup.push(Template.asString(buf2));
  1807. }
  1808. } else if (
  1809. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1810. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1811. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1812. ) {
  1813. buf.push(
  1814. "// the startup function",
  1815. "// It's empty as no entry modules are in this chunk",
  1816. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`,
  1817. ""
  1818. );
  1819. }
  1820. } else if (
  1821. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1822. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1823. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1824. ) {
  1825. result.allowInlineStartup = false;
  1826. buf.push(
  1827. "// the startup function",
  1828. "// It's empty as some runtime module handles the default behavior",
  1829. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1830. );
  1831. startup.push("// run startup");
  1832. startup.push(
  1833. `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();`
  1834. );
  1835. }
  1836. return result;
  1837. }
  1838. /**
  1839. * Renders the generated source of the require function.
  1840. * @param {RenderBootstrapContext} renderContext options object
  1841. * @param {CompilationHooks} hooks hooks
  1842. * @returns {string} the generated source of the require function
  1843. */
  1844. renderRequire(renderContext, hooks) {
  1845. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  1846. const { outputOptions } = runtimeTemplate;
  1847. const cst = runtimeTemplate.renderConst();
  1848. const lt = runtimeTemplate.renderLet();
  1849. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1850. /**
  1851. * Renders missing module error.
  1852. * @param {string} condition guard expression
  1853. * @returns {string[]} source
  1854. */
  1855. const renderMissingModuleError = (condition) =>
  1856. outputOptions.strictModuleResolution
  1857. ? [
  1858. `if (${condition}) {`,
  1859. Template.indent([
  1860. "delete __webpack_module_cache__[moduleId];",
  1861. `${cst} e = new Error("Cannot find module '" + moduleId + "'");`,
  1862. "e.code = 'MODULE_NOT_FOUND';",
  1863. "throw e;"
  1864. ]),
  1865. "}"
  1866. ]
  1867. : [];
  1868. const moduleExecution = runtimeRequirements.has(
  1869. RuntimeGlobals.interceptModuleExecution
  1870. )
  1871. ? Template.asString([
  1872. `${cst} execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`,
  1873. `${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
  1874. ...renderMissingModuleError("!execOptions.factory"),
  1875. "module = execOptions.module;",
  1876. "execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
  1877. ])
  1878. : runtimeRequirements.has(RuntimeGlobals.thisAsExports)
  1879. ? Template.asString([
  1880. ...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
  1881. `__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});`
  1882. ])
  1883. : Template.asString([
  1884. ...renderMissingModuleError("!(moduleId in __webpack_modules__)"),
  1885. `__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});`
  1886. ]);
  1887. const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
  1888. const needModuleLoaded = runtimeRequirements.has(
  1889. RuntimeGlobals.moduleLoaded
  1890. );
  1891. const needModuleDefer = runtimeRequirements.has(
  1892. RuntimeGlobals.makeDeferredNamespaceObject
  1893. );
  1894. // Both deferred-namespace runtimes re-invoke `__webpack_require__` on
  1895. // access, so a module's evaluation error must be retained and re-thrown
  1896. // (a Cyclic Module Record's [[EvaluationError]]); the optimized variant
  1897. // does not use `__webpack_module_deferred_exports__`, so it is tracked
  1898. // separately from `needModuleDefer`.
  1899. const needModuleDeferAny =
  1900. needModuleDefer ||
  1901. runtimeRequirements.has(
  1902. RuntimeGlobals.makeOptimizedDeferredNamespaceObject
  1903. );
  1904. const needModuleErrorCaching =
  1905. outputOptions.strictModuleErrorHandling || needModuleDeferAny;
  1906. // `module` is reassigned by the interceptModuleExecution path; use `let`.
  1907. const moduleDecl = runtimeRequirements.has(
  1908. RuntimeGlobals.interceptModuleExecution
  1909. )
  1910. ? lt
  1911. : cst;
  1912. const content = Template.asString([
  1913. "// Check if module is in cache",
  1914. `${cst} cachedModule = __webpack_module_cache__[moduleId];`,
  1915. "if (cachedModule !== undefined) {",
  1916. needModuleErrorCaching
  1917. ? Template.indent([
  1918. "if (cachedModule.error !== undefined) throw cachedModule.error;",
  1919. "return cachedModule.exports;"
  1920. ])
  1921. : Template.indent("return cachedModule.exports;"),
  1922. "}",
  1923. "// Create a new module (and put it into the cache)",
  1924. `${moduleDecl} module = __webpack_module_cache__[moduleId] = {`,
  1925. Template.indent([
  1926. needModuleId ? "id: moduleId," : "// no module.id needed",
  1927. needModuleLoaded ? "loaded: false," : "// no module.loaded needed",
  1928. needModuleDefer
  1929. ? "exports: __webpack_module_deferred_exports__[moduleId] || {}"
  1930. : "exports: {}"
  1931. ]),
  1932. "};",
  1933. "",
  1934. outputOptions.strictModuleExceptionHandling && !needModuleErrorCaching
  1935. ? Template.asString([
  1936. "// Execute the module function",
  1937. `${lt} threw = true;`,
  1938. "try {",
  1939. Template.indent([
  1940. moduleExecution,
  1941. "threw = false;",
  1942. ...(needModuleDefer
  1943. ? ["delete __webpack_module_deferred_exports__[moduleId];"]
  1944. : [])
  1945. ]),
  1946. "} finally {",
  1947. Template.indent([
  1948. "if(threw) delete __webpack_module_cache__[moduleId];"
  1949. ]),
  1950. "}"
  1951. ])
  1952. : needModuleErrorCaching
  1953. ? Template.asString([
  1954. "// Execute the module function",
  1955. // Mark the module as evaluating so a deferred namespace that
  1956. // forces evaluation of an already-evaluating module can throw
  1957. // instead of exposing its partial exports.
  1958. ...(needModuleDeferAny ? ["module.evaluating = true;"] : []),
  1959. "try {",
  1960. Template.indent([
  1961. moduleExecution,
  1962. ...(needModuleDefer
  1963. ? ["delete __webpack_module_deferred_exports__[moduleId];"]
  1964. : []),
  1965. ...(needModuleDeferAny ? ["module.evaluating = false;"] : [])
  1966. ]),
  1967. "} catch(e) {",
  1968. Template.indent([
  1969. ...(needModuleDeferAny ? ["module.evaluating = false;"] : []),
  1970. "module.error = e;",
  1971. "throw e;"
  1972. ]),
  1973. "}"
  1974. ])
  1975. : Template.asString([
  1976. "// Execute the module function",
  1977. moduleExecution,
  1978. ...(needModuleDefer
  1979. ? ["delete __webpack_module_deferred_exports__[moduleId];"]
  1980. : [])
  1981. ]),
  1982. needModuleLoaded
  1983. ? Template.asString([
  1984. "",
  1985. "// Flag the module as loaded",
  1986. `${RuntimeGlobals.moduleLoaded} = true;`,
  1987. ""
  1988. ])
  1989. : "",
  1990. "// Return the exports of the module",
  1991. "return module.exports;"
  1992. ]);
  1993. return tryRunOrWebpackError(
  1994. () => hooks.renderRequire.call(content, renderContext),
  1995. "JavascriptModulesPlugin.getCompilationHooks().renderRequire"
  1996. );
  1997. }
  1998. /**
  1999. * Get renamed inline module.
  2000. * @param {Compilation} compilation compilation
  2001. * @param {Module[]} allModules allModules
  2002. * @param {MainRenderContext} renderContext renderContext
  2003. * @param {Set<Module>} inlinedModules inlinedModules
  2004. * @param {ChunkRenderContext} chunkRenderContext chunkRenderContext
  2005. * @param {CompilationHooks} hooks hooks
  2006. * @param {boolean | undefined} allStrict allStrict
  2007. * @param {boolean} hasChunkModules hasChunkModules
  2008. * @returns {Map<Module, Source> | false} renamed inlined modules
  2009. */
  2010. _getRenamedInlineModule(
  2011. compilation,
  2012. allModules,
  2013. renderContext,
  2014. inlinedModules,
  2015. chunkRenderContext,
  2016. hooks,
  2017. allStrict,
  2018. hasChunkModules
  2019. ) {
  2020. const innerStrict =
  2021. !allStrict &&
  2022. allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict);
  2023. const isMultipleEntries = inlinedModules.size > 1;
  2024. const singleEntryWithModules = inlinedModules.size === 1 && hasChunkModules;
  2025. // This step is before the IIFE reason calculation; it only runs for the
  2026. // cases whose IIFE reason it can remove: multiple inlined entry modules, or a
  2027. // single inlined entry alongside other chunk modules. The remaining reason
  2028. // ('it uses a non-standard name for the exports') is not handled here.
  2029. if (innerStrict || (!isMultipleEntries && !singleEntryWithModules)) {
  2030. return false;
  2031. }
  2032. /** @type {Map<Module, Source>} */
  2033. const renamedInlinedModules = new Map();
  2034. const { runtimeTemplate } = renderContext;
  2035. /** @typedef {{ source: Source, module: Module, ast: Program, variables: Set<Variable>, through: Set<Reference>, usedInNonInlined: Set<Variable>, moduleScope: Scope }} Info */
  2036. /** @type {Map<Module, Info>} */
  2037. const inlinedModulesToInfo = new Map();
  2038. /** @type {Set<string>} */
  2039. const nonInlinedModuleThroughIdentifiers = new Set();
  2040. /** @type {Map<Module, Source>} */
  2041. const inlinedModuleSources = new Map();
  2042. for (const m of allModules) {
  2043. const isInlinedModule = inlinedModules && inlinedModules.has(m);
  2044. const moduleSource = this.renderModule(
  2045. m,
  2046. {
  2047. ...chunkRenderContext,
  2048. factory: !isInlinedModule,
  2049. inlinedInIIFE: false
  2050. },
  2051. hooks
  2052. );
  2053. if (!moduleSource) continue;
  2054. if (isInlinedModule) {
  2055. // Parsing the inlined entry (often the whole concatenated app) is
  2056. // expensive; defer it until we know renaming is actually needed.
  2057. inlinedModuleSources.set(m, moduleSource);
  2058. continue;
  2059. }
  2060. const code = /** @type {string} */ (moduleSource.source());
  2061. const { experiments } = compilation.options;
  2062. const { ast } = JavascriptParser._parse(
  2063. code,
  2064. {
  2065. sourceType: "auto",
  2066. ranges: true,
  2067. // generated code contains phase imports when the experiments are on
  2068. importPhases: Boolean(
  2069. experiments.deferImport || experiments.sourceImport
  2070. )
  2071. },
  2072. JavascriptParser._getModuleParseFunction(compilation, m)
  2073. );
  2074. const analysis = analyzeScope(ast);
  2075. for (const ref of analysis.unresolvedReferences) {
  2076. nonInlinedModuleThroughIdentifiers.add(ref.identifier.name);
  2077. }
  2078. }
  2079. // Fast path: codegen reports each inlined entry's rendered top-level
  2080. // declarations and free names (post-concatenation), so when no declaration
  2081. // collides with a free name of any other module, another entry's
  2082. // declarations, or a reserved name, no renaming is needed and the entries
  2083. // don't have to be parsed at all.
  2084. fastPath: {
  2085. const { codeGenerationResults, chunk } = renderContext;
  2086. /** @type {Set<string>} */
  2087. const usedNames = new Set(nonInlinedModuleThroughIdentifiers);
  2088. for (const name of RESERVED_NAMES) usedNames.add(name);
  2089. /** @type {Set<string>[]} */
  2090. const declarationsList = [];
  2091. for (const m of inlinedModuleSources.keys()) {
  2092. if (!codeGenerationResults.has(m, chunk.runtime)) break fastPath;
  2093. const result = codeGenerationResults.get(m, chunk.runtime);
  2094. const data = result.data;
  2095. if (!data) break fastPath;
  2096. const declarations = data.get("topLevelDeclarations");
  2097. if (!declarations) break fastPath;
  2098. declarationsList.push(declarations);
  2099. if (!isMultipleEntries) continue;
  2100. // Entries share the startup scope: an entry's free names and runtime
  2101. // globals must not be shadowed by another entry's declarations.
  2102. const freeNames = data.get("freeNames");
  2103. if (!freeNames) break fastPath;
  2104. for (const name of freeNames) usedNames.add(name);
  2105. if (result.runtimeRequirements) {
  2106. for (const req of result.runtimeRequirements) {
  2107. const dot = req.indexOf(".");
  2108. usedNames.add(dot === -1 ? req : req.slice(0, dot));
  2109. }
  2110. }
  2111. }
  2112. for (const declarations of declarationsList) {
  2113. for (const name of declarations) {
  2114. if (usedNames.has(name)) break fastPath;
  2115. }
  2116. // earlier entries' declarations join the used set so later entries
  2117. // are checked against them
  2118. for (const name of declarations) usedNames.add(name);
  2119. }
  2120. for (const [m, moduleSource] of inlinedModuleSources) {
  2121. renamedInlinedModules.set(m, moduleSource);
  2122. }
  2123. return renamedInlinedModules;
  2124. }
  2125. for (const [m, moduleSource] of inlinedModuleSources) {
  2126. const code = /** @type {string} */ (moduleSource.source());
  2127. const { experiments } = compilation.options;
  2128. const { ast } = JavascriptParser._parse(
  2129. code,
  2130. {
  2131. sourceType: "auto",
  2132. ranges: true,
  2133. // generated code contains phase imports when the experiments are on
  2134. importPhases: Boolean(
  2135. experiments.deferImport || experiments.sourceImport
  2136. )
  2137. },
  2138. JavascriptParser._getModuleParseFunction(compilation, m)
  2139. );
  2140. const analysis = analyzeScope(ast);
  2141. const moduleScope = analysis.moduleScope;
  2142. inlinedModulesToInfo.set(m, {
  2143. source: moduleSource,
  2144. ast,
  2145. module: m,
  2146. variables: new Set(moduleScope.variables),
  2147. through: new Set(analysis.unresolvedReferences),
  2148. usedInNonInlined: new Set(),
  2149. moduleScope
  2150. });
  2151. }
  2152. for (const [, { variables, usedInNonInlined }] of inlinedModulesToInfo) {
  2153. for (const variable of variables) {
  2154. if (
  2155. nonInlinedModuleThroughIdentifiers.has(variable.name) ||
  2156. RESERVED_NAMES.has(variable.name)
  2157. ) {
  2158. usedInNonInlined.add(variable);
  2159. }
  2160. }
  2161. }
  2162. // Multiple inlined entry modules share the chunk's startup scope. Rename any
  2163. // top-level declaration that would collide with another inlined module's
  2164. // declaration, with any inlined or non-inlined module's free (global)
  2165. // reference, or with a reserved name, so the modules can be emitted without a
  2166. // per-entry IIFE.
  2167. if (isMultipleEntries) {
  2168. /** @type {Set<string>} */
  2169. const allUsedNames = new Set(nonInlinedModuleThroughIdentifiers);
  2170. for (const name of RESERVED_NAMES) allUsedNames.add(name);
  2171. for (const { through } of inlinedModulesToInfo.values()) {
  2172. for (const ref of through) allUsedNames.add(ref.identifier.name);
  2173. }
  2174. for (const [m, moduleInfo] of inlinedModulesToInfo) {
  2175. const { ast, source: _source } = moduleInfo;
  2176. const source = new ReplaceSource(_source);
  2177. for (const variable of moduleInfo.variables) {
  2178. renameInlinedModuleVariable(
  2179. source,
  2180. ast,
  2181. variable,
  2182. moduleInfo.module.identifier(),
  2183. m.readableIdentifier(runtimeTemplate.requestShortener),
  2184. allUsedNames
  2185. );
  2186. }
  2187. renamedInlinedModules.set(m, source);
  2188. }
  2189. return renamedInlinedModules;
  2190. }
  2191. for (const [m, moduleInfo] of inlinedModulesToInfo) {
  2192. const { ast, source: _source, usedInNonInlined } = moduleInfo;
  2193. const source = new ReplaceSource(_source);
  2194. if (usedInNonInlined.size === 0) {
  2195. renamedInlinedModules.set(m, source);
  2196. continue;
  2197. }
  2198. const info = /** @type {Info} */ (inlinedModulesToInfo.get(m));
  2199. const allUsedNames = new Set(
  2200. Array.from(info.through, (v) => v.identifier.name)
  2201. );
  2202. for (const variable of usedInNonInlined) {
  2203. allUsedNames.add(variable.name);
  2204. }
  2205. for (const variable of info.variables) {
  2206. renameInlinedModuleVariable(
  2207. source,
  2208. ast,
  2209. variable,
  2210. info.module.identifier(),
  2211. m.readableIdentifier(runtimeTemplate.requestShortener),
  2212. allUsedNames
  2213. );
  2214. }
  2215. renamedInlinedModules.set(m, source);
  2216. }
  2217. return renamedInlinedModules;
  2218. }
  2219. }
  2220. JavascriptModulesPlugin.getCompilationHooks = createHooksRegistry(
  2221. createCompilationHooks
  2222. );
  2223. JavascriptModulesPlugin.chunkHasJs = chunkHasJs;
  2224. module.exports = JavascriptModulesPlugin;