Module.js 34 KB

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