JavascriptModulesPlugin.js 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { SyncWaterfallHook, SyncHook, SyncBailHook } = require("tapable");
  7. const vm = require("vm");
  8. const {
  9. ConcatSource,
  10. OriginalSource,
  11. PrefixSource,
  12. RawSource,
  13. CachedSource
  14. } = require("webpack-sources");
  15. const Compilation = require("../Compilation");
  16. const { tryRunOrWebpackError } = require("../HookWebpackError");
  17. const HotUpdateChunk = require("../HotUpdateChunk");
  18. const InitFragment = require("../InitFragment");
  19. const RuntimeGlobals = require("../RuntimeGlobals");
  20. const Template = require("../Template");
  21. const { last, someInIterable } = require("../util/IterableHelpers");
  22. const StringXor = require("../util/StringXor");
  23. const { compareModulesByIdentifier } = require("../util/comparators");
  24. const createHash = require("../util/createHash");
  25. const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
  26. const { intersectRuntime } = require("../util/runtime");
  27. const JavascriptGenerator = require("./JavascriptGenerator");
  28. const JavascriptParser = require("./JavascriptParser");
  29. /** @typedef {import("webpack-sources").Source} Source */
  30. /** @typedef {import("../Chunk")} Chunk */
  31. /** @typedef {import("../ChunkGraph")} ChunkGraph */
  32. /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
  33. /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
  34. /** @typedef {import("../Compiler")} Compiler */
  35. /** @typedef {import("../DependencyTemplates")} DependencyTemplates */
  36. /** @typedef {import("../Module")} Module */
  37. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  38. /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
  39. /** @typedef {import("../util/Hash")} Hash */
  40. /**
  41. * @param {Chunk} chunk a chunk
  42. * @param {ChunkGraph} chunkGraph the chunk graph
  43. * @returns {boolean} true, when a JS file is needed for this chunk
  44. */
  45. const chunkHasJs = (chunk, chunkGraph) => {
  46. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) return true;
  47. return chunkGraph.getChunkModulesIterableBySourceType(chunk, "javascript")
  48. ? true
  49. : false;
  50. };
  51. const printGeneratedCodeForStack = (module, code) => {
  52. const lines = code.split("\n");
  53. const n = `${lines.length}`.length;
  54. return `\n\nGenerated code for ${module.identifier()}\n${lines
  55. .map((line, i, lines) => {
  56. const iStr = `${i + 1}`;
  57. return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`;
  58. })
  59. .join("\n")}`;
  60. };
  61. /**
  62. * @typedef {Object} RenderContext
  63. * @property {Chunk} chunk the chunk
  64. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  65. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  66. * @property {ModuleGraph} moduleGraph the module graph
  67. * @property {ChunkGraph} chunkGraph the chunk graph
  68. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  69. * @property {boolean} strictMode rendering in strict context
  70. */
  71. /**
  72. * @typedef {Object} MainRenderContext
  73. * @property {Chunk} chunk the chunk
  74. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  75. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  76. * @property {ModuleGraph} moduleGraph the module graph
  77. * @property {ChunkGraph} chunkGraph the chunk graph
  78. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  79. * @property {string} hash hash to be used for render call
  80. * @property {boolean} strictMode rendering in strict context
  81. */
  82. /**
  83. * @typedef {Object} ChunkRenderContext
  84. * @property {Chunk} chunk the chunk
  85. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  86. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  87. * @property {ModuleGraph} moduleGraph the module graph
  88. * @property {ChunkGraph} chunkGraph the chunk graph
  89. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  90. * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
  91. * @property {boolean} strictMode rendering in strict context
  92. */
  93. /**
  94. * @typedef {Object} RenderBootstrapContext
  95. * @property {Chunk} chunk the chunk
  96. * @property {CodeGenerationResults} codeGenerationResults results of code generation
  97. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  98. * @property {ModuleGraph} moduleGraph the module graph
  99. * @property {ChunkGraph} chunkGraph the chunk graph
  100. * @property {string} hash hash to be used for render call
  101. */
  102. /** @typedef {RenderContext & { inlined: boolean }} StartupRenderContext */
  103. /**
  104. * @typedef {Object} CompilationHooks
  105. * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContent
  106. * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContainer
  107. * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
  108. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
  109. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
  110. * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent
  111. * @property {SyncWaterfallHook<[Source, RenderContext]>} render
  112. * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup
  113. * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire
  114. * @property {SyncBailHook<[Module, RenderBootstrapContext], string>} inlineInRuntimeBailout
  115. * @property {SyncBailHook<[Module, RenderContext], string>} embedInRuntimeBailout
  116. * @property {SyncBailHook<[RenderContext], string>} strictRuntimeBailout
  117. * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
  118. * @property {SyncBailHook<[Chunk, RenderContext], boolean>} useSourceMap
  119. */
  120. /** @type {WeakMap<Compilation, CompilationHooks>} */
  121. const compilationHooksMap = new WeakMap();
  122. class JavascriptModulesPlugin {
  123. /**
  124. * @param {Compilation} compilation the compilation
  125. * @returns {CompilationHooks} the attached hooks
  126. */
  127. static getCompilationHooks(compilation) {
  128. if (!(compilation instanceof Compilation)) {
  129. throw new TypeError(
  130. "The 'compilation' argument must be an instance of Compilation"
  131. );
  132. }
  133. let hooks = compilationHooksMap.get(compilation);
  134. if (hooks === undefined) {
  135. hooks = {
  136. renderModuleContent: new SyncWaterfallHook([
  137. "source",
  138. "module",
  139. "renderContext"
  140. ]),
  141. renderModuleContainer: new SyncWaterfallHook([
  142. "source",
  143. "module",
  144. "renderContext"
  145. ]),
  146. renderModulePackage: new SyncWaterfallHook([
  147. "source",
  148. "module",
  149. "renderContext"
  150. ]),
  151. render: new SyncWaterfallHook(["source", "renderContext"]),
  152. renderContent: new SyncWaterfallHook(["source", "renderContext"]),
  153. renderStartup: new SyncWaterfallHook([
  154. "source",
  155. "module",
  156. "startupRenderContext"
  157. ]),
  158. renderChunk: new SyncWaterfallHook(["source", "renderContext"]),
  159. renderMain: new SyncWaterfallHook(["source", "renderContext"]),
  160. renderRequire: new SyncWaterfallHook(["code", "renderContext"]),
  161. inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  162. embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),
  163. strictRuntimeBailout: new SyncBailHook(["renderContext"]),
  164. chunkHash: new SyncHook(["chunk", "hash", "context"]),
  165. useSourceMap: new SyncBailHook(["chunk", "renderContext"])
  166. };
  167. compilationHooksMap.set(compilation, hooks);
  168. }
  169. return hooks;
  170. }
  171. constructor(options = {}) {
  172. this.options = options;
  173. /** @type {WeakMap<Source, TODO>} */
  174. this._moduleFactoryCache = new WeakMap();
  175. }
  176. /**
  177. * Apply the plugin
  178. * @param {Compiler} compiler the compiler instance
  179. * @returns {void}
  180. */
  181. apply(compiler) {
  182. compiler.hooks.compilation.tap(
  183. "JavascriptModulesPlugin",
  184. (compilation, { normalModuleFactory }) => {
  185. const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
  186. normalModuleFactory.hooks.createParser
  187. .for("javascript/auto")
  188. .tap("JavascriptModulesPlugin", options => {
  189. return new JavascriptParser("auto");
  190. });
  191. normalModuleFactory.hooks.createParser
  192. .for("javascript/dynamic")
  193. .tap("JavascriptModulesPlugin", options => {
  194. return new JavascriptParser("script");
  195. });
  196. normalModuleFactory.hooks.createParser
  197. .for("javascript/esm")
  198. .tap("JavascriptModulesPlugin", options => {
  199. return new JavascriptParser("module");
  200. });
  201. normalModuleFactory.hooks.createGenerator
  202. .for("javascript/auto")
  203. .tap("JavascriptModulesPlugin", () => {
  204. return new JavascriptGenerator();
  205. });
  206. normalModuleFactory.hooks.createGenerator
  207. .for("javascript/dynamic")
  208. .tap("JavascriptModulesPlugin", () => {
  209. return new JavascriptGenerator();
  210. });
  211. normalModuleFactory.hooks.createGenerator
  212. .for("javascript/esm")
  213. .tap("JavascriptModulesPlugin", () => {
  214. return new JavascriptGenerator();
  215. });
  216. compilation.hooks.renderManifest.tap(
  217. "JavascriptModulesPlugin",
  218. (result, options) => {
  219. const {
  220. hash,
  221. chunk,
  222. chunkGraph,
  223. moduleGraph,
  224. runtimeTemplate,
  225. dependencyTemplates,
  226. outputOptions,
  227. codeGenerationResults
  228. } = options;
  229. const hotUpdateChunk =
  230. chunk instanceof HotUpdateChunk ? chunk : null;
  231. let render;
  232. const filenameTemplate =
  233. JavascriptModulesPlugin.getChunkFilenameTemplate(
  234. chunk,
  235. outputOptions
  236. );
  237. if (hotUpdateChunk) {
  238. render = () =>
  239. this.renderChunk(
  240. {
  241. chunk,
  242. dependencyTemplates,
  243. runtimeTemplate,
  244. moduleGraph,
  245. chunkGraph,
  246. codeGenerationResults,
  247. strictMode: runtimeTemplate.isModule()
  248. },
  249. hooks
  250. );
  251. } else if (chunk.hasRuntime()) {
  252. render = () =>
  253. this.renderMain(
  254. {
  255. hash,
  256. chunk,
  257. dependencyTemplates,
  258. runtimeTemplate,
  259. moduleGraph,
  260. chunkGraph,
  261. codeGenerationResults,
  262. strictMode: runtimeTemplate.isModule()
  263. },
  264. hooks,
  265. compilation
  266. );
  267. } else {
  268. if (!chunkHasJs(chunk, chunkGraph)) {
  269. return result;
  270. }
  271. render = () =>
  272. this.renderChunk(
  273. {
  274. chunk,
  275. dependencyTemplates,
  276. runtimeTemplate,
  277. moduleGraph,
  278. chunkGraph,
  279. codeGenerationResults,
  280. strictMode: runtimeTemplate.isModule()
  281. },
  282. hooks
  283. );
  284. }
  285. result.push({
  286. render,
  287. filenameTemplate,
  288. pathOptions: {
  289. hash,
  290. runtime: chunk.runtime,
  291. chunk,
  292. contentHashType: "javascript"
  293. },
  294. info: {
  295. javascriptModule: compilation.runtimeTemplate.isModule()
  296. },
  297. identifier: hotUpdateChunk
  298. ? `hotupdatechunk${chunk.id}`
  299. : `chunk${chunk.id}`,
  300. hash: chunk.contentHash.javascript
  301. });
  302. return result;
  303. }
  304. );
  305. compilation.hooks.chunkHash.tap(
  306. "JavascriptModulesPlugin",
  307. (chunk, hash, context) => {
  308. hooks.chunkHash.call(chunk, hash, context);
  309. if (chunk.hasRuntime()) {
  310. this.updateHashWithBootstrap(
  311. hash,
  312. {
  313. hash: "0000",
  314. chunk,
  315. codeGenerationResults: context.codeGenerationResults,
  316. chunkGraph: context.chunkGraph,
  317. moduleGraph: context.moduleGraph,
  318. runtimeTemplate: context.runtimeTemplate
  319. },
  320. hooks
  321. );
  322. }
  323. }
  324. );
  325. compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => {
  326. const {
  327. chunkGraph,
  328. codeGenerationResults,
  329. moduleGraph,
  330. runtimeTemplate,
  331. outputOptions: {
  332. hashSalt,
  333. hashDigest,
  334. hashDigestLength,
  335. hashFunction
  336. }
  337. } = compilation;
  338. const hash = createHash(hashFunction);
  339. if (hashSalt) hash.update(hashSalt);
  340. if (chunk.hasRuntime()) {
  341. this.updateHashWithBootstrap(
  342. hash,
  343. {
  344. hash: "0000",
  345. chunk,
  346. codeGenerationResults,
  347. chunkGraph: compilation.chunkGraph,
  348. moduleGraph: compilation.moduleGraph,
  349. runtimeTemplate: compilation.runtimeTemplate
  350. },
  351. hooks
  352. );
  353. } else {
  354. hash.update(`${chunk.id} `);
  355. hash.update(chunk.ids ? chunk.ids.join(",") : "");
  356. }
  357. hooks.chunkHash.call(chunk, hash, {
  358. chunkGraph,
  359. codeGenerationResults,
  360. moduleGraph,
  361. runtimeTemplate
  362. });
  363. const modules = chunkGraph.getChunkModulesIterableBySourceType(
  364. chunk,
  365. "javascript"
  366. );
  367. if (modules) {
  368. const xor = new StringXor();
  369. for (const m of modules) {
  370. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  371. }
  372. xor.updateHash(hash);
  373. }
  374. const runtimeModules = chunkGraph.getChunkModulesIterableBySourceType(
  375. chunk,
  376. "runtime"
  377. );
  378. if (runtimeModules) {
  379. const xor = new StringXor();
  380. for (const m of runtimeModules) {
  381. xor.add(chunkGraph.getModuleHash(m, chunk.runtime));
  382. }
  383. xor.updateHash(hash);
  384. }
  385. const digest = /** @type {string} */ (hash.digest(hashDigest));
  386. chunk.contentHash.javascript = nonNumericOnlyHash(
  387. digest,
  388. hashDigestLength
  389. );
  390. });
  391. compilation.hooks.additionalTreeRuntimeRequirements.tap(
  392. "JavascriptModulesPlugin",
  393. (chunk, set, { chunkGraph }) => {
  394. if (
  395. !set.has(RuntimeGlobals.startupNoDefault) &&
  396. chunkGraph.hasChunkEntryDependentChunks(chunk)
  397. ) {
  398. set.add(RuntimeGlobals.onChunksLoaded);
  399. set.add(RuntimeGlobals.require);
  400. }
  401. }
  402. );
  403. compilation.hooks.executeModule.tap(
  404. "JavascriptModulesPlugin",
  405. (options, context) => {
  406. const source =
  407. options.codeGenerationResult.sources.get("javascript");
  408. if (source === undefined) return;
  409. const { module, moduleObject } = options;
  410. const code = source.source();
  411. const fn = vm.runInThisContext(
  412. `(function(${module.moduleArgument}, ${module.exportsArgument}, __webpack_require__) {\n${code}\n/**/})`,
  413. {
  414. filename: module.identifier(),
  415. lineOffset: -1
  416. }
  417. );
  418. try {
  419. fn.call(
  420. moduleObject.exports,
  421. moduleObject,
  422. moduleObject.exports,
  423. context.__webpack_require__
  424. );
  425. } catch (e) {
  426. e.stack += printGeneratedCodeForStack(options.module, code);
  427. throw e;
  428. }
  429. }
  430. );
  431. compilation.hooks.executeModule.tap(
  432. "JavascriptModulesPlugin",
  433. (options, context) => {
  434. const source = options.codeGenerationResult.sources.get("runtime");
  435. if (source === undefined) return;
  436. let code = source.source();
  437. if (typeof code !== "string") code = code.toString();
  438. const fn = vm.runInThisContext(
  439. `(function(__webpack_require__) {\n${code}\n/**/})`,
  440. {
  441. filename: options.module.identifier(),
  442. lineOffset: -1
  443. }
  444. );
  445. try {
  446. fn.call(null, context.__webpack_require__);
  447. } catch (e) {
  448. e.stack += printGeneratedCodeForStack(options.module, code);
  449. throw e;
  450. }
  451. }
  452. );
  453. }
  454. );
  455. }
  456. static getChunkFilenameTemplate(chunk, outputOptions) {
  457. if (chunk.filenameTemplate) {
  458. return chunk.filenameTemplate;
  459. } else if (chunk instanceof HotUpdateChunk) {
  460. return outputOptions.hotUpdateChunkFilename;
  461. } else if (chunk.canBeInitial()) {
  462. return outputOptions.filename;
  463. } else {
  464. return outputOptions.chunkFilename;
  465. }
  466. }
  467. /**
  468. * @param {Module} module the rendered module
  469. * @param {ChunkRenderContext} renderContext options object
  470. * @param {CompilationHooks} hooks hooks
  471. * @param {boolean} factory true: renders as factory method, false: pure module content
  472. * @returns {Source} the newly generated source from rendering
  473. */
  474. renderModule(module, renderContext, hooks, factory) {
  475. const {
  476. chunk,
  477. chunkGraph,
  478. runtimeTemplate,
  479. codeGenerationResults,
  480. strictMode
  481. } = renderContext;
  482. try {
  483. const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
  484. const moduleSource = codeGenResult.sources.get("javascript");
  485. if (!moduleSource) return null;
  486. if (codeGenResult.data !== undefined) {
  487. const chunkInitFragments = codeGenResult.data.get("chunkInitFragments");
  488. if (chunkInitFragments) {
  489. for (const i of chunkInitFragments)
  490. renderContext.chunkInitFragments.push(i);
  491. }
  492. }
  493. const moduleSourcePostContent = tryRunOrWebpackError(
  494. () =>
  495. hooks.renderModuleContent.call(moduleSource, module, renderContext),
  496. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContent"
  497. );
  498. let moduleSourcePostContainer;
  499. if (factory) {
  500. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  501. module,
  502. chunk.runtime
  503. );
  504. const needModule = runtimeRequirements.has(RuntimeGlobals.module);
  505. const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
  506. const needRequire =
  507. runtimeRequirements.has(RuntimeGlobals.require) ||
  508. runtimeRequirements.has(RuntimeGlobals.requireScope);
  509. const needThisAsExports = runtimeRequirements.has(
  510. RuntimeGlobals.thisAsExports
  511. );
  512. const needStrict = module.buildInfo.strict && !strictMode;
  513. const cacheEntry = this._moduleFactoryCache.get(
  514. moduleSourcePostContent
  515. );
  516. let source;
  517. if (
  518. cacheEntry &&
  519. cacheEntry.needModule === needModule &&
  520. cacheEntry.needExports === needExports &&
  521. cacheEntry.needRequire === needRequire &&
  522. cacheEntry.needThisAsExports === needThisAsExports &&
  523. cacheEntry.needStrict === needStrict
  524. ) {
  525. source = cacheEntry.source;
  526. } else {
  527. const factorySource = new ConcatSource();
  528. const args = [];
  529. if (needExports || needRequire || needModule)
  530. args.push(
  531. needModule
  532. ? module.moduleArgument
  533. : "__unused_webpack_" + module.moduleArgument
  534. );
  535. if (needExports || needRequire)
  536. args.push(
  537. needExports
  538. ? module.exportsArgument
  539. : "__unused_webpack_" + module.exportsArgument
  540. );
  541. if (needRequire) args.push("__webpack_require__");
  542. if (!needThisAsExports && runtimeTemplate.supportsArrowFunction()) {
  543. factorySource.add("/***/ ((" + args.join(", ") + ") => {\n\n");
  544. } else {
  545. factorySource.add("/***/ (function(" + args.join(", ") + ") {\n\n");
  546. }
  547. if (needStrict) {
  548. factorySource.add('"use strict";\n');
  549. }
  550. factorySource.add(moduleSourcePostContent);
  551. factorySource.add("\n\n/***/ })");
  552. source = new CachedSource(factorySource);
  553. this._moduleFactoryCache.set(moduleSourcePostContent, {
  554. source,
  555. needModule,
  556. needExports,
  557. needRequire,
  558. needThisAsExports,
  559. needStrict
  560. });
  561. }
  562. moduleSourcePostContainer = tryRunOrWebpackError(
  563. () => hooks.renderModuleContainer.call(source, module, renderContext),
  564. "JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer"
  565. );
  566. } else {
  567. moduleSourcePostContainer = moduleSourcePostContent;
  568. }
  569. return tryRunOrWebpackError(
  570. () =>
  571. hooks.renderModulePackage.call(
  572. moduleSourcePostContainer,
  573. module,
  574. renderContext
  575. ),
  576. "JavascriptModulesPlugin.getCompilationHooks().renderModulePackage"
  577. );
  578. } catch (e) {
  579. e.module = module;
  580. throw e;
  581. }
  582. }
  583. /**
  584. * @param {RenderContext} renderContext the render context
  585. * @param {CompilationHooks} hooks hooks
  586. * @returns {Source} the rendered source
  587. */
  588. renderChunk(renderContext, hooks) {
  589. const { chunk, chunkGraph } = renderContext;
  590. const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
  591. chunk,
  592. "javascript",
  593. compareModulesByIdentifier
  594. );
  595. const allModules = modules ? Array.from(modules) : [];
  596. let strictHeader;
  597. let allStrict = renderContext.strictMode;
  598. if (!allStrict && allModules.every(m => m.buildInfo.strict)) {
  599. const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
  600. strictHeader = strictBailout
  601. ? `// runtime can't be in strict mode because ${strictBailout}.\n`
  602. : '"use strict";\n';
  603. if (!strictBailout) allStrict = true;
  604. }
  605. /** @type {ChunkRenderContext} */
  606. const chunkRenderContext = {
  607. ...renderContext,
  608. chunkInitFragments: [],
  609. strictMode: allStrict
  610. };
  611. const moduleSources =
  612. Template.renderChunkModules(chunkRenderContext, allModules, module =>
  613. this.renderModule(module, chunkRenderContext, hooks, true)
  614. ) || new RawSource("{}");
  615. let source = tryRunOrWebpackError(
  616. () => hooks.renderChunk.call(moduleSources, chunkRenderContext),
  617. "JavascriptModulesPlugin.getCompilationHooks().renderChunk"
  618. );
  619. source = tryRunOrWebpackError(
  620. () => hooks.renderContent.call(source, chunkRenderContext),
  621. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  622. );
  623. if (!source) {
  624. throw new Error(
  625. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  626. );
  627. }
  628. source = InitFragment.addToSource(
  629. source,
  630. chunkRenderContext.chunkInitFragments,
  631. chunkRenderContext
  632. );
  633. source = tryRunOrWebpackError(
  634. () => hooks.render.call(source, chunkRenderContext),
  635. "JavascriptModulesPlugin.getCompilationHooks().render"
  636. );
  637. if (!source) {
  638. throw new Error(
  639. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  640. );
  641. }
  642. chunk.rendered = true;
  643. return strictHeader
  644. ? new ConcatSource(strictHeader, source, ";")
  645. : renderContext.runtimeTemplate.isModule()
  646. ? source
  647. : new ConcatSource(source, ";");
  648. }
  649. /**
  650. * @param {MainRenderContext} renderContext options object
  651. * @param {CompilationHooks} hooks hooks
  652. * @param {Compilation} compilation the compilation
  653. * @returns {Source} the newly generated source from rendering
  654. */
  655. renderMain(renderContext, hooks, compilation) {
  656. const { chunk, chunkGraph, runtimeTemplate } = renderContext;
  657. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  658. const iife = runtimeTemplate.isIIFE();
  659. const bootstrap = this.renderBootstrap(renderContext, hooks);
  660. const useSourceMap = hooks.useSourceMap.call(chunk, renderContext);
  661. const allModules = Array.from(
  662. chunkGraph.getOrderedChunkModulesIterableBySourceType(
  663. chunk,
  664. "javascript",
  665. compareModulesByIdentifier
  666. ) || []
  667. );
  668. const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0;
  669. let inlinedModules;
  670. if (bootstrap.allowInlineStartup && hasEntryModules) {
  671. inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
  672. }
  673. let source = new ConcatSource();
  674. let prefix;
  675. if (iife) {
  676. if (runtimeTemplate.supportsArrowFunction()) {
  677. source.add("/******/ (() => { // webpackBootstrap\n");
  678. } else {
  679. source.add("/******/ (function() { // webpackBootstrap\n");
  680. }
  681. prefix = "/******/ \t";
  682. } else {
  683. prefix = "/******/ ";
  684. }
  685. let allStrict = renderContext.strictMode;
  686. if (!allStrict && allModules.every(m => m.buildInfo.strict)) {
  687. const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
  688. if (strictBailout) {
  689. source.add(
  690. prefix +
  691. `// runtime can't be in strict mode because ${strictBailout}.\n`
  692. );
  693. } else {
  694. allStrict = true;
  695. source.add(prefix + '"use strict";\n');
  696. }
  697. }
  698. /** @type {ChunkRenderContext} */
  699. const chunkRenderContext = {
  700. ...renderContext,
  701. chunkInitFragments: [],
  702. strictMode: allStrict
  703. };
  704. const chunkModules = Template.renderChunkModules(
  705. chunkRenderContext,
  706. inlinedModules
  707. ? allModules.filter(m => !inlinedModules.has(m))
  708. : allModules,
  709. module => this.renderModule(module, chunkRenderContext, hooks, true),
  710. prefix
  711. );
  712. if (
  713. chunkModules ||
  714. runtimeRequirements.has(RuntimeGlobals.moduleFactories) ||
  715. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) ||
  716. runtimeRequirements.has(RuntimeGlobals.require)
  717. ) {
  718. source.add(prefix + "var __webpack_modules__ = (");
  719. source.add(chunkModules || "{}");
  720. source.add(");\n");
  721. source.add(
  722. "/************************************************************************/\n"
  723. );
  724. }
  725. if (bootstrap.header.length > 0) {
  726. const header = Template.asString(bootstrap.header) + "\n";
  727. source.add(
  728. new PrefixSource(
  729. prefix,
  730. useSourceMap
  731. ? new OriginalSource(header, "webpack/bootstrap")
  732. : new RawSource(header)
  733. )
  734. );
  735. source.add(
  736. "/************************************************************************/\n"
  737. );
  738. }
  739. const runtimeModules =
  740. renderContext.chunkGraph.getChunkRuntimeModulesInOrder(chunk);
  741. if (runtimeModules.length > 0) {
  742. source.add(
  743. new PrefixSource(
  744. prefix,
  745. Template.renderRuntimeModules(runtimeModules, chunkRenderContext)
  746. )
  747. );
  748. source.add(
  749. "/************************************************************************/\n"
  750. );
  751. // runtimeRuntimeModules calls codeGeneration
  752. for (const module of runtimeModules) {
  753. compilation.codeGeneratedModules.add(module);
  754. }
  755. }
  756. if (inlinedModules) {
  757. if (bootstrap.beforeStartup.length > 0) {
  758. const beforeStartup = Template.asString(bootstrap.beforeStartup) + "\n";
  759. source.add(
  760. new PrefixSource(
  761. prefix,
  762. useSourceMap
  763. ? new OriginalSource(beforeStartup, "webpack/before-startup")
  764. : new RawSource(beforeStartup)
  765. )
  766. );
  767. }
  768. const lastInlinedModule = last(inlinedModules);
  769. const startupSource = new ConcatSource();
  770. startupSource.add(`var __webpack_exports__ = {};\n`);
  771. for (const m of inlinedModules) {
  772. const renderedModule = this.renderModule(
  773. m,
  774. chunkRenderContext,
  775. hooks,
  776. false
  777. );
  778. if (renderedModule) {
  779. const innerStrict = !allStrict && m.buildInfo.strict;
  780. const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
  781. m,
  782. chunk.runtime
  783. );
  784. const exports = runtimeRequirements.has(RuntimeGlobals.exports);
  785. const webpackExports =
  786. exports && m.exportsArgument === "__webpack_exports__";
  787. let iife = innerStrict
  788. ? "it need to be in strict mode."
  789. : inlinedModules.size > 1
  790. ? // TODO check globals and top-level declarations of other entries and chunk modules
  791. // to make a better decision
  792. "it need to be isolated against other entry modules."
  793. : chunkModules
  794. ? "it need to be isolated against other modules in the chunk."
  795. : exports && !webpackExports
  796. ? `it uses a non-standard name for the exports (${m.exportsArgument}).`
  797. : hooks.embedInRuntimeBailout.call(m, renderContext);
  798. let footer;
  799. if (iife !== undefined) {
  800. startupSource.add(
  801. `// This entry need to be wrapped in an IIFE because ${iife}\n`
  802. );
  803. const arrow = runtimeTemplate.supportsArrowFunction();
  804. if (arrow) {
  805. startupSource.add("(() => {\n");
  806. footer = "\n})();\n\n";
  807. } else {
  808. startupSource.add("!function() {\n");
  809. footer = "\n}();\n";
  810. }
  811. if (innerStrict) startupSource.add('"use strict";\n');
  812. } else {
  813. footer = "\n";
  814. }
  815. if (exports) {
  816. if (m !== lastInlinedModule)
  817. startupSource.add(`var ${m.exportsArgument} = {};\n`);
  818. else if (m.exportsArgument !== "__webpack_exports__")
  819. startupSource.add(
  820. `var ${m.exportsArgument} = __webpack_exports__;\n`
  821. );
  822. }
  823. startupSource.add(renderedModule);
  824. startupSource.add(footer);
  825. }
  826. }
  827. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  828. startupSource.add(
  829. `__webpack_exports__ = ${RuntimeGlobals.onChunksLoaded}(__webpack_exports__);\n`
  830. );
  831. }
  832. source.add(
  833. hooks.renderStartup.call(startupSource, lastInlinedModule, {
  834. ...renderContext,
  835. inlined: true
  836. })
  837. );
  838. if (bootstrap.afterStartup.length > 0) {
  839. const afterStartup = Template.asString(bootstrap.afterStartup) + "\n";
  840. source.add(
  841. new PrefixSource(
  842. prefix,
  843. useSourceMap
  844. ? new OriginalSource(afterStartup, "webpack/after-startup")
  845. : new RawSource(afterStartup)
  846. )
  847. );
  848. }
  849. } else {
  850. const lastEntryModule = last(
  851. chunkGraph.getChunkEntryModulesIterable(chunk)
  852. );
  853. const toSource = useSourceMap
  854. ? (content, name) =>
  855. new OriginalSource(Template.asString(content), name)
  856. : content => new RawSource(Template.asString(content));
  857. source.add(
  858. new PrefixSource(
  859. prefix,
  860. new ConcatSource(
  861. toSource(bootstrap.beforeStartup, "webpack/before-startup"),
  862. "\n",
  863. hooks.renderStartup.call(
  864. toSource(bootstrap.startup.concat(""), "webpack/startup"),
  865. lastEntryModule,
  866. {
  867. ...renderContext,
  868. inlined: false
  869. }
  870. ),
  871. toSource(bootstrap.afterStartup, "webpack/after-startup"),
  872. "\n"
  873. )
  874. )
  875. );
  876. }
  877. if (
  878. hasEntryModules &&
  879. runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)
  880. ) {
  881. source.add(`${prefix}return __webpack_exports__;\n`);
  882. }
  883. if (iife) {
  884. source.add("/******/ })()\n");
  885. }
  886. /** @type {Source} */
  887. let finalSource = tryRunOrWebpackError(
  888. () => hooks.renderMain.call(source, renderContext),
  889. "JavascriptModulesPlugin.getCompilationHooks().renderMain"
  890. );
  891. if (!finalSource) {
  892. throw new Error(
  893. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something"
  894. );
  895. }
  896. finalSource = tryRunOrWebpackError(
  897. () => hooks.renderContent.call(finalSource, renderContext),
  898. "JavascriptModulesPlugin.getCompilationHooks().renderContent"
  899. );
  900. if (!finalSource) {
  901. throw new Error(
  902. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
  903. );
  904. }
  905. finalSource = InitFragment.addToSource(
  906. finalSource,
  907. chunkRenderContext.chunkInitFragments,
  908. chunkRenderContext
  909. );
  910. finalSource = tryRunOrWebpackError(
  911. () => hooks.render.call(finalSource, renderContext),
  912. "JavascriptModulesPlugin.getCompilationHooks().render"
  913. );
  914. if (!finalSource) {
  915. throw new Error(
  916. "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
  917. );
  918. }
  919. chunk.rendered = true;
  920. return iife ? new ConcatSource(finalSource, ";") : finalSource;
  921. }
  922. /**
  923. * @param {Hash} hash the hash to be updated
  924. * @param {RenderBootstrapContext} renderContext options object
  925. * @param {CompilationHooks} hooks hooks
  926. */
  927. updateHashWithBootstrap(hash, renderContext, hooks) {
  928. const bootstrap = this.renderBootstrap(renderContext, hooks);
  929. for (const key of Object.keys(bootstrap)) {
  930. hash.update(key);
  931. if (Array.isArray(bootstrap[key])) {
  932. for (const line of bootstrap[key]) {
  933. hash.update(line);
  934. }
  935. } else {
  936. hash.update(JSON.stringify(bootstrap[key]));
  937. }
  938. }
  939. }
  940. /**
  941. * @param {RenderBootstrapContext} renderContext options object
  942. * @param {CompilationHooks} hooks hooks
  943. * @returns {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} the generated source of the bootstrap code
  944. */
  945. renderBootstrap(renderContext, hooks) {
  946. const {
  947. chunkGraph,
  948. codeGenerationResults,
  949. moduleGraph,
  950. chunk,
  951. runtimeTemplate
  952. } = renderContext;
  953. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  954. const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
  955. const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
  956. const moduleFactories = runtimeRequirements.has(
  957. RuntimeGlobals.moduleFactories
  958. );
  959. const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
  960. const requireScopeUsed = runtimeRequirements.has(
  961. RuntimeGlobals.requireScope
  962. );
  963. const interceptModuleExecution = runtimeRequirements.has(
  964. RuntimeGlobals.interceptModuleExecution
  965. );
  966. const useRequire =
  967. requireFunction || interceptModuleExecution || moduleUsed;
  968. const result = {
  969. header: [],
  970. beforeStartup: [],
  971. startup: [],
  972. afterStartup: [],
  973. allowInlineStartup: true
  974. };
  975. let { header: buf, startup, beforeStartup, afterStartup } = result;
  976. if (result.allowInlineStartup && moduleFactories) {
  977. startup.push(
  978. "// module factories are used so entry inlining is disabled"
  979. );
  980. result.allowInlineStartup = false;
  981. }
  982. if (result.allowInlineStartup && moduleCache) {
  983. startup.push("// module cache are used so entry inlining is disabled");
  984. result.allowInlineStartup = false;
  985. }
  986. if (result.allowInlineStartup && interceptModuleExecution) {
  987. startup.push(
  988. "// module execution is intercepted so entry inlining is disabled"
  989. );
  990. result.allowInlineStartup = false;
  991. }
  992. if (useRequire || moduleCache) {
  993. buf.push("// The module cache");
  994. buf.push("var __webpack_module_cache__ = {};");
  995. buf.push("");
  996. }
  997. if (useRequire) {
  998. buf.push("// The require function");
  999. buf.push(`function __webpack_require__(moduleId) {`);
  1000. buf.push(Template.indent(this.renderRequire(renderContext, hooks)));
  1001. buf.push("}");
  1002. buf.push("");
  1003. } else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
  1004. buf.push("// The require scope");
  1005. buf.push("var __webpack_require__ = {};");
  1006. buf.push("");
  1007. }
  1008. if (
  1009. moduleFactories ||
  1010. runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
  1011. ) {
  1012. buf.push("// expose the modules object (__webpack_modules__)");
  1013. buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
  1014. buf.push("");
  1015. }
  1016. if (moduleCache) {
  1017. buf.push("// expose the module cache");
  1018. buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
  1019. buf.push("");
  1020. }
  1021. if (interceptModuleExecution) {
  1022. buf.push("// expose the module execution interceptor");
  1023. buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
  1024. buf.push("");
  1025. }
  1026. if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
  1027. if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
  1028. /** @type {string[]} */
  1029. const buf2 = [];
  1030. const runtimeRequirements =
  1031. chunkGraph.getTreeRuntimeRequirements(chunk);
  1032. buf2.push("// Load entry module and return exports");
  1033. let i = chunkGraph.getNumberOfEntryModules(chunk);
  1034. for (const [
  1035. entryModule,
  1036. entrypoint
  1037. ] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) {
  1038. const chunks = entrypoint.chunks.filter(c => c !== chunk);
  1039. if (result.allowInlineStartup && chunks.length > 0) {
  1040. buf2.push(
  1041. "// This entry module depends on other loaded chunks and execution need to be delayed"
  1042. );
  1043. result.allowInlineStartup = false;
  1044. }
  1045. if (
  1046. result.allowInlineStartup &&
  1047. someInIterable(
  1048. moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
  1049. ([originModule, connections]) =>
  1050. originModule &&
  1051. connections.some(c => c.isTargetActive(chunk.runtime)) &&
  1052. someInIterable(
  1053. chunkGraph.getModuleRuntimes(originModule),
  1054. runtime =>
  1055. intersectRuntime(runtime, chunk.runtime) !== undefined
  1056. )
  1057. )
  1058. ) {
  1059. buf2.push(
  1060. "// This entry module is referenced by other modules so it can't be inlined"
  1061. );
  1062. result.allowInlineStartup = false;
  1063. }
  1064. let data;
  1065. if (codeGenerationResults.has(entryModule, chunk.runtime)) {
  1066. const result = codeGenerationResults.get(
  1067. entryModule,
  1068. chunk.runtime
  1069. );
  1070. data = result.data;
  1071. }
  1072. if (
  1073. result.allowInlineStartup &&
  1074. (!data || !data.get("topLevelDeclarations")) &&
  1075. (!entryModule.buildInfo ||
  1076. !entryModule.buildInfo.topLevelDeclarations)
  1077. ) {
  1078. buf2.push(
  1079. "// This entry module doesn't tell about it's top-level declarations so it can't be inlined"
  1080. );
  1081. result.allowInlineStartup = false;
  1082. }
  1083. if (result.allowInlineStartup) {
  1084. const bailout = hooks.inlineInRuntimeBailout.call(
  1085. entryModule,
  1086. renderContext
  1087. );
  1088. if (bailout !== undefined) {
  1089. buf2.push(
  1090. `// This entry module can't be inlined because ${bailout}`
  1091. );
  1092. result.allowInlineStartup = false;
  1093. }
  1094. }
  1095. i--;
  1096. const moduleId = chunkGraph.getModuleId(entryModule);
  1097. const entryRuntimeRequirements =
  1098. chunkGraph.getModuleRuntimeRequirements(entryModule, chunk.runtime);
  1099. let moduleIdExpr = JSON.stringify(moduleId);
  1100. if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
  1101. moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
  1102. }
  1103. if (
  1104. result.allowInlineStartup &&
  1105. entryRuntimeRequirements.has(RuntimeGlobals.module)
  1106. ) {
  1107. result.allowInlineStartup = false;
  1108. buf2.push(
  1109. "// This entry module used 'module' so it can't be inlined"
  1110. );
  1111. }
  1112. if (chunks.length > 0) {
  1113. buf2.push(
  1114. `${i === 0 ? "var __webpack_exports__ = " : ""}${
  1115. RuntimeGlobals.onChunksLoaded
  1116. }(undefined, ${JSON.stringify(
  1117. chunks.map(c => c.id)
  1118. )}, ${runtimeTemplate.returningFunction(
  1119. `__webpack_require__(${moduleIdExpr})`
  1120. )})`
  1121. );
  1122. } else if (useRequire) {
  1123. buf2.push(
  1124. `${
  1125. i === 0 ? "var __webpack_exports__ = " : ""
  1126. }__webpack_require__(${moduleIdExpr});`
  1127. );
  1128. } else {
  1129. if (i === 0) buf2.push("var __webpack_exports__ = {};");
  1130. if (requireScopeUsed) {
  1131. buf2.push(
  1132. `__webpack_modules__[${moduleIdExpr}](0, ${
  1133. i === 0 ? "__webpack_exports__" : "{}"
  1134. }, __webpack_require__);`
  1135. );
  1136. } else if (entryRuntimeRequirements.has(RuntimeGlobals.exports)) {
  1137. buf2.push(
  1138. `__webpack_modules__[${moduleIdExpr}](0, ${
  1139. i === 0 ? "__webpack_exports__" : "{}"
  1140. });`
  1141. );
  1142. } else {
  1143. buf2.push(`__webpack_modules__[${moduleIdExpr}]();`);
  1144. }
  1145. }
  1146. }
  1147. if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
  1148. buf2.push(
  1149. `__webpack_exports__ = ${RuntimeGlobals.onChunksLoaded}(__webpack_exports__);`
  1150. );
  1151. }
  1152. if (
  1153. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1154. (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) &&
  1155. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter))
  1156. ) {
  1157. result.allowInlineStartup = false;
  1158. buf.push("// the startup function");
  1159. buf.push(
  1160. `${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction("", [
  1161. ...buf2,
  1162. "return __webpack_exports__;"
  1163. ])};`
  1164. );
  1165. buf.push("");
  1166. startup.push("// run startup");
  1167. startup.push(
  1168. `var __webpack_exports__ = ${RuntimeGlobals.startup}();`
  1169. );
  1170. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) {
  1171. buf.push("// the startup function");
  1172. buf.push(
  1173. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1174. );
  1175. beforeStartup.push("// run runtime startup");
  1176. beforeStartup.push(`${RuntimeGlobals.startup}();`);
  1177. startup.push("// startup");
  1178. startup.push(Template.asString(buf2));
  1179. } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)) {
  1180. buf.push("// the startup function");
  1181. buf.push(
  1182. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1183. );
  1184. startup.push("// startup");
  1185. startup.push(Template.asString(buf2));
  1186. afterStartup.push("// run runtime startup");
  1187. afterStartup.push(`${RuntimeGlobals.startup}();`);
  1188. } else {
  1189. startup.push("// startup");
  1190. startup.push(Template.asString(buf2));
  1191. }
  1192. } else if (
  1193. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1194. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1195. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1196. ) {
  1197. buf.push(
  1198. "// the startup function",
  1199. "// It's empty as no entry modules are in this chunk",
  1200. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`,
  1201. ""
  1202. );
  1203. }
  1204. } else if (
  1205. runtimeRequirements.has(RuntimeGlobals.startup) ||
  1206. runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore) ||
  1207. runtimeRequirements.has(RuntimeGlobals.startupOnlyAfter)
  1208. ) {
  1209. result.allowInlineStartup = false;
  1210. buf.push(
  1211. "// the startup function",
  1212. "// It's empty as some runtime module handles the default behavior",
  1213. `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
  1214. );
  1215. startup.push("// run startup");
  1216. startup.push(`var __webpack_exports__ = ${RuntimeGlobals.startup}();`);
  1217. }
  1218. return result;
  1219. }
  1220. /**
  1221. * @param {RenderBootstrapContext} renderContext options object
  1222. * @param {CompilationHooks} hooks hooks
  1223. * @returns {string} the generated source of the require function
  1224. */
  1225. renderRequire(renderContext, hooks) {
  1226. const {
  1227. chunk,
  1228. chunkGraph,
  1229. runtimeTemplate: { outputOptions }
  1230. } = renderContext;
  1231. const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
  1232. const moduleExecution = runtimeRequirements.has(
  1233. RuntimeGlobals.interceptModuleExecution
  1234. )
  1235. ? Template.asString([
  1236. "var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };",
  1237. `${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
  1238. "module = execOptions.module;",
  1239. "execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
  1240. ])
  1241. : runtimeRequirements.has(RuntimeGlobals.thisAsExports)
  1242. ? Template.asString([
  1243. "__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);"
  1244. ])
  1245. : Template.asString([
  1246. "__webpack_modules__[moduleId](module, module.exports, __webpack_require__);"
  1247. ]);
  1248. const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId);
  1249. const needModuleLoaded = runtimeRequirements.has(
  1250. RuntimeGlobals.moduleLoaded
  1251. );
  1252. const content = Template.asString([
  1253. "// Check if module is in cache",
  1254. "var cachedModule = __webpack_module_cache__[moduleId];",
  1255. "if (cachedModule !== undefined) {",
  1256. outputOptions.strictModuleErrorHandling
  1257. ? Template.indent([
  1258. "if (cachedModule.error !== undefined) throw cachedModule.error;",
  1259. "return cachedModule.exports;"
  1260. ])
  1261. : Template.indent("return cachedModule.exports;"),
  1262. "}",
  1263. "// Create a new module (and put it into the cache)",
  1264. "var module = __webpack_module_cache__[moduleId] = {",
  1265. Template.indent([
  1266. needModuleId ? "id: moduleId," : "// no module.id needed",
  1267. needModuleLoaded ? "loaded: false," : "// no module.loaded needed",
  1268. "exports: {}"
  1269. ]),
  1270. "};",
  1271. "",
  1272. outputOptions.strictModuleExceptionHandling
  1273. ? Template.asString([
  1274. "// Execute the module function",
  1275. "var threw = true;",
  1276. "try {",
  1277. Template.indent([moduleExecution, "threw = false;"]),
  1278. "} finally {",
  1279. Template.indent([
  1280. "if(threw) delete __webpack_module_cache__[moduleId];"
  1281. ]),
  1282. "}"
  1283. ])
  1284. : outputOptions.strictModuleErrorHandling
  1285. ? Template.asString([
  1286. "// Execute the module function",
  1287. "try {",
  1288. Template.indent(moduleExecution),
  1289. "} catch(e) {",
  1290. Template.indent(["module.error = e;", "throw e;"]),
  1291. "}"
  1292. ])
  1293. : Template.asString([
  1294. "// Execute the module function",
  1295. moduleExecution
  1296. ]),
  1297. needModuleLoaded
  1298. ? Template.asString([
  1299. "",
  1300. "// Flag the module as loaded",
  1301. "module.loaded = true;",
  1302. ""
  1303. ])
  1304. : "",
  1305. "// Return the exports of the module",
  1306. "return module.exports;"
  1307. ]);
  1308. return tryRunOrWebpackError(
  1309. () => hooks.renderRequire.call(content, renderContext),
  1310. "JavascriptModulesPlugin.getCompilationHooks().renderRequire"
  1311. );
  1312. }
  1313. }
  1314. module.exports = JavascriptModulesPlugin;
  1315. module.exports.chunkHasJs = chunkHasJs;