defaults.js 50 KB

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