Module.js 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const util = require("util");
  7. const ChunkGraph = require("./ChunkGraph");
  8. const DependenciesBlock = require("./DependenciesBlock");
  9. const ModuleGraph = require("./ModuleGraph");
  10. const RuntimeGlobals = require("./RuntimeGlobals");
  11. const { first } = require("./util/SetHelpers");
  12. const { compareChunksById } = require("./util/comparators");
  13. const makeSerializable = require("./util/makeSerializable");
  14. /** @typedef {import("webpack-sources").Source} Source */
  15. /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
  16. /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
  17. /** @typedef {import("./Chunk")} Chunk */
  18. /** @typedef {import("./ChunkGroup")} ChunkGroup */
  19. /** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
  20. /** @typedef {import("./Compilation")} Compilation */
  21. /** @typedef {import("./ConcatenationScope")} ConcatenationScope */
  22. /** @typedef {import("./Dependency")} Dependency */
  23. /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
  24. /** @typedef {import("./DependencyTemplates")} DependencyTemplates */
  25. /** @typedef {import("./ExportsInfo").UsageStateType} UsageStateType */
  26. /** @typedef {import("./FileSystemInfo")} FileSystemInfo */
  27. /** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */
  28. /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
  29. /** @typedef {import("./RequestShortener")} RequestShortener */
  30. /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
  31. /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
  32. /** @typedef {import("./WebpackError")} WebpackError */
  33. /** @typedef {import("./util/Hash")} Hash */
  34. /** @template T @typedef {import("./util/LazySet")<T>} LazySet<T> */
  35. /** @template T @typedef {import("./util/SortableSet")<T>} SortableSet<T> */
  36. /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
  37. /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
  38. /**
  39. * @typedef {Object} SourceContext
  40. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  41. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  42. * @property {ModuleGraph} moduleGraph the module graph
  43. * @property {ChunkGraph} chunkGraph the chunk graph
  44. * @property {RuntimeSpec} runtime the runtimes code should be generated for
  45. * @property {string=} type the type of source that should be generated
  46. */
  47. /**
  48. * @typedef {Object} CodeGenerationContext
  49. * @property {DependencyTemplates} dependencyTemplates the dependency templates
  50. * @property {RuntimeTemplate} runtimeTemplate the runtime template
  51. * @property {ModuleGraph} moduleGraph the module graph
  52. * @property {ChunkGraph} chunkGraph the chunk graph
  53. * @property {RuntimeSpec} runtime the runtimes code should be generated for
  54. * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules
  55. * @property {CodeGenerationResults} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that)
  56. */
  57. /**
  58. * @typedef {Object} ConcatenationBailoutReasonContext
  59. * @property {ModuleGraph} moduleGraph the module graph
  60. * @property {ChunkGraph} chunkGraph the chunk graph
  61. */
  62. /**
  63. * @typedef {Object} CodeGenerationResult
  64. * @property {Map<string, Source>} sources the resulting sources for all source types
  65. * @property {Map<string, any>=} data the resulting data for all source types
  66. * @property {ReadonlySet<string>} runtimeRequirements the runtime requirements
  67. * @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
  68. */
  69. /**
  70. * @typedef {Object} LibIdentOptions
  71. * @property {string} context absolute context path to which lib ident is relative to
  72. * @property {Object=} associatedObjectForCache object for caching
  73. */
  74. /**
  75. * @typedef {Object} KnownBuildMeta
  76. * @property {string=} moduleArgument
  77. * @property {string=} exportsArgument
  78. * @property {boolean=} strict
  79. * @property {string=} moduleConcatenationBailout
  80. * @property {("default" | "namespace" | "flagged" | "dynamic")=} exportsType
  81. * @property {(false | "redirect" | "redirect-warn")=} defaultObject
  82. * @property {boolean=} strictHarmonyModule
  83. * @property {boolean=} async
  84. * @property {boolean=} sideEffectFree
  85. */
  86. /**
  87. * @typedef {Object} NeedBuildContext
  88. * @property {Compilation} compilation
  89. * @property {FileSystemInfo} fileSystemInfo
  90. * @property {Map<string, string | Set<string>>} valueCacheVersions
  91. */
  92. /** @typedef {KnownBuildMeta & Record<string, any>} BuildMeta */
  93. const EMPTY_RESOLVE_OPTIONS = {};
  94. let debugId = 1000;
  95. const DEFAULT_TYPES_UNKNOWN = new Set(["unknown"]);
  96. const DEFAULT_TYPES_JS = new Set(["javascript"]);
  97. const deprecatedNeedRebuild = util.deprecate(
  98. (module, context) => {
  99. return module.needRebuild(
  100. context.fileSystemInfo.getDeprecatedFileTimestamps(),
  101. context.fileSystemInfo.getDeprecatedContextTimestamps()
  102. );
  103. },
  104. "Module.needRebuild is deprecated in favor of Module.needBuild",
  105. "DEP_WEBPACK_MODULE_NEED_REBUILD"
  106. );
  107. /** @typedef {(requestShortener: RequestShortener) => string} OptimizationBailoutFunction */
  108. class Module extends DependenciesBlock {
  109. /**
  110. * @param {string} type the module type
  111. * @param {string=} context an optional context
  112. * @param {string=} layer an optional layer in which the module is
  113. */
  114. constructor(type, context = null, layer = null) {
  115. super();
  116. /** @type {string} */
  117. this.type = type;
  118. /** @type {string | null} */
  119. this.context = context;
  120. /** @type {string | null} */
  121. this.layer = layer;
  122. /** @type {boolean} */
  123. this.needId = true;
  124. // Unique Id
  125. /** @type {number} */
  126. this.debugId = debugId++;
  127. // Info from Factory
  128. /** @type {ResolveOptions} */
  129. this.resolveOptions = EMPTY_RESOLVE_OPTIONS;
  130. /** @type {object | undefined} */
  131. this.factoryMeta = undefined;
  132. // TODO refactor this -> options object filled from Factory
  133. // TODO webpack 6: use an enum
  134. /** @type {boolean} */
  135. this.useSourceMap = false;
  136. /** @type {boolean} */
  137. this.useSimpleSourceMap = false;
  138. // Info from Build
  139. /** @type {WebpackError[] | undefined} */
  140. this._warnings = undefined;
  141. /** @type {WebpackError[] | undefined} */
  142. this._errors = undefined;
  143. /** @type {BuildMeta} */
  144. this.buildMeta = undefined;
  145. /** @type {Record<string, any>} */
  146. this.buildInfo = undefined;
  147. /** @type {Dependency[] | undefined} */
  148. this.presentationalDependencies = undefined;
  149. /** @type {Dependency[] | undefined} */
  150. this.codeGenerationDependencies = undefined;
  151. }
  152. // TODO remove in webpack 6
  153. // BACKWARD-COMPAT START
  154. get id() {
  155. return ChunkGraph.getChunkGraphForModule(
  156. this,
  157. "Module.id",
  158. "DEP_WEBPACK_MODULE_ID"
  159. ).getModuleId(this);
  160. }
  161. set id(value) {
  162. if (value === "") {
  163. this.needId = false;
  164. return;
  165. }
  166. ChunkGraph.getChunkGraphForModule(
  167. this,
  168. "Module.id",
  169. "DEP_WEBPACK_MODULE_ID"
  170. ).setModuleId(this, value);
  171. }
  172. /**
  173. * @returns {string} the hash of the module
  174. */
  175. get hash() {
  176. return ChunkGraph.getChunkGraphForModule(
  177. this,
  178. "Module.hash",
  179. "DEP_WEBPACK_MODULE_HASH"
  180. ).getModuleHash(this, undefined);
  181. }
  182. /**
  183. * @returns {string} the shortened hash of the module
  184. */
  185. get renderedHash() {
  186. return ChunkGraph.getChunkGraphForModule(
  187. this,
  188. "Module.renderedHash",
  189. "DEP_WEBPACK_MODULE_RENDERED_HASH"
  190. ).getRenderedModuleHash(this, undefined);
  191. }
  192. get profile() {
  193. return ModuleGraph.getModuleGraphForModule(
  194. this,
  195. "Module.profile",
  196. "DEP_WEBPACK_MODULE_PROFILE"
  197. ).getProfile(this);
  198. }
  199. set profile(value) {
  200. ModuleGraph.getModuleGraphForModule(
  201. this,
  202. "Module.profile",
  203. "DEP_WEBPACK_MODULE_PROFILE"
  204. ).setProfile(this, value);
  205. }
  206. get index() {
  207. return ModuleGraph.getModuleGraphForModule(
  208. this,
  209. "Module.index",
  210. "DEP_WEBPACK_MODULE_INDEX"
  211. ).getPreOrderIndex(this);
  212. }
  213. set index(value) {
  214. ModuleGraph.getModuleGraphForModule(
  215. this,
  216. "Module.index",
  217. "DEP_WEBPACK_MODULE_INDEX"
  218. ).setPreOrderIndex(this, value);
  219. }
  220. get index2() {
  221. return ModuleGraph.getModuleGraphForModule(
  222. this,
  223. "Module.index2",
  224. "DEP_WEBPACK_MODULE_INDEX2"
  225. ).getPostOrderIndex(this);
  226. }
  227. set index2(value) {
  228. ModuleGraph.getModuleGraphForModule(
  229. this,
  230. "Module.index2",
  231. "DEP_WEBPACK_MODULE_INDEX2"
  232. ).setPostOrderIndex(this, value);
  233. }
  234. get depth() {
  235. return ModuleGraph.getModuleGraphForModule(
  236. this,
  237. "Module.depth",
  238. "DEP_WEBPACK_MODULE_DEPTH"
  239. ).getDepth(this);
  240. }
  241. set depth(value) {
  242. ModuleGraph.getModuleGraphForModule(
  243. this,
  244. "Module.depth",
  245. "DEP_WEBPACK_MODULE_DEPTH"
  246. ).setDepth(this, value);
  247. }
  248. get issuer() {
  249. return ModuleGraph.getModuleGraphForModule(
  250. this,
  251. "Module.issuer",
  252. "DEP_WEBPACK_MODULE_ISSUER"
  253. ).getIssuer(this);
  254. }
  255. set issuer(value) {
  256. ModuleGraph.getModuleGraphForModule(
  257. this,
  258. "Module.issuer",
  259. "DEP_WEBPACK_MODULE_ISSUER"
  260. ).setIssuer(this, value);
  261. }
  262. get usedExports() {
  263. return ModuleGraph.getModuleGraphForModule(
  264. this,
  265. "Module.usedExports",
  266. "DEP_WEBPACK_MODULE_USED_EXPORTS"
  267. ).getUsedExports(this, undefined);
  268. }
  269. /**
  270. * @deprecated
  271. * @returns {(string | OptimizationBailoutFunction)[]} list
  272. */
  273. get optimizationBailout() {
  274. return ModuleGraph.getModuleGraphForModule(
  275. this,
  276. "Module.optimizationBailout",
  277. "DEP_WEBPACK_MODULE_OPTIMIZATION_BAILOUT"
  278. ).getOptimizationBailout(this);
  279. }
  280. get optional() {
  281. return this.isOptional(
  282. ModuleGraph.getModuleGraphForModule(
  283. this,
  284. "Module.optional",
  285. "DEP_WEBPACK_MODULE_OPTIONAL"
  286. )
  287. );
  288. }
  289. addChunk(chunk) {
  290. const chunkGraph = ChunkGraph.getChunkGraphForModule(
  291. this,
  292. "Module.addChunk",
  293. "DEP_WEBPACK_MODULE_ADD_CHUNK"
  294. );
  295. if (chunkGraph.isModuleInChunk(this, chunk)) return false;
  296. chunkGraph.connectChunkAndModule(chunk, this);
  297. return true;
  298. }
  299. removeChunk(chunk) {
  300. return ChunkGraph.getChunkGraphForModule(
  301. this,
  302. "Module.removeChunk",
  303. "DEP_WEBPACK_MODULE_REMOVE_CHUNK"
  304. ).disconnectChunkAndModule(chunk, this);
  305. }
  306. isInChunk(chunk) {
  307. return ChunkGraph.getChunkGraphForModule(
  308. this,
  309. "Module.isInChunk",
  310. "DEP_WEBPACK_MODULE_IS_IN_CHUNK"
  311. ).isModuleInChunk(this, chunk);
  312. }
  313. isEntryModule() {
  314. return ChunkGraph.getChunkGraphForModule(
  315. this,
  316. "Module.isEntryModule",
  317. "DEP_WEBPACK_MODULE_IS_ENTRY_MODULE"
  318. ).isEntryModule(this);
  319. }
  320. getChunks() {
  321. return ChunkGraph.getChunkGraphForModule(
  322. this,
  323. "Module.getChunks",
  324. "DEP_WEBPACK_MODULE_GET_CHUNKS"
  325. ).getModuleChunks(this);
  326. }
  327. getNumberOfChunks() {
  328. return ChunkGraph.getChunkGraphForModule(
  329. this,
  330. "Module.getNumberOfChunks",
  331. "DEP_WEBPACK_MODULE_GET_NUMBER_OF_CHUNKS"
  332. ).getNumberOfModuleChunks(this);
  333. }
  334. get chunksIterable() {
  335. return ChunkGraph.getChunkGraphForModule(
  336. this,
  337. "Module.chunksIterable",
  338. "DEP_WEBPACK_MODULE_CHUNKS_ITERABLE"
  339. ).getOrderedModuleChunksIterable(this, compareChunksById);
  340. }
  341. /**
  342. * @param {string} exportName a name of an export
  343. * @returns {boolean | null} true, if the export is provided why the module.
  344. * null, if it's unknown.
  345. * false, if it's not provided.
  346. */
  347. isProvided(exportName) {
  348. return ModuleGraph.getModuleGraphForModule(
  349. this,
  350. "Module.usedExports",
  351. "DEP_WEBPACK_MODULE_USED_EXPORTS"
  352. ).isExportProvided(this, exportName);
  353. }
  354. // BACKWARD-COMPAT END
  355. /**
  356. * @returns {string} name of the exports argument
  357. */
  358. get exportsArgument() {
  359. return (this.buildInfo && this.buildInfo.exportsArgument) || "exports";
  360. }
  361. /**
  362. * @returns {string} name of the module argument
  363. */
  364. get moduleArgument() {
  365. return (this.buildInfo && this.buildInfo.moduleArgument) || "module";
  366. }
  367. /**
  368. * @param {ModuleGraph} moduleGraph the module graph
  369. * @param {boolean} strict the importing module is strict
  370. * @returns {"namespace" | "default-only" | "default-with-named" | "dynamic"} export type
  371. * "namespace": Exports is already a namespace object. namespace = exports.
  372. * "dynamic": Check at runtime if __esModule is set. When set: namespace = { ...exports, default: exports }. When not set: namespace = { default: exports }.
  373. * "default-only": Provide a namespace object with only default export. namespace = { default: exports }
  374. * "default-with-named": Provide a namespace object with named and default export. namespace = { ...exports, default: exports }
  375. */
  376. getExportsType(moduleGraph, strict) {
  377. switch (this.buildMeta && this.buildMeta.exportsType) {
  378. case "flagged":
  379. return strict ? "default-with-named" : "namespace";
  380. case "namespace":
  381. return "namespace";
  382. case "default":
  383. switch (this.buildMeta.defaultObject) {
  384. case "redirect":
  385. return "default-with-named";
  386. case "redirect-warn":
  387. return strict ? "default-only" : "default-with-named";
  388. default:
  389. return "default-only";
  390. }
  391. case "dynamic": {
  392. if (strict) return "default-with-named";
  393. // Try to figure out value of __esModule by following reexports
  394. const handleDefault = () => {
  395. switch (this.buildMeta.defaultObject) {
  396. case "redirect":
  397. case "redirect-warn":
  398. return "default-with-named";
  399. default:
  400. return "default-only";
  401. }
  402. };
  403. const exportInfo = moduleGraph.getReadOnlyExportInfo(
  404. this,
  405. "__esModule"
  406. );
  407. if (exportInfo.provided === false) {
  408. return handleDefault();
  409. }
  410. const target = exportInfo.getTarget(moduleGraph);
  411. if (
  412. !target ||
  413. !target.export ||
  414. target.export.length !== 1 ||
  415. target.export[0] !== "__esModule"
  416. ) {
  417. return "dynamic";
  418. }
  419. switch (
  420. target.module.buildMeta &&
  421. target.module.buildMeta.exportsType
  422. ) {
  423. case "flagged":
  424. case "namespace":
  425. return "namespace";
  426. case "default":
  427. return handleDefault();
  428. default:
  429. return "dynamic";
  430. }
  431. }
  432. default:
  433. return strict ? "default-with-named" : "dynamic";
  434. }
  435. }
  436. /**
  437. * @param {Dependency} presentationalDependency dependency being tied to module.
  438. * This is a Dependency without edge in the module graph. It's only for presentation.
  439. * @returns {void}
  440. */
  441. addPresentationalDependency(presentationalDependency) {
  442. if (this.presentationalDependencies === undefined) {
  443. this.presentationalDependencies = [];
  444. }
  445. this.presentationalDependencies.push(presentationalDependency);
  446. }
  447. /**
  448. * @param {Dependency} codeGenerationDependency dependency being tied to module.
  449. * This is a Dependency where the code generation result of the referenced module is needed during code generation.
  450. * The Dependency should also be added to normal dependencies via addDependency.
  451. * @returns {void}
  452. */
  453. addCodeGenerationDependency(codeGenerationDependency) {
  454. if (this.codeGenerationDependencies === undefined) {
  455. this.codeGenerationDependencies = [];
  456. }
  457. this.codeGenerationDependencies.push(codeGenerationDependency);
  458. }
  459. /**
  460. * Removes all dependencies and blocks
  461. * @returns {void}
  462. */
  463. clearDependenciesAndBlocks() {
  464. if (this.presentationalDependencies !== undefined) {
  465. this.presentationalDependencies.length = 0;
  466. }
  467. if (this.codeGenerationDependencies !== undefined) {
  468. this.codeGenerationDependencies.length = 0;
  469. }
  470. super.clearDependenciesAndBlocks();
  471. }
  472. /**
  473. * @param {WebpackError} warning the warning
  474. * @returns {void}
  475. */
  476. addWarning(warning) {
  477. if (this._warnings === undefined) {
  478. this._warnings = [];
  479. }
  480. this._warnings.push(warning);
  481. }
  482. /**
  483. * @returns {Iterable<WebpackError> | undefined} list of warnings if any
  484. */
  485. getWarnings() {
  486. return this._warnings;
  487. }
  488. /**
  489. * @returns {number} number of warnings
  490. */
  491. getNumberOfWarnings() {
  492. return this._warnings !== undefined ? this._warnings.length : 0;
  493. }
  494. /**
  495. * @param {WebpackError} error the error
  496. * @returns {void}
  497. */
  498. addError(error) {
  499. if (this._errors === undefined) {
  500. this._errors = [];
  501. }
  502. this._errors.push(error);
  503. }
  504. /**
  505. * @returns {Iterable<WebpackError> | undefined} list of errors if any
  506. */
  507. getErrors() {
  508. return this._errors;
  509. }
  510. /**
  511. * @returns {number} number of errors
  512. */
  513. getNumberOfErrors() {
  514. return this._errors !== undefined ? this._errors.length : 0;
  515. }
  516. /**
  517. * removes all warnings and errors
  518. * @returns {void}
  519. */
  520. clearWarningsAndErrors() {
  521. if (this._warnings !== undefined) {
  522. this._warnings.length = 0;
  523. }
  524. if (this._errors !== undefined) {
  525. this._errors.length = 0;
  526. }
  527. }
  528. /**
  529. * @param {ModuleGraph} moduleGraph the module graph
  530. * @returns {boolean} true, if the module is optional
  531. */
  532. isOptional(moduleGraph) {
  533. let hasConnections = false;
  534. for (const r of moduleGraph.getIncomingConnections(this)) {
  535. if (
  536. !r.dependency ||
  537. !r.dependency.optional ||
  538. !r.isTargetActive(undefined)
  539. ) {
  540. return false;
  541. }
  542. hasConnections = true;
  543. }
  544. return hasConnections;
  545. }
  546. /**
  547. * @param {ChunkGraph} chunkGraph the chunk graph
  548. * @param {Chunk} chunk a chunk
  549. * @param {Chunk=} ignoreChunk chunk to be ignored
  550. * @returns {boolean} true, if the module is accessible from "chunk" when ignoring "ignoreChunk"
  551. */
  552. isAccessibleInChunk(chunkGraph, chunk, ignoreChunk) {
  553. // Check if module is accessible in ALL chunk groups
  554. for (const chunkGroup of chunk.groupsIterable) {
  555. if (!this.isAccessibleInChunkGroup(chunkGraph, chunkGroup)) return false;
  556. }
  557. return true;
  558. }
  559. /**
  560. * @param {ChunkGraph} chunkGraph the chunk graph
  561. * @param {ChunkGroup} chunkGroup a chunk group
  562. * @param {Chunk=} ignoreChunk chunk to be ignored
  563. * @returns {boolean} true, if the module is accessible from "chunkGroup" when ignoring "ignoreChunk"
  564. */
  565. isAccessibleInChunkGroup(chunkGraph, chunkGroup, ignoreChunk) {
  566. const queue = new Set([chunkGroup]);
  567. // Check if module is accessible from all items of the queue
  568. queueFor: for (const cg of queue) {
  569. // 1. If module is in one of the chunks of the group we can continue checking the next items
  570. // because it's accessible.
  571. for (const chunk of cg.chunks) {
  572. if (chunk !== ignoreChunk && chunkGraph.isModuleInChunk(this, chunk))
  573. continue queueFor;
  574. }
  575. // 2. If the chunk group is initial, we can break here because it's not accessible.
  576. if (chunkGroup.isInitial()) return false;
  577. // 3. Enqueue all parents because it must be accessible from ALL parents
  578. for (const parent of chunkGroup.parentsIterable) queue.add(parent);
  579. }
  580. // When we processed through the whole list and we didn't bailout, the module is accessible
  581. return true;
  582. }
  583. /**
  584. * @param {Chunk} chunk a chunk
  585. * @param {ModuleGraph} moduleGraph the module graph
  586. * @param {ChunkGraph} chunkGraph the chunk graph
  587. * @returns {boolean} true, if the module has any reason why "chunk" should be included
  588. */
  589. hasReasonForChunk(chunk, moduleGraph, chunkGraph) {
  590. // check for each reason if we need the chunk
  591. for (const [
  592. fromModule,
  593. connections
  594. ] of moduleGraph.getIncomingConnectionsByOriginModule(this)) {
  595. if (!connections.some(c => c.isTargetActive(chunk.runtime))) continue;
  596. for (const originChunk of chunkGraph.getModuleChunksIterable(
  597. fromModule
  598. )) {
  599. // return true if module this is not reachable from originChunk when ignoring chunk
  600. if (!this.isAccessibleInChunk(chunkGraph, originChunk, chunk))
  601. return true;
  602. }
  603. }
  604. return false;
  605. }
  606. /**
  607. * @param {ModuleGraph} moduleGraph the module graph
  608. * @param {RuntimeSpec} runtime the runtime
  609. * @returns {boolean} true if at least one other module depends on this module
  610. */
  611. hasReasons(moduleGraph, runtime) {
  612. for (const c of moduleGraph.getIncomingConnections(this)) {
  613. if (c.isTargetActive(runtime)) return true;
  614. }
  615. return false;
  616. }
  617. /**
  618. * @returns {string} for debugging
  619. */
  620. toString() {
  621. return `Module[${this.debugId}: ${this.identifier()}]`;
  622. }
  623. /**
  624. * @param {NeedBuildContext} context context info
  625. * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
  626. * @returns {void}
  627. */
  628. needBuild(context, callback) {
  629. callback(
  630. null,
  631. !this.buildMeta ||
  632. this.needRebuild === Module.prototype.needRebuild ||
  633. deprecatedNeedRebuild(this, context)
  634. );
  635. }
  636. /**
  637. * @deprecated Use needBuild instead
  638. * @param {Map<string, number|null>} fileTimestamps timestamps of files
  639. * @param {Map<string, number|null>} contextTimestamps timestamps of directories
  640. * @returns {boolean} true, if the module needs a rebuild
  641. */
  642. needRebuild(fileTimestamps, contextTimestamps) {
  643. return true;
  644. }
  645. /**
  646. * @param {Hash} hash the hash used to track dependencies
  647. * @param {UpdateHashContext} context context
  648. * @returns {void}
  649. */
  650. updateHash(
  651. hash,
  652. context = {
  653. chunkGraph: ChunkGraph.getChunkGraphForModule(
  654. this,
  655. "Module.updateHash",
  656. "DEP_WEBPACK_MODULE_UPDATE_HASH"
  657. ),
  658. runtime: undefined
  659. }
  660. ) {
  661. const { chunkGraph, runtime } = context;
  662. hash.update(chunkGraph.getModuleGraphHash(this, runtime));
  663. if (this.presentationalDependencies !== undefined) {
  664. for (const dep of this.presentationalDependencies) {
  665. dep.updateHash(hash, context);
  666. }
  667. }
  668. super.updateHash(hash, context);
  669. }
  670. /**
  671. * @returns {void}
  672. */
  673. invalidateBuild() {
  674. // should be overridden to support this feature
  675. }
  676. /* istanbul ignore next */
  677. /**
  678. * @abstract
  679. * @returns {string} a unique identifier of the module
  680. */
  681. identifier() {
  682. const AbstractMethodError = require("./AbstractMethodError");
  683. throw new AbstractMethodError();
  684. }
  685. /* istanbul ignore next */
  686. /**
  687. * @abstract
  688. * @param {RequestShortener} requestShortener the request shortener
  689. * @returns {string} a user readable identifier of the module
  690. */
  691. readableIdentifier(requestShortener) {
  692. const AbstractMethodError = require("./AbstractMethodError");
  693. throw new AbstractMethodError();
  694. }
  695. /* istanbul ignore next */
  696. /**
  697. * @abstract
  698. * @param {WebpackOptions} options webpack options
  699. * @param {Compilation} compilation the compilation
  700. * @param {ResolverWithOptions} resolver the resolver
  701. * @param {InputFileSystem} fs the file system
  702. * @param {function(WebpackError=): void} callback callback function
  703. * @returns {void}
  704. */
  705. build(options, compilation, resolver, fs, callback) {
  706. const AbstractMethodError = require("./AbstractMethodError");
  707. throw new AbstractMethodError();
  708. }
  709. /**
  710. * @abstract
  711. * @returns {Set<string>} types available (do not mutate)
  712. */
  713. getSourceTypes() {
  714. // Better override this method to return the correct types
  715. if (this.source === Module.prototype.source) {
  716. return DEFAULT_TYPES_UNKNOWN;
  717. } else {
  718. return DEFAULT_TYPES_JS;
  719. }
  720. }
  721. /**
  722. * @abstract
  723. * @deprecated Use codeGeneration() instead
  724. * @param {DependencyTemplates} dependencyTemplates the dependency templates
  725. * @param {RuntimeTemplate} runtimeTemplate the runtime template
  726. * @param {string=} type the type of source that should be generated
  727. * @returns {Source} generated source
  728. */
  729. source(dependencyTemplates, runtimeTemplate, type = "javascript") {
  730. if (this.codeGeneration === Module.prototype.codeGeneration) {
  731. const AbstractMethodError = require("./AbstractMethodError");
  732. throw new AbstractMethodError();
  733. }
  734. const chunkGraph = ChunkGraph.getChunkGraphForModule(
  735. this,
  736. "Module.source() is deprecated. Use Compilation.codeGenerationResults.getSource(module, runtime, type) instead",
  737. "DEP_WEBPACK_MODULE_SOURCE"
  738. );
  739. /** @type {CodeGenerationContext} */
  740. const codeGenContext = {
  741. dependencyTemplates,
  742. runtimeTemplate,
  743. moduleGraph: chunkGraph.moduleGraph,
  744. chunkGraph,
  745. runtime: undefined,
  746. codeGenerationResults: undefined
  747. };
  748. const sources = this.codeGeneration(codeGenContext).sources;
  749. return type ? sources.get(type) : sources.get(first(this.getSourceTypes()));
  750. }
  751. /* istanbul ignore next */
  752. /**
  753. * @abstract
  754. * @param {string=} type the source type for which the size should be estimated
  755. * @returns {number} the estimated size of the module (must be non-zero)
  756. */
  757. size(type) {
  758. const AbstractMethodError = require("./AbstractMethodError");
  759. throw new AbstractMethodError();
  760. }
  761. /**
  762. * @param {LibIdentOptions} options options
  763. * @returns {string | null} an identifier for library inclusion
  764. */
  765. libIdent(options) {
  766. return null;
  767. }
  768. /**
  769. * @returns {string | null} absolute path which should be used for condition matching (usually the resource path)
  770. */
  771. nameForCondition() {
  772. return null;
  773. }
  774. /**
  775. * @param {ConcatenationBailoutReasonContext} context context
  776. * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
  777. */
  778. getConcatenationBailoutReason(context) {
  779. return `Module Concatenation is not implemented for ${this.constructor.name}`;
  780. }
  781. /**
  782. * @param {ModuleGraph} moduleGraph the module graph
  783. * @returns {ConnectionState} how this module should be connected to referencing modules when consumed for side-effects only
  784. */
  785. getSideEffectsConnectionState(moduleGraph) {
  786. return true;
  787. }
  788. /**
  789. * @param {CodeGenerationContext} context context for code generation
  790. * @returns {CodeGenerationResult} result
  791. */
  792. codeGeneration(context) {
  793. // Best override this method
  794. const sources = new Map();
  795. for (const type of this.getSourceTypes()) {
  796. if (type !== "unknown") {
  797. sources.set(
  798. type,
  799. this.source(
  800. context.dependencyTemplates,
  801. context.runtimeTemplate,
  802. type
  803. )
  804. );
  805. }
  806. }
  807. return {
  808. sources,
  809. runtimeRequirements: new Set([
  810. RuntimeGlobals.module,
  811. RuntimeGlobals.exports,
  812. RuntimeGlobals.require
  813. ])
  814. };
  815. }
  816. /**
  817. * @param {Chunk} chunk the chunk which condition should be checked
  818. * @param {Compilation} compilation the compilation
  819. * @returns {boolean} true, if the chunk is ok for the module
  820. */
  821. chunkCondition(chunk, compilation) {
  822. return true;
  823. }
  824. hasChunkCondition() {
  825. return this.chunkCondition !== Module.prototype.chunkCondition;
  826. }
  827. /**
  828. * Assuming this module is in the cache. Update the (cached) module with
  829. * the fresh module from the factory. Usually updates internal references
  830. * and properties.
  831. * @param {Module} module fresh module
  832. * @returns {void}
  833. */
  834. updateCacheModule(module) {
  835. this.type = module.type;
  836. this.layer = module.layer;
  837. this.context = module.context;
  838. this.factoryMeta = module.factoryMeta;
  839. this.resolveOptions = module.resolveOptions;
  840. }
  841. /**
  842. * Module should be unsafe cached. Get data that's needed for that.
  843. * This data will be passed to restoreFromUnsafeCache later.
  844. * @returns {object} cached data
  845. */
  846. getUnsafeCacheData() {
  847. return {
  848. factoryMeta: this.factoryMeta,
  849. resolveOptions: this.resolveOptions
  850. };
  851. }
  852. /**
  853. * restore unsafe cache data
  854. * @param {object} unsafeCacheData data from getUnsafeCacheData
  855. * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching
  856. */
  857. _restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
  858. this.factoryMeta = unsafeCacheData.factoryMeta;
  859. this.resolveOptions = unsafeCacheData.resolveOptions;
  860. }
  861. /**
  862. * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
  863. */
  864. cleanupForCache() {
  865. this.factoryMeta = undefined;
  866. this.resolveOptions = undefined;
  867. }
  868. /**
  869. * @returns {Source | null} the original source for the module before webpack transformation
  870. */
  871. originalSource() {
  872. return null;
  873. }
  874. /**
  875. * @param {LazySet<string>} fileDependencies set where file dependencies are added to
  876. * @param {LazySet<string>} contextDependencies set where context dependencies are added to
  877. * @param {LazySet<string>} missingDependencies set where missing dependencies are added to
  878. * @param {LazySet<string>} buildDependencies set where build dependencies are added to
  879. */
  880. addCacheDependencies(
  881. fileDependencies,
  882. contextDependencies,
  883. missingDependencies,
  884. buildDependencies
  885. ) {}
  886. serialize(context) {
  887. const { write } = context;
  888. write(this.type);
  889. write(this.layer);
  890. write(this.context);
  891. write(this.resolveOptions);
  892. write(this.factoryMeta);
  893. write(this.useSourceMap);
  894. write(this.useSimpleSourceMap);
  895. write(
  896. this._warnings !== undefined && this._warnings.length === 0
  897. ? undefined
  898. : this._warnings
  899. );
  900. write(
  901. this._errors !== undefined && this._errors.length === 0
  902. ? undefined
  903. : this._errors
  904. );
  905. write(this.buildMeta);
  906. write(this.buildInfo);
  907. write(this.presentationalDependencies);
  908. write(this.codeGenerationDependencies);
  909. super.serialize(context);
  910. }
  911. deserialize(context) {
  912. const { read } = context;
  913. this.type = read();
  914. this.layer = read();
  915. this.context = read();
  916. this.resolveOptions = read();
  917. this.factoryMeta = read();
  918. this.useSourceMap = read();
  919. this.useSimpleSourceMap = read();
  920. this._warnings = read();
  921. this._errors = read();
  922. this.buildMeta = read();
  923. this.buildInfo = read();
  924. this.presentationalDependencies = read();
  925. this.codeGenerationDependencies = read();
  926. super.deserialize(context);
  927. }
  928. }
  929. makeSerializable(Module, "webpack/lib/Module");
  930. // TODO remove in webpack 6
  931. Object.defineProperty(Module.prototype, "hasEqualsChunks", {
  932. get() {
  933. throw new Error(
  934. "Module.hasEqualsChunks was renamed (use hasEqualChunks instead)"
  935. );
  936. }
  937. });
  938. // TODO remove in webpack 6
  939. Object.defineProperty(Module.prototype, "isUsed", {
  940. get() {
  941. throw new Error(
  942. "Module.isUsed was renamed (use getUsedName, isExportUsed or isModuleUsed instead)"
  943. );
  944. }
  945. });
  946. // TODO remove in webpack 6
  947. Object.defineProperty(Module.prototype, "errors", {
  948. get: util.deprecate(
  949. /**
  950. * @this {Module}
  951. * @returns {WebpackError[]} array
  952. */
  953. function () {
  954. if (this._errors === undefined) {
  955. this._errors = [];
  956. }
  957. return this._errors;
  958. },
  959. "Module.errors was removed (use getErrors instead)",
  960. "DEP_WEBPACK_MODULE_ERRORS"
  961. )
  962. });
  963. // TODO remove in webpack 6
  964. Object.defineProperty(Module.prototype, "warnings", {
  965. get: util.deprecate(
  966. /**
  967. * @this {Module}
  968. * @returns {WebpackError[]} array
  969. */
  970. function () {
  971. if (this._warnings === undefined) {
  972. this._warnings = [];
  973. }
  974. return this._warnings;
  975. },
  976. "Module.warnings was removed (use getWarnings instead)",
  977. "DEP_WEBPACK_MODULE_WARNINGS"
  978. )
  979. });
  980. // TODO remove in webpack 6
  981. Object.defineProperty(Module.prototype, "used", {
  982. get() {
  983. throw new Error(
  984. "Module.used was refactored (use ModuleGraph.getUsedExports instead)"
  985. );
  986. },
  987. set(value) {
  988. throw new Error(
  989. "Module.used was refactored (use ModuleGraph.setUsedExports instead)"
  990. );
  991. }
  992. });
  993. module.exports = Module;