defaults.js 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const fs = require("fs");
  7. const path = require("path");
  8. const {
  9. CSS_TYPE,
  10. JAVASCRIPT_TYPE,
  11. UNKNOWN_TYPE
  12. } = require("../ModuleSourceTypeConstants");
  13. const {
  14. ASSET_MODULE_TYPE,
  15. ASSET_MODULE_TYPE_BYTES,
  16. ASSET_MODULE_TYPE_INLINE,
  17. ASSET_MODULE_TYPE_RESOURCE,
  18. ASSET_MODULE_TYPE_SOURCE,
  19. CSS_MODULE_TYPE,
  20. CSS_MODULE_TYPE_AUTO,
  21. CSS_MODULE_TYPE_GLOBAL,
  22. CSS_MODULE_TYPE_MODULE,
  23. JAVASCRIPT_MODULE_TYPE_AUTO,
  24. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  25. JAVASCRIPT_MODULE_TYPE_ESM,
  26. JSON_MODULE_TYPE,
  27. WEBASSEMBLY_MODULE_TYPE_ASYNC,
  28. WEBASSEMBLY_MODULE_TYPE_SYNC
  29. } = require("../ModuleTypeConstants");
  30. const Template = require("../Template");
  31. const { cleverMerge } = require("../util/cleverMerge");
  32. const {
  33. getDefaultTarget,
  34. getTargetProperties,
  35. getTargetsProperties
  36. } = require("./target");
  37. /** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptionsNormalized */
  38. /** @typedef {import("../../declarations/WebpackOptions").Context} Context */
  39. /** @typedef {import("../../declarations/WebpackOptions").DevTool} Devtool */
  40. /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
  41. /** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
  42. /** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
  43. /** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */
  44. /** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
  45. /** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
  46. /** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
  47. /** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
  48. /** @typedef {import("../../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */
  49. /** @typedef {import("../../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */
  50. /** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
  51. /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
  52. /** @typedef {import("../../declarations/WebpackOptions").JsonGeneratorOptions} JsonGeneratorOptions */
  53. /** @typedef {import("../../declarations/WebpackOptions").Library} Library */
  54. /** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
  55. /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
  56. /** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */
  57. /** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */
  58. /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
  59. /** @typedef {import("../../declarations/WebpackOptions").HashSalt} HashSalt */
  60. /** @typedef {import("../../declarations/WebpackOptions").HashDigest} HashDigest */
  61. /** @typedef {import("../../declarations/WebpackOptions").HashDigestLength} HashDigestLength */
  62. /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
  63. /** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */
  64. /** @typedef {import("../../declarations/WebpackOptions").OptimizationNormalized} Optimization */
  65. /** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
  66. /** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */
  67. /** @typedef {import("../../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */
  68. /** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */
  69. /** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
  70. /** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
  71. /** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
  72. /** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
  73. /** @typedef {import("../Module")} Module */
  74. /** @typedef {import("../javascript/EnableChunkLoadingPlugin").ChunkLoadingTypes} ChunkLoadingTypes */
  75. /** @typedef {import("../wasm/EnableWasmLoadingPlugin").WasmLoadingTypes} WasmLoadingTypes */
  76. /** @typedef {import("./target").PlatformTargetProperties} PlatformTargetProperties */
  77. /** @typedef {import("./target").TargetProperties} TargetProperties */
  78. /**
  79. * Defines the recursive non nullable type used by this module.
  80. * @template T
  81. * @typedef {{ [P in keyof T]-?: T[P] extends object ? RecursiveNonNullable<NonNullable<T[P]>> : NonNullable<T[P]> }} RecursiveNonNullable
  82. */
  83. /**
  84. * Defines the shared type used by this module.
  85. * @typedef {Output & {
  86. * uniqueName: NonNullable<Output["uniqueName"]>,
  87. * filename: NonNullable<Output["filename"]>,
  88. * cssFilename: NonNullable<Output["cssFilename"]>,
  89. * chunkFilename: NonNullable<Output["chunkFilename"]>,
  90. * cssChunkFilename: NonNullable<Output["cssChunkFilename"]>,
  91. * hotUpdateChunkFilename: NonNullable<Output["hotUpdateChunkFilename"]>,
  92. * hotUpdateGlobal: NonNullable<Output["hotUpdateGlobal"]>,
  93. * assetModuleFilename: NonNullable<Output["assetModuleFilename"]>,
  94. * webassemblyModuleFilename: NonNullable<Output["webassemblyModuleFilename"]>,
  95. * sourceMapFilename: NonNullable<Output["sourceMapFilename"]>,
  96. * hotUpdateMainFilename: NonNullable<Output["hotUpdateMainFilename"]>,
  97. * devtoolNamespace: NonNullable<Output["devtoolNamespace"]>,
  98. * publicPath: NonNullable<Output["publicPath"]>,
  99. * workerPublicPath: NonNullable<Output["workerPublicPath"]>,
  100. * workerWasmLoading: NonNullable<Output["workerWasmLoading"]>,
  101. * workerChunkLoading: NonNullable<Output["workerChunkLoading"]>,
  102. * chunkFormat: NonNullable<Output["chunkFormat"]>,
  103. * module: NonNullable<Output["module"]>,
  104. * asyncChunks: NonNullable<Output["asyncChunks"]>,
  105. * charset: NonNullable<Output["charset"]>,
  106. * iife: NonNullable<Output["iife"]>,
  107. * globalObject: NonNullable<Output["globalObject"]>,
  108. * scriptType: NonNullable<Output["scriptType"]>,
  109. * path: NonNullable<Output["path"]>,
  110. * pathinfo: NonNullable<Output["pathinfo"]>,
  111. * hashFunction: NonNullable<Output["hashFunction"]>,
  112. * hashDigest: NonNullable<Output["hashDigest"]>,
  113. * hashDigestLength: NonNullable<Output["hashDigestLength"]>,
  114. * chunkLoadTimeout: NonNullable<Output["chunkLoadTimeout"]>,
  115. * chunkLoading: NonNullable<Output["chunkLoading"]>,
  116. * chunkLoadingGlobal: NonNullable<Output["chunkLoadingGlobal"]>,
  117. * compareBeforeEmit: NonNullable<Output["compareBeforeEmit"]>,
  118. * strictModuleErrorHandling: NonNullable<Output["strictModuleErrorHandling"]>,
  119. * strictModuleExceptionHandling: NonNullable<Output["strictModuleExceptionHandling"]>,
  120. * importFunctionName: NonNullable<Output["importFunctionName"]>,
  121. * importMetaName: NonNullable<Output["importMetaName"]>,
  122. * environment: RecursiveNonNullable<Output["environment"]>,
  123. * crossOriginLoading: NonNullable<Output["crossOriginLoading"]>,
  124. * wasmLoading: NonNullable<Output["wasmLoading"]>,
  125. * }} OutputNormalizedWithDefaults
  126. */
  127. /**
  128. * Defines the shared type used by this module.
  129. * @typedef {SnapshotOptions & {
  130. * managedPaths: NonNullable<SnapshotOptions["managedPaths"]>,
  131. * unmanagedPaths: NonNullable<SnapshotOptions["unmanagedPaths"]>,
  132. * immutablePaths: NonNullable<SnapshotOptions["immutablePaths"]>,
  133. * resolveBuildDependencies: NonNullable<SnapshotOptions["resolveBuildDependencies"]>,
  134. * buildDependencies: NonNullable<SnapshotOptions["buildDependencies"]>,
  135. * module: NonNullable<SnapshotOptions["module"]>,
  136. * resolve: NonNullable<SnapshotOptions["resolve"]>,
  137. * }} SnapshotNormalizedWithDefaults
  138. */
  139. /**
  140. * Defines the shared type used by this module.
  141. * @typedef {Optimization & {
  142. * runtimeChunk: NonNullable<Optimization["runtimeChunk"]>,
  143. * splitChunks: NonNullable<Optimization["splitChunks"]>,
  144. * mergeDuplicateChunks: NonNullable<Optimization["mergeDuplicateChunks"]>,
  145. * removeAvailableModules: NonNullable<Optimization["removeAvailableModules"]>,
  146. * removeEmptyChunks: NonNullable<Optimization["removeEmptyChunks"]>,
  147. * flagIncludedChunks: NonNullable<Optimization["flagIncludedChunks"]>,
  148. * moduleIds: NonNullable<Optimization["moduleIds"]>,
  149. * chunkIds: NonNullable<Optimization["chunkIds"]>,
  150. * sideEffects: NonNullable<Optimization["sideEffects"]>,
  151. * providedExports: NonNullable<Optimization["providedExports"]>,
  152. * usedExports: NonNullable<Optimization["usedExports"]>,
  153. * mangleExports: NonNullable<Optimization["mangleExports"]>,
  154. * innerGraph: NonNullable<Optimization["innerGraph"]>,
  155. * concatenateModules: NonNullable<Optimization["concatenateModules"]>,
  156. * avoidEntryIife: NonNullable<Optimization["avoidEntryIife"]>,
  157. * emitOnErrors: NonNullable<Optimization["emitOnErrors"]>,
  158. * checkWasmTypes: NonNullable<Optimization["checkWasmTypes"]>,
  159. * mangleWasmImports: NonNullable<Optimization["mangleWasmImports"]>,
  160. * portableRecords: NonNullable<Optimization["portableRecords"]>,
  161. * realContentHash: NonNullable<Optimization["realContentHash"]>,
  162. * minimize: NonNullable<Optimization["minimize"]>,
  163. * minimizer: NonNullable<Exclude<Optimization["minimizer"], "...">>,
  164. * nodeEnv: NonNullable<Optimization["nodeEnv"]>,
  165. * }} OptimizationNormalizedWithDefaults
  166. */
  167. /**
  168. * Defines the shared type used by this module.
  169. * @typedef {ExternalsPresets & {
  170. * web: NonNullable<ExternalsPresets["web"]>,
  171. * node: NonNullable<ExternalsPresets["node"]>,
  172. * nwjs: NonNullable<ExternalsPresets["nwjs"]>,
  173. * electron: NonNullable<ExternalsPresets["electron"]>,
  174. * electronMain: NonNullable<ExternalsPresets["electronMain"]>,
  175. * electronPreload: NonNullable<ExternalsPresets["electronPreload"]>,
  176. * electronRenderer: NonNullable<ExternalsPresets["electronRenderer"]>,
  177. * }} ExternalsPresetsNormalizedWithDefaults
  178. */
  179. /**
  180. * Defines the shared type used by this module.
  181. * @typedef {InfrastructureLogging & {
  182. * stream: NonNullable<InfrastructureLogging["stream"]>,
  183. * level: NonNullable<InfrastructureLogging["level"]>,
  184. * debug: NonNullable<InfrastructureLogging["debug"]>,
  185. * colors: NonNullable<InfrastructureLogging["colors"]>,
  186. * appendOnly: NonNullable<InfrastructureLogging["appendOnly"]>,
  187. * }} InfrastructureLoggingNormalizedWithDefaults
  188. */
  189. /**
  190. * Defines the webpack options normalized with base defaults type used by this module.
  191. * @typedef {WebpackOptionsNormalized & { context: NonNullable<WebpackOptionsNormalized["context"]> } & { infrastructureLogging: InfrastructureLoggingNormalizedWithDefaults }} WebpackOptionsNormalizedWithBaseDefaults
  192. */
  193. /**
  194. * Defines the webpack options normalized with defaults type used by this module.
  195. * @typedef {WebpackOptionsNormalizedWithBaseDefaults & { target: NonNullable<WebpackOptionsNormalized["target"]> } & { output: OutputNormalizedWithDefaults } & { optimization: OptimizationNormalizedWithDefaults } & { devtool: NonNullable<WebpackOptionsNormalized["devtool"]> } & { stats: NonNullable<WebpackOptionsNormalized["stats"]> } & { node: NonNullable<WebpackOptionsNormalized["node"]> } & { profile: NonNullable<WebpackOptionsNormalized["profile"]> } & { parallelism: NonNullable<WebpackOptionsNormalized["parallelism"]> } & { snapshot: SnapshotNormalizedWithDefaults } & { externalsPresets: ExternalsPresetsNormalizedWithDefaults } & { externalsType: NonNullable<WebpackOptionsNormalized["externalsType"]> } & { watch: NonNullable<WebpackOptionsNormalized["watch"]> } & { performance: NonNullable<WebpackOptionsNormalized["performance"]> } & { recordsInputPath: NonNullable<WebpackOptionsNormalized["recordsInputPath"]> } & { recordsOutputPath: NonNullable<WebpackOptionsNormalized["recordsOutputPath"]> } & { dotenv: NonNullable<WebpackOptionsNormalized["dotenv"]> }} WebpackOptionsNormalizedWithDefaults
  196. */
  197. /**
  198. * Defines the resolved options type used by this module.
  199. * @typedef {object} ResolvedOptions
  200. * @property {PlatformTargetProperties | false} platform - platform target properties
  201. */
  202. const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
  203. const DEFAULT_CACHE_NAME = "default";
  204. const DEFAULTS = {
  205. // TODO webpack 6 - use xxhash64
  206. HASH_FUNCTION: "md4"
  207. };
  208. /**
  209. * Processes the provided obj.
  210. * @template T
  211. * @template {keyof T} P
  212. * @param {T} obj an object
  213. * @param {P} prop a property of this object
  214. * @param {T[P]} value a default value of the property
  215. * @returns {void}
  216. */
  217. const D = (obj, prop, value) => {
  218. if (obj[prop] === undefined) {
  219. obj[prop] = value;
  220. }
  221. };
  222. /**
  223. * Processes the provided obj.
  224. * @template T
  225. * @template {keyof T} P
  226. * @param {T} obj an object
  227. * @param {P} prop a property of this object
  228. * @param {() => T[P]} factory a default value factory for the property
  229. * @returns {void}
  230. */
  231. const F = (obj, prop, factory) => {
  232. if (obj[prop] === undefined) {
  233. obj[prop] = factory();
  234. }
  235. };
  236. /**
  237. * Sets a dynamic default value when undefined, by calling the factory function.
  238. * factory must return an array or undefined
  239. * When the current value is already an array an contains "..." it's replaced with
  240. * the result of the factory function
  241. * @template T
  242. * @template {keyof T} P
  243. * @param {T} obj an object
  244. * @param {P} prop a property of this object
  245. * @param {() => T[P]} factory a default value factory for the property
  246. * @returns {void}
  247. */
  248. const A = (obj, prop, factory) => {
  249. const value = obj[prop];
  250. if (value === undefined) {
  251. obj[prop] = factory();
  252. } else if (Array.isArray(value)) {
  253. /** @type {EXPECTED_ANY[] | undefined} */
  254. let newArray;
  255. for (let i = 0; i < value.length; i++) {
  256. const item = value[i];
  257. if (item === "...") {
  258. if (newArray === undefined) {
  259. newArray = value.slice(0, i);
  260. obj[prop] = /** @type {T[P]} */ (/** @type {unknown} */ (newArray));
  261. }
  262. const items =
  263. /** @type {EXPECTED_ANY[]} */
  264. (/** @type {unknown} */ (factory()));
  265. if (items !== undefined) {
  266. for (const item of items) {
  267. newArray.push(item);
  268. }
  269. }
  270. } else if (newArray !== undefined) {
  271. newArray.push(item);
  272. }
  273. }
  274. }
  275. };
  276. /**
  277. * Apply webpack options base defaults.
  278. * @param {WebpackOptionsNormalized} options options to be modified
  279. * @returns {void}
  280. */
  281. const applyWebpackOptionsBaseDefaults = (options) => {
  282. F(options, "context", () => process.cwd());
  283. applyInfrastructureLoggingDefaults(options.infrastructureLogging);
  284. };
  285. /**
  286. * Apply webpack options defaults.
  287. * @param {WebpackOptionsNormalized} options options to be modified
  288. * @param {number=} compilerIndex index of compiler
  289. * @returns {ResolvedOptions} Resolved options after apply defaults
  290. */
  291. const applyWebpackOptionsDefaults = (options, compilerIndex) => {
  292. F(options, "context", () => process.cwd());
  293. F(options, "target", () =>
  294. getDefaultTarget(/** @type {string} */ (options.context))
  295. );
  296. const { mode, name, target } = options;
  297. const targetProperties =
  298. target === false
  299. ? /** @type {false} */ (false)
  300. : typeof target === "string"
  301. ? getTargetProperties(target, /** @type {Context} */ (options.context))
  302. : getTargetsProperties(
  303. /** @type {string[]} */ (target),
  304. /** @type {Context} */ (options.context)
  305. );
  306. const development = mode === "development";
  307. const production = mode === "production" || !mode;
  308. if (typeof options.entry !== "function") {
  309. for (const key of Object.keys(options.entry)) {
  310. F(
  311. options.entry[key],
  312. "import",
  313. () => /** @type {[string]} */ (["./src"])
  314. );
  315. }
  316. }
  317. F(
  318. options,
  319. "devtool",
  320. () =>
  321. /** @type {Devtool} */ (
  322. development
  323. ? [
  324. options.experiments.css
  325. ? {
  326. type: "css",
  327. use: "source-map"
  328. }
  329. : undefined,
  330. {
  331. type: "javascript",
  332. use: "eval"
  333. }
  334. ].filter(Boolean)
  335. : false
  336. )
  337. );
  338. D(options, "watch", false);
  339. D(options, "profile", false);
  340. D(options, "parallelism", 100);
  341. D(options, "recordsInputPath", false);
  342. D(options, "recordsOutputPath", false);
  343. applyExperimentsDefaults(options.experiments, {
  344. production,
  345. development,
  346. targetProperties
  347. });
  348. const futureDefaults =
  349. /** @type {NonNullable<ExperimentsNormalized["futureDefaults"]>} */
  350. (options.experiments.futureDefaults);
  351. F(options, "validate", () => !(futureDefaults === true && production));
  352. F(options, "cache", () =>
  353. development ? { type: /** @type {"memory"} */ ("memory") } : false
  354. );
  355. applyCacheDefaults(options.cache, {
  356. name: name || DEFAULT_CACHE_NAME,
  357. mode: mode || "production",
  358. development,
  359. cacheUnaffected: options.experiments.cacheUnaffected,
  360. futureDefaults,
  361. compilerIndex
  362. });
  363. const cache = Boolean(options.cache);
  364. applySnapshotDefaults(options.snapshot, {
  365. production,
  366. futureDefaults
  367. });
  368. applyOutputDefaults(options.output, {
  369. context: /** @type {Context} */ (options.context),
  370. targetProperties,
  371. isAffectedByBrowserslist:
  372. target === undefined ||
  373. (typeof target === "string" && target.startsWith("browserslist")) ||
  374. (Array.isArray(target) &&
  375. target.some((target) => target.startsWith("browserslist"))),
  376. outputModule:
  377. /** @type {NonNullable<ExperimentsNormalized["outputModule"]>} */
  378. (options.experiments.outputModule),
  379. development,
  380. entry: options.entry,
  381. futureDefaults,
  382. asyncWebAssembly:
  383. /** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
  384. (options.experiments.asyncWebAssembly)
  385. });
  386. applyModuleDefaults(options.module, {
  387. cache,
  388. hashSalt: /** @type {NonNullable<Output["hashSalt"]>} */ (
  389. options.output.hashSalt
  390. ),
  391. hashFunction: /** @type {NonNullable<Output["hashFunction"]>} */ (
  392. options.output.hashFunction
  393. ),
  394. syncWebAssembly:
  395. /** @type {NonNullable<ExperimentsNormalized["syncWebAssembly"]>} */
  396. (options.experiments.syncWebAssembly),
  397. asyncWebAssembly:
  398. /** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
  399. (options.experiments.asyncWebAssembly),
  400. css:
  401. /** @type {NonNullable<ExperimentsNormalized["css"]>} */
  402. (options.experiments.css),
  403. deferImport:
  404. /** @type {NonNullable<ExperimentsNormalized["deferImport"]>} */
  405. (options.experiments.deferImport),
  406. sourceImport:
  407. /** @type {NonNullable<ExperimentsNormalized["sourceImport"]>} */
  408. (options.experiments.sourceImport),
  409. futureDefaults,
  410. isNode: targetProperties && targetProperties.node === true,
  411. uniqueName: /** @type {string} */ (options.output.uniqueName),
  412. targetProperties,
  413. mode: options.mode,
  414. outputModule:
  415. /** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
  416. (options.output.module)
  417. });
  418. applyExternalsPresetsDefaults(options.externalsPresets, {
  419. targetProperties,
  420. buildHttp: Boolean(options.experiments.buildHttp),
  421. outputModule:
  422. /** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
  423. (options.output.module)
  424. });
  425. applyLoaderDefaults(
  426. /** @type {NonNullable<WebpackOptionsNormalized["loader"]>} */ (
  427. options.loader
  428. ),
  429. { targetProperties, environment: options.output.environment }
  430. );
  431. F(options, "externalsType", () => {
  432. const validExternalTypes = require("../../schemas/WebpackOptions.json")
  433. .definitions.ExternalsType.enum;
  434. return options.output.library &&
  435. validExternalTypes.includes(options.output.library.type)
  436. ? /** @type {ExternalsType} */ (options.output.library.type)
  437. : options.output.module
  438. ? "module-import"
  439. : "var";
  440. });
  441. applyNodeDefaults(options.node, {
  442. futureDefaults:
  443. /** @type {NonNullable<WebpackOptionsNormalized["experiments"]["futureDefaults"]>} */
  444. (options.experiments.futureDefaults),
  445. outputModule:
  446. /** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */
  447. (options.output.module),
  448. targetProperties
  449. });
  450. F(options, "performance", () =>
  451. production &&
  452. targetProperties &&
  453. (targetProperties.browser || targetProperties.browser === null)
  454. ? {}
  455. : false
  456. );
  457. applyPerformanceDefaults(
  458. /** @type {NonNullable<WebpackOptionsNormalized["performance"]>} */
  459. (options.performance),
  460. {
  461. production
  462. }
  463. );
  464. applyOptimizationDefaults(options.optimization, {
  465. development,
  466. production,
  467. css:
  468. /** @type {NonNullable<ExperimentsNormalized["css"]>} */
  469. (options.experiments.css),
  470. records: Boolean(options.recordsInputPath || options.recordsOutputPath)
  471. });
  472. options.resolve = cleverMerge(
  473. getResolveDefaults({
  474. cache,
  475. context: /** @type {Context} */ (options.context),
  476. targetProperties,
  477. mode: /** @type {Mode} */ (options.mode),
  478. css:
  479. /** @type {NonNullable<ExperimentsNormalized["css"]>} */
  480. (options.experiments.css)
  481. }),
  482. options.resolve
  483. );
  484. options.resolveLoader = cleverMerge(
  485. getResolveLoaderDefaults({ cache }),
  486. options.resolveLoader
  487. );
  488. return {
  489. platform:
  490. targetProperties === false
  491. ? targetProperties
  492. : {
  493. web: targetProperties.web,
  494. browser: targetProperties.browser,
  495. webworker: targetProperties.webworker,
  496. node: targetProperties.node,
  497. nwjs: targetProperties.nwjs,
  498. electron: targetProperties.electron
  499. }
  500. };
  501. };
  502. /**
  503. * Apply experiments defaults.
  504. * @param {ExperimentsNormalized} experiments options
  505. * @param {object} options options
  506. * @param {boolean} options.production is production
  507. * @param {boolean} options.development is development mode
  508. * @param {TargetProperties | false} options.targetProperties target properties
  509. * @returns {void}
  510. */
  511. const applyExperimentsDefaults = (
  512. experiments,
  513. { production, development, targetProperties }
  514. ) => {
  515. D(experiments, "futureDefaults", false);
  516. D(experiments, "backCompat", !experiments.futureDefaults);
  517. // TODO do we need sync web assembly in webpack@6?
  518. D(experiments, "syncWebAssembly", false);
  519. D(experiments, "asyncWebAssembly", experiments.futureDefaults);
  520. D(experiments, "outputModule", false);
  521. D(experiments, "lazyCompilation", undefined);
  522. D(experiments, "buildHttp", undefined);
  523. D(experiments, "cacheUnaffected", experiments.futureDefaults);
  524. D(experiments, "deferImport", false);
  525. D(experiments, "sourceImport", false);
  526. F(experiments, "css", () => (experiments.futureDefaults ? true : undefined));
  527. if (typeof experiments.buildHttp === "object") {
  528. D(experiments.buildHttp, "frozen", production);
  529. D(experiments.buildHttp, "upgrade", false);
  530. }
  531. };
  532. /**
  533. * Apply cache defaults.
  534. * @param {CacheOptionsNormalized} cache options
  535. * @param {object} options options
  536. * @param {string} options.name name
  537. * @param {Mode} options.mode mode
  538. * @param {boolean} options.futureDefaults is future defaults enabled
  539. * @param {boolean} options.development is development mode
  540. * @param {number=} options.compilerIndex index of compiler
  541. * @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled
  542. * @returns {void}
  543. */
  544. const applyCacheDefaults = (
  545. cache,
  546. { name, mode, development, cacheUnaffected, compilerIndex, futureDefaults }
  547. ) => {
  548. if (cache === false) return;
  549. switch (cache.type) {
  550. case "filesystem":
  551. F(cache, "name", () =>
  552. compilerIndex !== undefined
  553. ? `${`${name}-${mode}`}__compiler${compilerIndex + 1}__`
  554. : `${name}-${mode}`
  555. );
  556. D(cache, "version", "");
  557. F(cache, "cacheDirectory", () => {
  558. const cwd = process.cwd();
  559. /** @type {string | undefined} */
  560. let dir = cwd;
  561. for (;;) {
  562. try {
  563. if (fs.statSync(path.join(dir, "package.json")).isFile()) break;
  564. // eslint-disable-next-line no-empty
  565. } catch (_err) {}
  566. const parent = path.dirname(dir);
  567. if (dir === parent) {
  568. dir = undefined;
  569. break;
  570. }
  571. dir = parent;
  572. }
  573. if (!dir) {
  574. return path.resolve(cwd, ".cache/webpack");
  575. } else if (process.versions.pnp === "1") {
  576. return path.resolve(dir, ".pnp/.cache/webpack");
  577. } else if (process.versions.pnp === "3") {
  578. return path.resolve(dir, ".yarn/.cache/webpack");
  579. }
  580. return path.resolve(dir, "node_modules/.cache/webpack");
  581. });
  582. F(cache, "cacheLocation", () =>
  583. path.resolve(
  584. /** @type {NonNullable<FileCacheOptions["cacheDirectory"]>} */
  585. (cache.cacheDirectory),
  586. /** @type {NonNullable<FileCacheOptions["name"]>} */ (cache.name)
  587. )
  588. );
  589. D(cache, "hashAlgorithm", futureDefaults ? "xxhash64" : "md4");
  590. D(cache, "store", "pack");
  591. D(cache, "compression", false);
  592. D(cache, "profile", false);
  593. D(cache, "idleTimeout", 60000);
  594. D(cache, "idleTimeoutForInitialStore", 5000);
  595. D(cache, "idleTimeoutAfterLargeChanges", 1000);
  596. D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
  597. D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
  598. D(cache, "allowCollectingMemory", development);
  599. D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
  600. D(cache, "readonly", false);
  601. D(
  602. /** @type {NonNullable<FileCacheOptions["buildDependencies"]>} */
  603. (cache.buildDependencies),
  604. "defaultWebpack",
  605. [path.resolve(__dirname, "..") + path.sep]
  606. );
  607. break;
  608. case "memory":
  609. D(cache, "maxGenerations", Infinity);
  610. D(cache, "cacheUnaffected", development && cacheUnaffected);
  611. break;
  612. }
  613. };
  614. /**
  615. * Apply snapshot defaults.
  616. * @param {SnapshotOptions} snapshot options
  617. * @param {object} options options
  618. * @param {boolean} options.production is production
  619. * @param {boolean} options.futureDefaults is future defaults enabled
  620. * @returns {void}
  621. */
  622. const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => {
  623. if (futureDefaults) {
  624. F(snapshot, "managedPaths", () =>
  625. process.versions.pnp === "3"
  626. ? [
  627. /^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/
  628. ]
  629. : [/^(.+?[\\/]node_modules[\\/])/]
  630. );
  631. F(snapshot, "immutablePaths", () =>
  632. process.versions.pnp === "3"
  633. ? [/^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/]
  634. : []
  635. );
  636. } else {
  637. A(snapshot, "managedPaths", () => {
  638. if (process.versions.pnp === "3") {
  639. const match =
  640. /^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
  641. require.resolve("watchpack")
  642. );
  643. if (match) {
  644. return [path.resolve(match[1], "unplugged")];
  645. }
  646. } else {
  647. const match = /^(.+?[\\/]node_modules[\\/])/.exec(
  648. require.resolve("watchpack")
  649. );
  650. if (match) {
  651. return [match[1]];
  652. }
  653. }
  654. return [];
  655. });
  656. A(snapshot, "immutablePaths", () => {
  657. if (process.versions.pnp === "1") {
  658. const match =
  659. /^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
  660. require.resolve("watchpack")
  661. );
  662. if (match) {
  663. return [match[1]];
  664. }
  665. } else if (process.versions.pnp === "3") {
  666. const match =
  667. /^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
  668. require.resolve("watchpack")
  669. );
  670. if (match) {
  671. return [match[1]];
  672. }
  673. }
  674. return [];
  675. });
  676. }
  677. F(snapshot, "unmanagedPaths", () => []);
  678. F(snapshot, "resolveBuildDependencies", () => ({
  679. timestamp: true,
  680. hash: true
  681. }));
  682. F(snapshot, "buildDependencies", () => ({ timestamp: true, hash: true }));
  683. F(snapshot, "module", () =>
  684. production ? { timestamp: true, hash: true } : { timestamp: true }
  685. );
  686. F(snapshot, "contextModule", () => ({ timestamp: true }));
  687. F(snapshot, "resolve", () =>
  688. production ? { timestamp: true, hash: true } : { timestamp: true }
  689. );
  690. };
  691. /**
  692. * Apply javascript parser options defaults.
  693. * @param {JavascriptParserOptions} parserOptions parser options
  694. * @param {object} options options
  695. * @param {boolean} options.futureDefaults is future defaults enabled
  696. * @param {boolean} options.deferImport is defer import enabled
  697. * @param {boolean} options.sourceImport is import source enabled
  698. * @param {boolean} options.isNode is node target platform
  699. * @param {boolean} options.outputModule is output.module enabled
  700. * @returns {void}
  701. */
  702. const applyJavascriptParserOptionsDefaults = (
  703. parserOptions,
  704. { futureDefaults, deferImport, sourceImport, isNode, outputModule }
  705. ) => {
  706. D(parserOptions, "unknownContextRequest", ".");
  707. D(parserOptions, "unknownContextRegExp", false);
  708. D(parserOptions, "unknownContextRecursive", true);
  709. D(parserOptions, "unknownContextCritical", true);
  710. D(parserOptions, "exprContextRequest", ".");
  711. D(parserOptions, "exprContextRegExp", false);
  712. D(parserOptions, "exprContextRecursive", true);
  713. D(parserOptions, "exprContextCritical", true);
  714. D(parserOptions, "wrappedContextRegExp", /.*/);
  715. D(parserOptions, "wrappedContextRecursive", true);
  716. D(parserOptions, "wrappedContextCritical", false);
  717. D(parserOptions, "strictThisContextOnImports", false);
  718. D(parserOptions, "importMeta", outputModule ? "preserve-unknown" : true);
  719. D(parserOptions, "dynamicImportMode", "lazy");
  720. D(parserOptions, "dynamicImportPrefetch", false);
  721. D(parserOptions, "dynamicImportPreload", false);
  722. D(parserOptions, "dynamicImportFetchPriority", false);
  723. D(parserOptions, "createRequire", isNode);
  724. D(parserOptions, "dynamicUrl", true);
  725. D(parserOptions, "deferImport", deferImport);
  726. D(parserOptions, "sourceImport", sourceImport);
  727. if (futureDefaults) D(parserOptions, "exportsPresence", "error");
  728. };
  729. /**
  730. * Apply json generator options defaults.
  731. * @param {JsonGeneratorOptions} generatorOptions generator options
  732. * @returns {void}
  733. */
  734. const applyJsonGeneratorOptionsDefaults = (generatorOptions) => {
  735. D(generatorOptions, "JSONParse", true);
  736. };
  737. /**
  738. * Apply css generator options defaults.
  739. * @param {CssGeneratorOptions} generatorOptions generator options
  740. * @param {object} options options
  741. * @param {TargetProperties | false} options.targetProperties target properties
  742. * @returns {void}
  743. */
  744. const applyCssGeneratorOptionsDefaults = (
  745. generatorOptions,
  746. { targetProperties }
  747. ) => {
  748. D(
  749. generatorOptions,
  750. "exportsOnly",
  751. !targetProperties || targetProperties.document === false
  752. );
  753. D(generatorOptions, "esModule", true);
  754. };
  755. /**
  756. * Apply module defaults.
  757. * @param {ModuleOptions} module options
  758. * @param {object} options options
  759. * @param {boolean} options.cache is caching enabled
  760. * @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
  761. * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
  762. * @param {boolean} options.css is css enabled
  763. * @param {boolean} options.futureDefaults is future defaults enabled
  764. * @param {string} options.uniqueName the unique name
  765. * @param {boolean} options.isNode is node target platform
  766. * @param {boolean} options.deferImport is defer import enabled
  767. * @param {boolean} options.sourceImport is import source enabled
  768. * @param {TargetProperties | false} options.targetProperties target properties
  769. * @param {Mode | undefined} options.mode mode
  770. * @param {HashSalt} options.hashSalt hash salt
  771. * @param {HashFunction} options.hashFunction hash function
  772. * @param {boolean} options.outputModule is output.module enabled
  773. * @returns {void}
  774. */
  775. const applyModuleDefaults = (
  776. module,
  777. {
  778. hashSalt,
  779. hashFunction,
  780. cache,
  781. syncWebAssembly,
  782. asyncWebAssembly,
  783. css,
  784. futureDefaults,
  785. isNode,
  786. uniqueName,
  787. targetProperties,
  788. mode,
  789. deferImport,
  790. sourceImport,
  791. outputModule
  792. }
  793. ) => {
  794. if (cache) {
  795. D(
  796. module,
  797. "unsafeCache",
  798. /**
  799. * Handles the callback logic for this hook.
  800. * @param {Module} module module
  801. * @returns {boolean} true, if we want to cache the module
  802. */
  803. (module) => {
  804. const name = module.nameForCondition();
  805. if (!name) {
  806. return false;
  807. }
  808. return NODE_MODULES_REGEXP.test(name);
  809. }
  810. );
  811. } else {
  812. D(module, "unsafeCache", false);
  813. }
  814. F(module.parser, ASSET_MODULE_TYPE, () => ({}));
  815. F(
  816. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  817. (module.parser[ASSET_MODULE_TYPE]),
  818. "dataUrlCondition",
  819. () => ({})
  820. );
  821. if (
  822. typeof (
  823. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  824. (module.parser[ASSET_MODULE_TYPE]).dataUrlCondition
  825. ) === "object"
  826. ) {
  827. D(
  828. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  829. (module.parser[ASSET_MODULE_TYPE]).dataUrlCondition,
  830. "maxSize",
  831. 8096
  832. );
  833. }
  834. F(module.parser, "javascript", () => ({}));
  835. F(module.parser, JSON_MODULE_TYPE, () => ({}));
  836. D(
  837. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[JSON_MODULE_TYPE]>} */
  838. (module.parser[JSON_MODULE_TYPE]),
  839. "exportsDepth",
  840. mode === "development" ? 1 : Infinity
  841. );
  842. applyJavascriptParserOptionsDefaults(
  843. /** @type {NonNullable<ParserOptionsByModuleTypeKnown["javascript"]>} */
  844. (module.parser.javascript),
  845. {
  846. futureDefaults,
  847. deferImport,
  848. sourceImport,
  849. isNode,
  850. outputModule
  851. }
  852. );
  853. F(module.generator, "json", () => ({}));
  854. applyJsonGeneratorOptionsDefaults(
  855. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown["json"]>} */
  856. (module.generator.json)
  857. );
  858. if (css) {
  859. F(module.parser, CSS_MODULE_TYPE, () => ({}));
  860. D(
  861. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  862. (module.parser[CSS_MODULE_TYPE]),
  863. "import",
  864. true
  865. );
  866. D(
  867. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  868. (module.parser[CSS_MODULE_TYPE]),
  869. "url",
  870. true
  871. );
  872. D(
  873. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  874. (module.parser[CSS_MODULE_TYPE]),
  875. "namedExports",
  876. true
  877. );
  878. for (const type of [
  879. CSS_MODULE_TYPE_AUTO,
  880. CSS_MODULE_TYPE_MODULE,
  881. CSS_MODULE_TYPE_GLOBAL
  882. ]) {
  883. F(module.parser, type, () => ({}));
  884. D(
  885. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  886. (module.parser[type]),
  887. "animation",
  888. true
  889. );
  890. D(
  891. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  892. (module.parser[type]),
  893. "container",
  894. true
  895. );
  896. D(
  897. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  898. (module.parser[type]),
  899. "customIdents",
  900. true
  901. );
  902. D(
  903. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  904. (module.parser[type]),
  905. "dashedIdents",
  906. true
  907. );
  908. D(
  909. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  910. (module.parser[type]),
  911. "function",
  912. true
  913. );
  914. D(
  915. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  916. (module.parser[type]),
  917. "grid",
  918. true
  919. );
  920. }
  921. F(module.generator, CSS_MODULE_TYPE, () => ({}));
  922. applyCssGeneratorOptionsDefaults(
  923. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  924. (module.generator[CSS_MODULE_TYPE]),
  925. { targetProperties }
  926. );
  927. const localIdentName =
  928. mode === "development"
  929. ? uniqueName.length > 0
  930. ? "[uniqueName]-[id]-[local]"
  931. : "[id]-[local]"
  932. : "[fullhash]";
  933. const localIdentHashSalt = hashSalt;
  934. const localIdentHashDigest = "base64url";
  935. const localIdentHashDigestLength = 6;
  936. const exportsConvention = "as-is";
  937. for (const type of [
  938. CSS_MODULE_TYPE_AUTO,
  939. CSS_MODULE_TYPE_MODULE,
  940. CSS_MODULE_TYPE_GLOBAL
  941. ]) {
  942. F(module.generator, type, () => ({}));
  943. D(
  944. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  945. (module.generator[type]),
  946. "localIdentName",
  947. localIdentName
  948. );
  949. D(
  950. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  951. (module.generator[type]),
  952. "localIdentHashSalt",
  953. localIdentHashSalt
  954. );
  955. D(
  956. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
  957. (module.generator[type]),
  958. "localIdentHashFunction",
  959. hashFunction
  960. );
  961. D(
  962. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
  963. (module.generator[type]),
  964. "localIdentHashDigest",
  965. localIdentHashDigest
  966. );
  967. D(
  968. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
  969. (module.generator[type]),
  970. "localIdentHashDigestLength",
  971. localIdentHashDigestLength
  972. );
  973. D(
  974. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]> | NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  975. (module.generator[type]),
  976. "exportsConvention",
  977. exportsConvention
  978. );
  979. }
  980. }
  981. A(module, "defaultRules", () => {
  982. const esm = {
  983. type: JAVASCRIPT_MODULE_TYPE_ESM,
  984. resolve: {
  985. byDependency: {
  986. esm: {
  987. fullySpecified: true
  988. }
  989. }
  990. }
  991. };
  992. const commonjs = {
  993. type: JAVASCRIPT_MODULE_TYPE_DYNAMIC
  994. };
  995. /** @type {RuleSetRules} */
  996. const rules = [
  997. {
  998. mimetype: "application/node",
  999. type: JAVASCRIPT_MODULE_TYPE_AUTO
  1000. },
  1001. {
  1002. test: /\.json$/i,
  1003. type: JSON_MODULE_TYPE
  1004. },
  1005. {
  1006. mimetype: "application/json",
  1007. type: JSON_MODULE_TYPE
  1008. },
  1009. {
  1010. test: /\.mjs$/i,
  1011. ...esm
  1012. },
  1013. {
  1014. test: /\.js$/i,
  1015. descriptionData: {
  1016. type: "module"
  1017. },
  1018. ...esm
  1019. },
  1020. {
  1021. test: /\.cjs$/i,
  1022. ...commonjs
  1023. },
  1024. {
  1025. test: /\.js$/i,
  1026. descriptionData: {
  1027. type: "commonjs"
  1028. },
  1029. ...commonjs
  1030. },
  1031. {
  1032. mimetype: {
  1033. or: ["text/javascript", "application/javascript"]
  1034. },
  1035. ...esm
  1036. }
  1037. ];
  1038. if (asyncWebAssembly) {
  1039. const wasm = {
  1040. type: WEBASSEMBLY_MODULE_TYPE_ASYNC,
  1041. rules: [
  1042. {
  1043. descriptionData: {
  1044. type: "module"
  1045. },
  1046. resolve: {
  1047. fullySpecified: true
  1048. }
  1049. }
  1050. ]
  1051. };
  1052. rules.push({
  1053. test: /\.wasm$/i,
  1054. ...wasm
  1055. });
  1056. rules.push({
  1057. mimetype: "application/wasm",
  1058. ...wasm
  1059. });
  1060. } else if (syncWebAssembly) {
  1061. const wasm = {
  1062. type: WEBASSEMBLY_MODULE_TYPE_SYNC,
  1063. rules: [
  1064. {
  1065. descriptionData: {
  1066. type: "module"
  1067. },
  1068. resolve: {
  1069. fullySpecified: true
  1070. }
  1071. }
  1072. ]
  1073. };
  1074. rules.push({
  1075. test: /\.wasm$/i,
  1076. ...wasm
  1077. });
  1078. rules.push({
  1079. mimetype: "application/wasm",
  1080. ...wasm
  1081. });
  1082. }
  1083. if (css) {
  1084. const resolve = {
  1085. fullySpecified: true,
  1086. preferRelative: true
  1087. };
  1088. rules.push({
  1089. test: /\.css$/i,
  1090. type: CSS_MODULE_TYPE_AUTO,
  1091. resolve
  1092. });
  1093. rules.push({
  1094. mimetype: "text/css+module",
  1095. type: CSS_MODULE_TYPE_MODULE,
  1096. resolve
  1097. });
  1098. rules.push({
  1099. mimetype: "text/css",
  1100. type: CSS_MODULE_TYPE,
  1101. resolve
  1102. });
  1103. // For CSS modules, i.e. `.class { composes: className from "./style.css" }`
  1104. // We inherit for such constructions
  1105. rules.push({
  1106. dependency: /css-import-local-module/,
  1107. type: CSS_MODULE_TYPE_MODULE,
  1108. resolve
  1109. });
  1110. rules.push({
  1111. dependency: /css-import-global-module/,
  1112. type: CSS_MODULE_TYPE_GLOBAL,
  1113. resolve
  1114. });
  1115. rules.push(
  1116. {
  1117. with: { type: "css" },
  1118. parser: {
  1119. exportType: "css-style-sheet"
  1120. },
  1121. resolve
  1122. },
  1123. {
  1124. assert: { type: "css" },
  1125. parser: {
  1126. exportType: "css-style-sheet"
  1127. },
  1128. resolve
  1129. }
  1130. );
  1131. }
  1132. rules.push(
  1133. {
  1134. dependency: "url",
  1135. oneOf: [
  1136. {
  1137. scheme: /^data$/,
  1138. type: ASSET_MODULE_TYPE_INLINE
  1139. },
  1140. {
  1141. type: ASSET_MODULE_TYPE_RESOURCE
  1142. }
  1143. ]
  1144. },
  1145. {
  1146. with: { type: JSON_MODULE_TYPE },
  1147. type: JSON_MODULE_TYPE,
  1148. parser: { namedExports: false }
  1149. },
  1150. {
  1151. assert: { type: JSON_MODULE_TYPE },
  1152. type: JSON_MODULE_TYPE,
  1153. parser: { namedExports: false }
  1154. },
  1155. {
  1156. with: { type: "text" },
  1157. type: ASSET_MODULE_TYPE_SOURCE
  1158. },
  1159. {
  1160. with: { type: "bytes" },
  1161. type: ASSET_MODULE_TYPE_BYTES
  1162. }
  1163. );
  1164. return rules;
  1165. });
  1166. };
  1167. /**
  1168. * Apply output defaults.
  1169. * @param {Output} output options
  1170. * @param {object} options options
  1171. * @param {string} options.context context
  1172. * @param {TargetProperties | false} options.targetProperties target properties
  1173. * @param {boolean} options.isAffectedByBrowserslist is affected by browserslist
  1174. * @param {boolean} options.outputModule is outputModule experiment enabled
  1175. * @param {boolean} options.development is development mode
  1176. * @param {Entry} options.entry entry option
  1177. * @param {boolean} options.futureDefaults is future defaults enabled
  1178. * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
  1179. * @returns {void}
  1180. */
  1181. const applyOutputDefaults = (
  1182. output,
  1183. {
  1184. context,
  1185. targetProperties: tp,
  1186. isAffectedByBrowserslist,
  1187. outputModule,
  1188. development,
  1189. entry,
  1190. futureDefaults,
  1191. asyncWebAssembly
  1192. }
  1193. ) => {
  1194. /**
  1195. * Returns a readable library name.
  1196. * @param {Library=} library the library option
  1197. * @returns {string} a readable library name
  1198. */
  1199. const getLibraryName = (library) => {
  1200. const libraryName =
  1201. typeof library === "object" &&
  1202. library &&
  1203. !Array.isArray(library) &&
  1204. "type" in library
  1205. ? library.name
  1206. : /** @type {LibraryName} */ (library);
  1207. if (Array.isArray(libraryName)) {
  1208. return libraryName.join(".");
  1209. } else if (typeof libraryName === "object") {
  1210. return getLibraryName(libraryName.root);
  1211. } else if (typeof libraryName === "string") {
  1212. return libraryName;
  1213. }
  1214. return "";
  1215. };
  1216. F(output, "uniqueName", () => {
  1217. const libraryName = getLibraryName(output.library).replace(
  1218. /^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g,
  1219. (m, a, d1, d2, b, c) => {
  1220. const content = a || b || c;
  1221. return content.startsWith("\\") && content.endsWith("\\")
  1222. ? `${d2 || ""}[${content.slice(1, -1)}]${d1 || ""}`
  1223. : "";
  1224. }
  1225. );
  1226. if (libraryName) return libraryName;
  1227. const pkgPath = path.resolve(context, "package.json");
  1228. try {
  1229. const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
  1230. return packageInfo.name || "";
  1231. } catch (err) {
  1232. if (/** @type {Error & { code: string }} */ (err).code !== "ENOENT") {
  1233. /** @type {Error & { code: string }} */
  1234. (err).message +=
  1235. `\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`;
  1236. throw err;
  1237. }
  1238. return "";
  1239. }
  1240. });
  1241. F(output, "module", () => Boolean(outputModule));
  1242. const environment = /** @type {Environment} */ (output.environment);
  1243. /**
  1244. * Returns true, when v is truthy or undefined.
  1245. * @param {boolean | undefined} v value
  1246. * @returns {boolean} true, when v is truthy or undefined
  1247. */
  1248. const optimistic = (v) => v || v === undefined;
  1249. /**
  1250. * Conditionally optimistic.
  1251. * @param {boolean | undefined} v value
  1252. * @param {boolean | undefined} c condition
  1253. * @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
  1254. */
  1255. const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
  1256. F(
  1257. environment,
  1258. "globalThis",
  1259. () => /** @type {boolean | undefined} */ (tp && tp.globalThis)
  1260. );
  1261. F(
  1262. environment,
  1263. "bigIntLiteral",
  1264. () =>
  1265. tp && optimistic(/** @type {boolean | undefined} */ (tp.bigIntLiteral))
  1266. );
  1267. F(
  1268. environment,
  1269. "const",
  1270. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
  1271. );
  1272. F(
  1273. environment,
  1274. "methodShorthand",
  1275. () =>
  1276. tp && optimistic(/** @type {boolean | undefined} */ (tp.methodShorthand))
  1277. );
  1278. F(
  1279. environment,
  1280. "arrowFunction",
  1281. () =>
  1282. tp && optimistic(/** @type {boolean | undefined} */ (tp.arrowFunction))
  1283. );
  1284. F(
  1285. environment,
  1286. "asyncFunction",
  1287. () =>
  1288. tp && optimistic(/** @type {boolean | undefined} */ (tp.asyncFunction))
  1289. );
  1290. F(
  1291. environment,
  1292. "forOf",
  1293. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
  1294. );
  1295. F(
  1296. environment,
  1297. "destructuring",
  1298. () =>
  1299. tp && optimistic(/** @type {boolean | undefined} */ (tp.destructuring))
  1300. );
  1301. F(
  1302. environment,
  1303. "optionalChaining",
  1304. () =>
  1305. tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining))
  1306. );
  1307. F(
  1308. environment,
  1309. "nodePrefixForCoreModules",
  1310. () =>
  1311. tp &&
  1312. optimistic(
  1313. /** @type {boolean | undefined} */ (tp.nodePrefixForCoreModules)
  1314. )
  1315. );
  1316. F(
  1317. environment,
  1318. "importMetaDirnameAndFilename",
  1319. () =>
  1320. // No optimistic, because it is new
  1321. tp && /** @type {boolean | undefined} */ (tp.importMetaDirnameAndFilename)
  1322. );
  1323. F(
  1324. environment,
  1325. "templateLiteral",
  1326. () =>
  1327. tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral))
  1328. );
  1329. F(environment, "dynamicImport", () =>
  1330. conditionallyOptimistic(
  1331. /** @type {boolean | undefined} */ (tp && tp.dynamicImport),
  1332. output.module
  1333. )
  1334. );
  1335. F(environment, "dynamicImportInWorker", () =>
  1336. conditionallyOptimistic(
  1337. /** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker),
  1338. output.module
  1339. )
  1340. );
  1341. F(environment, "module", () =>
  1342. conditionallyOptimistic(
  1343. /** @type {boolean | undefined} */ (tp && tp.module),
  1344. output.module
  1345. )
  1346. );
  1347. F(
  1348. environment,
  1349. "document",
  1350. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.document))
  1351. );
  1352. D(output, "filename", output.module ? "[name].mjs" : "[name].js");
  1353. F(output, "iife", () => !output.module);
  1354. D(output, "importFunctionName", "import");
  1355. D(output, "importMetaName", "import.meta");
  1356. F(output, "chunkFilename", () => {
  1357. const filename =
  1358. /** @type {NonNullable<Output["chunkFilename"]>} */
  1359. (output.filename);
  1360. if (typeof filename !== "function") {
  1361. const hasName = filename.includes("[name]");
  1362. const hasId = filename.includes("[id]");
  1363. const hasChunkHash = filename.includes("[chunkhash]");
  1364. const hasContentHash = filename.includes("[contenthash]");
  1365. // Anything changing depending on chunk is fine
  1366. if (hasChunkHash || hasContentHash || hasName || hasId) return filename;
  1367. // Otherwise prefix "[id]." in front of the basename to make it changing
  1368. return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");
  1369. }
  1370. return output.module ? "[id].mjs" : "[id].js";
  1371. });
  1372. F(output, "cssFilename", () => {
  1373. const filename =
  1374. /** @type {NonNullable<Output["cssFilename"]>} */
  1375. (output.filename);
  1376. if (typeof filename !== "function") {
  1377. return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
  1378. }
  1379. return "[id].css";
  1380. });
  1381. F(output, "cssChunkFilename", () => {
  1382. const chunkFilename =
  1383. /** @type {NonNullable<Output["cssChunkFilename"]>} */
  1384. (output.chunkFilename);
  1385. if (typeof chunkFilename !== "function") {
  1386. return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
  1387. }
  1388. return "[id].css";
  1389. });
  1390. D(output, "assetModuleFilename", "[hash][ext][query][fragment]");
  1391. D(output, "webassemblyModuleFilename", "[hash].module.wasm");
  1392. D(output, "compareBeforeEmit", true);
  1393. D(output, "charset", !futureDefaults);
  1394. const uniqueNameId = Template.toIdentifier(
  1395. /** @type {NonNullable<Output["uniqueName"]>} */ (output.uniqueName)
  1396. );
  1397. F(output, "hotUpdateGlobal", () => `webpackHotUpdate${uniqueNameId}`);
  1398. F(output, "chunkLoadingGlobal", () => `webpackChunk${uniqueNameId}`);
  1399. F(output, "globalObject", () => {
  1400. if (tp) {
  1401. if (tp.global) return "global";
  1402. if (tp.globalThis) return "globalThis";
  1403. // For universal target (i.e. code can be run in browser/node/worker etc.)
  1404. if (tp.web === null && tp.node === null && tp.module) return "globalThis";
  1405. }
  1406. return "self";
  1407. });
  1408. F(output, "chunkFormat", () => {
  1409. if (tp) {
  1410. const helpMessage = isAffectedByBrowserslist
  1411. ? "Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly."
  1412. : "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly.";
  1413. if (output.module) {
  1414. if (environment.dynamicImport) return "module";
  1415. if (tp.document) return "array-push";
  1416. throw new Error(
  1417. "For the selected environment is no default ESM chunk format available:\n" +
  1418. "ESM exports can be chosen when 'import()' is available.\n" +
  1419. `JSONP Array push can be chosen when 'document' is available.\n${helpMessage}`
  1420. );
  1421. } else {
  1422. if (tp.document) return "array-push";
  1423. if (tp.require) return "commonjs";
  1424. if (tp.nodeBuiltins) return "commonjs";
  1425. if (tp.importScripts) return "array-push";
  1426. throw new Error(
  1427. "For the selected environment is no default script chunk format available:\n" +
  1428. `${
  1429. tp.module
  1430. ? "Module ('module') can be chosen when ES modules are available (please set 'experiments.outputModule' and 'output.module' to `true`)"
  1431. : ""
  1432. }\n` +
  1433. "JSONP Array push ('array-push') can be chosen when 'document' or 'importScripts' is available.\n" +
  1434. `CommonJs exports ('commonjs') can be chosen when 'require' or node builtins are available.\n${helpMessage}`
  1435. );
  1436. }
  1437. }
  1438. throw new Error(
  1439. "Chunk format can't be selected by default when no target is specified"
  1440. );
  1441. });
  1442. D(output, "asyncChunks", true);
  1443. F(output, "chunkLoading", () => {
  1444. if (tp) {
  1445. switch (output.chunkFormat) {
  1446. case "array-push":
  1447. if (tp.document) return "jsonp";
  1448. if (tp.importScripts) return "import-scripts";
  1449. break;
  1450. case "commonjs":
  1451. if (tp.require) return "require";
  1452. if (tp.nodeBuiltins) return "async-node";
  1453. break;
  1454. case "module":
  1455. if (environment.dynamicImport) return "import";
  1456. break;
  1457. }
  1458. if (
  1459. (tp.require === null ||
  1460. tp.nodeBuiltins === null ||
  1461. tp.document === null ||
  1462. tp.importScripts === null) &&
  1463. output.module &&
  1464. environment.dynamicImport
  1465. ) {
  1466. return "import";
  1467. }
  1468. }
  1469. return false;
  1470. });
  1471. F(output, "workerChunkLoading", () => {
  1472. if (tp) {
  1473. switch (output.chunkFormat) {
  1474. case "array-push":
  1475. if (tp.importScriptsInWorker) return "import-scripts";
  1476. break;
  1477. case "commonjs":
  1478. if (tp.require) return "require";
  1479. if (tp.nodeBuiltins) return "async-node";
  1480. break;
  1481. case "module":
  1482. if (environment.dynamicImportInWorker) return "import";
  1483. break;
  1484. }
  1485. if (
  1486. (tp.require === null ||
  1487. tp.nodeBuiltins === null ||
  1488. tp.importScriptsInWorker === null) &&
  1489. output.module &&
  1490. environment.dynamicImportInWorker
  1491. ) {
  1492. return "import";
  1493. }
  1494. }
  1495. return false;
  1496. });
  1497. F(output, "wasmLoading", () => {
  1498. if (tp) {
  1499. if (tp.fetchWasm) return "fetch";
  1500. if (tp.nodeBuiltins) return "async-node";
  1501. if (
  1502. (tp.nodeBuiltins === null || tp.fetchWasm === null) &&
  1503. output.module &&
  1504. environment.dynamicImport
  1505. ) {
  1506. return "universal";
  1507. }
  1508. }
  1509. return false;
  1510. });
  1511. F(output, "workerWasmLoading", () => output.wasmLoading);
  1512. F(output, "devtoolNamespace", () => output.uniqueName);
  1513. if (output.library) {
  1514. F(output.library, "type", () => (output.module ? "module" : "var"));
  1515. }
  1516. F(output, "path", () => path.join(process.cwd(), "dist"));
  1517. F(output, "pathinfo", () => development);
  1518. D(output, "sourceMapFilename", "[file].map[query]");
  1519. D(
  1520. output,
  1521. "hotUpdateChunkFilename",
  1522. `[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
  1523. );
  1524. D(
  1525. output,
  1526. "hotUpdateMainFilename",
  1527. `[runtime].[fullhash].hot-update.${output.module ? "json.mjs" : "json"}`
  1528. );
  1529. D(output, "crossOriginLoading", false);
  1530. F(output, "scriptType", () => (output.module ? "module" : false));
  1531. D(
  1532. output,
  1533. "publicPath",
  1534. (tp && (tp.document || tp.importScripts)) || output.scriptType === "module"
  1535. ? "auto"
  1536. : ""
  1537. );
  1538. D(output, "workerPublicPath", "");
  1539. D(output, "chunkLoadTimeout", 120000);
  1540. F(output, "hashFunction", () => {
  1541. if (futureDefaults) {
  1542. DEFAULTS.HASH_FUNCTION = "xxhash64";
  1543. return "xxhash64";
  1544. }
  1545. return "md4";
  1546. });
  1547. D(output, "hashDigest", "hex");
  1548. D(output, "hashDigestLength", futureDefaults ? 16 : 20);
  1549. D(output, "strictModuleErrorHandling", false);
  1550. D(output, "strictModuleExceptionHandling", false);
  1551. const { trustedTypes } = output;
  1552. if (trustedTypes) {
  1553. F(
  1554. trustedTypes,
  1555. "policyName",
  1556. () =>
  1557. /** @type {NonNullable<Output["uniqueName"]>} */
  1558. (output.uniqueName).replace(/[^a-z0-9\-#=_/@.%]+/gi, "_") || "webpack"
  1559. );
  1560. D(trustedTypes, "onPolicyCreationFailure", "stop");
  1561. }
  1562. /**
  1563. * Processes the provided fn.
  1564. * @param {(entryDescription: EntryDescription) => void} fn iterator
  1565. * @returns {void}
  1566. */
  1567. const forEachEntry = (fn) => {
  1568. for (const name of Object.keys(entry)) {
  1569. fn(/** @type {{ [k: string]: EntryDescription }} */ (entry)[name]);
  1570. }
  1571. };
  1572. A(output, "enabledLibraryTypes", () => {
  1573. /** @type {LibraryType[]} */
  1574. const enabledLibraryTypes = [];
  1575. if (output.library) {
  1576. enabledLibraryTypes.push(output.library.type);
  1577. }
  1578. forEachEntry((desc) => {
  1579. if (desc.library) {
  1580. enabledLibraryTypes.push(desc.library.type);
  1581. }
  1582. });
  1583. return enabledLibraryTypes;
  1584. });
  1585. A(output, "enabledChunkLoadingTypes", () => {
  1586. /** @type {ChunkLoadingTypes} */
  1587. const enabledChunkLoadingTypes = new Set();
  1588. if (output.chunkLoading) {
  1589. enabledChunkLoadingTypes.add(output.chunkLoading);
  1590. }
  1591. if (output.workerChunkLoading) {
  1592. enabledChunkLoadingTypes.add(output.workerChunkLoading);
  1593. }
  1594. forEachEntry((desc) => {
  1595. if (desc.chunkLoading) {
  1596. enabledChunkLoadingTypes.add(desc.chunkLoading);
  1597. }
  1598. });
  1599. return [...enabledChunkLoadingTypes];
  1600. });
  1601. A(output, "enabledWasmLoadingTypes", () => {
  1602. /** @type {WasmLoadingTypes} */
  1603. const enabledWasmLoadingTypes = new Set();
  1604. if (output.wasmLoading) {
  1605. enabledWasmLoadingTypes.add(output.wasmLoading);
  1606. }
  1607. if (output.workerWasmLoading) {
  1608. enabledWasmLoadingTypes.add(output.workerWasmLoading);
  1609. }
  1610. forEachEntry((desc) => {
  1611. if (desc.wasmLoading) {
  1612. enabledWasmLoadingTypes.add(desc.wasmLoading);
  1613. }
  1614. });
  1615. return [...enabledWasmLoadingTypes];
  1616. });
  1617. };
  1618. /**
  1619. * Apply externals presets defaults.
  1620. * @param {ExternalsPresets} externalsPresets options
  1621. * @param {object} options options
  1622. * @param {TargetProperties | false} options.targetProperties target properties
  1623. * @param {boolean} options.buildHttp buildHttp experiment enabled
  1624. * @param {boolean} options.outputModule is output type is module
  1625. * @returns {void}
  1626. */
  1627. const applyExternalsPresetsDefaults = (
  1628. externalsPresets,
  1629. { targetProperties, buildHttp, outputModule }
  1630. ) => {
  1631. /**
  1632. * Checks whether this object is universal.
  1633. * @param {keyof TargetProperties} key a key
  1634. * @returns {boolean} true when target is universal, otherwise false
  1635. */
  1636. const isUniversal = (key) =>
  1637. Boolean(outputModule && targetProperties && targetProperties[key] === null);
  1638. D(
  1639. externalsPresets,
  1640. "web",
  1641. /** @type {boolean | undefined} */
  1642. (
  1643. !buildHttp &&
  1644. targetProperties &&
  1645. (targetProperties.web || isUniversal("node"))
  1646. )
  1647. );
  1648. D(
  1649. externalsPresets,
  1650. "node",
  1651. /** @type {boolean | undefined} */
  1652. (targetProperties && (targetProperties.node || isUniversal("node")))
  1653. );
  1654. D(
  1655. externalsPresets,
  1656. "nwjs",
  1657. /** @type {boolean | undefined} */
  1658. (targetProperties && (targetProperties.nwjs || isUniversal("nwjs")))
  1659. );
  1660. D(
  1661. externalsPresets,
  1662. "electron",
  1663. /** @type {boolean | undefined} */
  1664. ((targetProperties && targetProperties.electron) || isUniversal("electron"))
  1665. );
  1666. D(
  1667. externalsPresets,
  1668. "electronMain",
  1669. /** @type {boolean | undefined} */
  1670. (
  1671. targetProperties &&
  1672. targetProperties.electron &&
  1673. (targetProperties.electronMain || isUniversal("electronMain"))
  1674. )
  1675. );
  1676. D(
  1677. externalsPresets,
  1678. "electronPreload",
  1679. /** @type {boolean | undefined} */
  1680. (
  1681. targetProperties &&
  1682. targetProperties.electron &&
  1683. (targetProperties.electronPreload || isUniversal("electronPreload"))
  1684. )
  1685. );
  1686. D(
  1687. externalsPresets,
  1688. "electronRenderer",
  1689. /** @type {boolean | undefined} */
  1690. (
  1691. targetProperties &&
  1692. targetProperties.electron &&
  1693. (targetProperties.electronRenderer || isUniversal("electronRenderer"))
  1694. )
  1695. );
  1696. };
  1697. /**
  1698. * Apply loader defaults.
  1699. * @param {Loader} loader options
  1700. * @param {object} options options
  1701. * @param {TargetProperties | false} options.targetProperties target properties
  1702. * @param {Environment} options.environment environment
  1703. * @returns {void}
  1704. */
  1705. const applyLoaderDefaults = (loader, { targetProperties, environment }) => {
  1706. F(loader, "target", () => {
  1707. if (targetProperties) {
  1708. if (targetProperties.electron) {
  1709. if (targetProperties.electronMain) return "electron-main";
  1710. if (targetProperties.electronPreload) return "electron-preload";
  1711. if (targetProperties.electronRenderer) return "electron-renderer";
  1712. return "electron";
  1713. }
  1714. if (targetProperties.nwjs) return "nwjs";
  1715. if (targetProperties.node) return "node";
  1716. if (targetProperties.web) return "web";
  1717. }
  1718. });
  1719. D(loader, "environment", environment);
  1720. };
  1721. /**
  1722. * Apply node defaults.
  1723. * @param {WebpackNode} node options
  1724. * @param {object} options options
  1725. * @param {TargetProperties | false} options.targetProperties target properties
  1726. * @param {boolean} options.futureDefaults is future defaults enabled
  1727. * @param {boolean} options.outputModule is output type is module
  1728. * @returns {void}
  1729. */
  1730. const applyNodeDefaults = (
  1731. node,
  1732. { futureDefaults, outputModule, targetProperties }
  1733. ) => {
  1734. if (node === false) return;
  1735. F(node, "global", () => {
  1736. if (targetProperties && targetProperties.global) return false;
  1737. // We use `warm` because overriding `global` with `globalThis` (or a polyfill) is sometimes safe (global.URL), sometimes unsafe (global.process), but we need to warn about it
  1738. return futureDefaults ? "warn" : true;
  1739. });
  1740. const handlerForNames = () => {
  1741. // TODO webpack@6 remove `node-module` in favor of `eval-only`
  1742. if (targetProperties) {
  1743. if (targetProperties.node) {
  1744. return "eval-only";
  1745. }
  1746. // For the "universal" target we only evaluate these values
  1747. if (
  1748. outputModule &&
  1749. targetProperties.node === null &&
  1750. targetProperties.web === null
  1751. ) {
  1752. return "eval-only";
  1753. }
  1754. }
  1755. // TODO webpack@6 should we use `warn-even-only`?
  1756. return futureDefaults ? "warn-mock" : "mock";
  1757. };
  1758. F(node, "__filename", handlerForNames);
  1759. F(node, "__dirname", handlerForNames);
  1760. };
  1761. /**
  1762. * Apply performance defaults.
  1763. * @param {Performance} performance options
  1764. * @param {object} options options
  1765. * @param {boolean} options.production is production
  1766. * @returns {void}
  1767. */
  1768. const applyPerformanceDefaults = (performance, { production }) => {
  1769. if (performance === false) return;
  1770. D(performance, "maxAssetSize", 250000);
  1771. D(performance, "maxEntrypointSize", 250000);
  1772. F(performance, "hints", () => (production ? "warning" : false));
  1773. };
  1774. /**
  1775. * Apply optimization defaults.
  1776. * @param {Optimization} optimization options
  1777. * @param {object} options options
  1778. * @param {boolean} options.production is production
  1779. * @param {boolean} options.development is development
  1780. * @param {boolean} options.css is css enabled
  1781. * @param {boolean} options.records using records
  1782. * @returns {void}
  1783. */
  1784. const applyOptimizationDefaults = (
  1785. optimization,
  1786. { production, development, css, records }
  1787. ) => {
  1788. D(optimization, "removeAvailableModules", false);
  1789. D(optimization, "removeEmptyChunks", true);
  1790. D(optimization, "mergeDuplicateChunks", true);
  1791. D(optimization, "flagIncludedChunks", production);
  1792. F(optimization, "moduleIds", () => {
  1793. if (production) return "deterministic";
  1794. if (development) return "named";
  1795. return "natural";
  1796. });
  1797. F(optimization, "chunkIds", () => {
  1798. if (production) return "deterministic";
  1799. if (development) return "named";
  1800. return "natural";
  1801. });
  1802. F(optimization, "sideEffects", () => (production ? true : "flag"));
  1803. D(optimization, "providedExports", true);
  1804. D(optimization, "usedExports", production);
  1805. D(optimization, "innerGraph", production);
  1806. D(optimization, "mangleExports", production);
  1807. D(optimization, "concatenateModules", production);
  1808. D(optimization, "avoidEntryIife", production);
  1809. D(optimization, "runtimeChunk", false);
  1810. D(optimization, "emitOnErrors", !production);
  1811. D(optimization, "checkWasmTypes", production);
  1812. D(optimization, "mangleWasmImports", false);
  1813. D(optimization, "portableRecords", records);
  1814. D(optimization, "realContentHash", production);
  1815. D(optimization, "minimize", production);
  1816. A(optimization, "minimizer", () => [
  1817. {
  1818. apply: (compiler) => {
  1819. // Lazy load the Terser plugin
  1820. const TerserPlugin = require("terser-webpack-plugin");
  1821. new TerserPlugin({
  1822. terserOptions: {
  1823. compress: {
  1824. passes: 2
  1825. }
  1826. }
  1827. }).apply(/** @type {EXPECTED_ANY} */ (compiler));
  1828. }
  1829. }
  1830. ]);
  1831. F(optimization, "nodeEnv", () => {
  1832. if (production) return "production";
  1833. if (development) return "development";
  1834. return false;
  1835. });
  1836. const { splitChunks } = optimization;
  1837. if (splitChunks) {
  1838. A(splitChunks, "defaultSizeTypes", () =>
  1839. css
  1840. ? [JAVASCRIPT_TYPE, CSS_TYPE, UNKNOWN_TYPE]
  1841. : [JAVASCRIPT_TYPE, UNKNOWN_TYPE]
  1842. );
  1843. D(splitChunks, "hidePathInfo", production);
  1844. D(splitChunks, "chunks", "async");
  1845. D(splitChunks, "usedExports", optimization.usedExports === true);
  1846. D(splitChunks, "minChunks", 1);
  1847. F(splitChunks, "minSize", () => (production ? 20000 : 10000));
  1848. F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined));
  1849. F(splitChunks, "enforceSizeThreshold", () => (production ? 50000 : 30000));
  1850. F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity));
  1851. F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity));
  1852. D(splitChunks, "automaticNameDelimiter", "-");
  1853. const cacheGroups =
  1854. /** @type {NonNullable<OptimizationSplitChunksOptions["cacheGroups"]>} */
  1855. (splitChunks.cacheGroups);
  1856. F(cacheGroups, "default", () => ({
  1857. idHint: "",
  1858. reuseExistingChunk: true,
  1859. minChunks: 2,
  1860. priority: -20
  1861. }));
  1862. F(cacheGroups, "defaultVendors", () => ({
  1863. idHint: "vendors",
  1864. reuseExistingChunk: true,
  1865. test: NODE_MODULES_REGEXP,
  1866. priority: -10
  1867. }));
  1868. }
  1869. };
  1870. /**
  1871. * Gets resolve defaults.
  1872. * @param {object} options options
  1873. * @param {boolean} options.cache is cache enable
  1874. * @param {string} options.context build context
  1875. * @param {TargetProperties | false} options.targetProperties target properties
  1876. * @param {Mode} options.mode mode
  1877. * @param {boolean} options.css is css enabled
  1878. * @returns {ResolveOptions} resolve options
  1879. */
  1880. const getResolveDefaults = ({
  1881. cache,
  1882. context,
  1883. targetProperties,
  1884. mode,
  1885. css
  1886. }) => {
  1887. /** @type {string[]} */
  1888. const conditions = ["webpack"];
  1889. conditions.push(mode === "development" ? "development" : "production");
  1890. if (targetProperties) {
  1891. if (targetProperties.webworker) conditions.push("worker");
  1892. if (targetProperties.node) conditions.push("node");
  1893. if (targetProperties.web) conditions.push("browser");
  1894. if (targetProperties.electron) conditions.push("electron");
  1895. if (targetProperties.nwjs) conditions.push("nwjs");
  1896. }
  1897. const jsExtensions = [".js", ".json", ".wasm"];
  1898. const tp = targetProperties;
  1899. const browserField =
  1900. tp && tp.web && (!tp.node || (tp.electron && tp.electronRenderer));
  1901. /** @type {() => ResolveOptions} */
  1902. const cjsDeps = () => ({
  1903. aliasFields: browserField ? ["browser"] : [],
  1904. mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
  1905. conditionNames: ["require", "module", "..."],
  1906. extensions: [...jsExtensions]
  1907. });
  1908. /** @type {() => ResolveOptions} */
  1909. const esmDeps = () => ({
  1910. aliasFields: browserField ? ["browser"] : [],
  1911. mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
  1912. conditionNames: ["import", "module", "..."],
  1913. extensions: [...jsExtensions]
  1914. });
  1915. /** @type {() => ResolveOptions} */
  1916. const workerDeps = () => {
  1917. const options = esmDeps();
  1918. const conditionNames = options.conditionNames
  1919. ? ["worker", ...options.conditionNames]
  1920. : options.conditionNames;
  1921. return {
  1922. ...options,
  1923. conditionNames,
  1924. preferRelative: true
  1925. };
  1926. };
  1927. /** @type {ResolveOptions} */
  1928. const resolveOptions = {
  1929. cache,
  1930. modules: ["node_modules"],
  1931. conditionNames: conditions,
  1932. mainFiles: ["index"],
  1933. extensions: [],
  1934. aliasFields: [],
  1935. exportsFields: ["exports"],
  1936. roots: [context],
  1937. mainFields: ["main"],
  1938. importsFields: ["imports"],
  1939. byDependency: {
  1940. wasm: esmDeps(),
  1941. esm: esmDeps(),
  1942. loaderImport: esmDeps(),
  1943. url: {
  1944. preferRelative: true
  1945. },
  1946. worker: workerDeps(),
  1947. commonjs: cjsDeps(),
  1948. amd: cjsDeps(),
  1949. // for backward-compat: loadModule
  1950. loader: cjsDeps(),
  1951. // for backward-compat: Custom Dependency
  1952. unknown: cjsDeps(),
  1953. // for backward-compat: getResolve without dependencyType
  1954. undefined: cjsDeps()
  1955. }
  1956. };
  1957. if (css) {
  1958. /** @type {string[]} */
  1959. const styleConditions = [];
  1960. styleConditions.push("webpack");
  1961. styleConditions.push(mode === "development" ? "development" : "production");
  1962. styleConditions.push("style");
  1963. /** @type {ResolveOptions} */
  1964. const cssResolveOptions = {
  1965. // We avoid using any main files because we have to be consistent with CSS `@import`
  1966. // and CSS `@import` does not handle `main` files in directories,
  1967. // you should always specify the full URL for styles
  1968. mainFiles: [],
  1969. mainFields: ["style", "..."],
  1970. conditionNames: styleConditions,
  1971. extensions: [".css"],
  1972. preferRelative: true
  1973. };
  1974. /** @type {NonNullable<ResolveOptions["byDependency"]>} */
  1975. (resolveOptions.byDependency)["css-import"] = cssResolveOptions;
  1976. // For CSS modules, i.e. `.class { composes: className from "./style.css" }`
  1977. // We inherit for such constructions
  1978. /** @type {NonNullable<ResolveOptions["byDependency"]>} */
  1979. (resolveOptions.byDependency)["css-import-local-module"] =
  1980. cssResolveOptions;
  1981. /** @type {NonNullable<ResolveOptions["byDependency"]>} */
  1982. (resolveOptions.byDependency)["css-import-global-module"] =
  1983. cssResolveOptions;
  1984. }
  1985. return resolveOptions;
  1986. };
  1987. /**
  1988. * Gets resolve loader defaults.
  1989. * @param {object} options options
  1990. * @param {boolean} options.cache is cache enable
  1991. * @returns {ResolveOptions} resolve options
  1992. */
  1993. const getResolveLoaderDefaults = ({ cache }) => {
  1994. /** @type {ResolveOptions} */
  1995. const resolveOptions = {
  1996. cache,
  1997. conditionNames: ["loader", "require", "node"],
  1998. exportsFields: ["exports"],
  1999. mainFields: ["loader", "main"],
  2000. extensions: [".js"],
  2001. mainFiles: ["index"]
  2002. };
  2003. return resolveOptions;
  2004. };
  2005. /**
  2006. * Apply infrastructure logging defaults.
  2007. * @param {InfrastructureLogging} infrastructureLogging options
  2008. * @returns {void}
  2009. */
  2010. const applyInfrastructureLoggingDefaults = (infrastructureLogging) => {
  2011. F(infrastructureLogging, "stream", () => process.stderr);
  2012. const tty =
  2013. /** @type {NonNullable<InfrastructureLogging["stream"]>} */
  2014. (infrastructureLogging.stream).isTTY && process.env.TERM !== "dumb";
  2015. D(infrastructureLogging, "level", "info");
  2016. D(infrastructureLogging, "debug", false);
  2017. D(infrastructureLogging, "colors", tty);
  2018. D(infrastructureLogging, "appendOnly", !tty);
  2019. };
  2020. module.exports.DEFAULTS = DEFAULTS;
  2021. module.exports.applyWebpackOptionsBaseDefaults =
  2022. applyWebpackOptionsBaseDefaults;
  2023. module.exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults;