defaults.js 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752
  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. ASSET_MODULE_TYPE,
  10. ASSET_MODULE_TYPE_INLINE,
  11. ASSET_MODULE_TYPE_RESOURCE,
  12. CSS_MODULE_TYPE,
  13. CSS_MODULE_TYPE_AUTO,
  14. CSS_MODULE_TYPE_GLOBAL,
  15. CSS_MODULE_TYPE_MODULE,
  16. JAVASCRIPT_MODULE_TYPE_AUTO,
  17. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  18. JAVASCRIPT_MODULE_TYPE_ESM,
  19. JSON_MODULE_TYPE,
  20. WEBASSEMBLY_MODULE_TYPE_ASYNC,
  21. WEBASSEMBLY_MODULE_TYPE_SYNC
  22. } = require("../ModuleTypeConstants");
  23. const Template = require("../Template");
  24. const { cleverMerge } = require("../util/cleverMerge");
  25. const {
  26. getDefaultTarget,
  27. getTargetProperties,
  28. getTargetsProperties
  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. D(parserOptions, "dynamicUrl", true);
  553. if (futureDefaults) D(parserOptions, "exportsPresence", "error");
  554. };
  555. /**
  556. * @param {JsonGeneratorOptions} generatorOptions generator options
  557. * @returns {void}
  558. */
  559. const applyJsonGeneratorOptionsDefaults = generatorOptions => {
  560. D(generatorOptions, "JSONParse", true);
  561. };
  562. /**
  563. * @param {CssGeneratorOptions} generatorOptions generator options
  564. * @param {object} options options
  565. * @param {TargetProperties | false} options.targetProperties target properties
  566. * @returns {void}
  567. */
  568. const applyCssGeneratorOptionsDefaults = (
  569. generatorOptions,
  570. { targetProperties }
  571. ) => {
  572. D(
  573. generatorOptions,
  574. "exportsOnly",
  575. !targetProperties || targetProperties.document === false
  576. );
  577. D(generatorOptions, "esModule", true);
  578. };
  579. /**
  580. * @param {ModuleOptions} module options
  581. * @param {object} options options
  582. * @param {boolean} options.cache is caching enabled
  583. * @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
  584. * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
  585. * @param {boolean} options.css is css enabled
  586. * @param {boolean} options.futureDefaults is future defaults enabled
  587. * @param {string} options.uniqueName the unique name
  588. * @param {boolean} options.isNode is node target platform
  589. * @param {TargetProperties | false} options.targetProperties target properties
  590. * @param {Mode | undefined} options.mode mode
  591. * @returns {void}
  592. */
  593. const applyModuleDefaults = (
  594. module,
  595. {
  596. cache,
  597. syncWebAssembly,
  598. asyncWebAssembly,
  599. css,
  600. futureDefaults,
  601. isNode,
  602. uniqueName,
  603. targetProperties,
  604. mode
  605. }
  606. ) => {
  607. if (cache) {
  608. D(
  609. module,
  610. "unsafeCache",
  611. /**
  612. * @param {Module} module module
  613. * @returns {boolean} true, if we want to cache the module
  614. */
  615. module => {
  616. const name = module.nameForCondition();
  617. if (!name) {
  618. return false;
  619. }
  620. return NODE_MODULES_REGEXP.test(name);
  621. }
  622. );
  623. } else {
  624. D(module, "unsafeCache", false);
  625. }
  626. F(module.parser, ASSET_MODULE_TYPE, () => ({}));
  627. F(
  628. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  629. (module.parser[ASSET_MODULE_TYPE]),
  630. "dataUrlCondition",
  631. () => ({})
  632. );
  633. if (
  634. typeof (
  635. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  636. (module.parser[ASSET_MODULE_TYPE]).dataUrlCondition
  637. ) === "object"
  638. ) {
  639. D(
  640. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[ASSET_MODULE_TYPE]>} */
  641. (module.parser[ASSET_MODULE_TYPE]).dataUrlCondition,
  642. "maxSize",
  643. 8096
  644. );
  645. }
  646. F(module.parser, "javascript", () => ({}));
  647. F(module.parser, JSON_MODULE_TYPE, () => ({}));
  648. D(
  649. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[JSON_MODULE_TYPE]>} */
  650. (module.parser[JSON_MODULE_TYPE]),
  651. "exportsDepth",
  652. mode === "development" ? 1 : Infinity
  653. );
  654. applyJavascriptParserOptionsDefaults(
  655. /** @type {NonNullable<ParserOptionsByModuleTypeKnown["javascript"]>} */
  656. (module.parser.javascript),
  657. {
  658. futureDefaults,
  659. isNode
  660. }
  661. );
  662. F(module.generator, "json", () => ({}));
  663. applyJsonGeneratorOptionsDefaults(
  664. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown["json"]>} */
  665. (module.generator.json)
  666. );
  667. if (css) {
  668. F(module.parser, CSS_MODULE_TYPE, () => ({}));
  669. D(
  670. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  671. (module.parser[CSS_MODULE_TYPE]),
  672. "import",
  673. true
  674. );
  675. D(
  676. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  677. (module.parser[CSS_MODULE_TYPE]),
  678. "url",
  679. true
  680. );
  681. D(
  682. /** @type {NonNullable<ParserOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  683. (module.parser[CSS_MODULE_TYPE]),
  684. "namedExports",
  685. true
  686. );
  687. F(module.generator, CSS_MODULE_TYPE, () => ({}));
  688. applyCssGeneratorOptionsDefaults(
  689. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE]>} */
  690. (module.generator[CSS_MODULE_TYPE]),
  691. { targetProperties }
  692. );
  693. const localIdentName =
  694. uniqueName.length > 0 ? "[uniqueName]-[id]-[local]" : "[id]-[local]";
  695. F(module.generator, CSS_MODULE_TYPE_AUTO, () => ({}));
  696. D(
  697. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]>} */
  698. (module.generator[CSS_MODULE_TYPE_AUTO]),
  699. "localIdentName",
  700. localIdentName
  701. );
  702. D(
  703. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_AUTO]>} */
  704. (module.generator[CSS_MODULE_TYPE_AUTO]),
  705. "exportsConvention",
  706. "as-is"
  707. );
  708. F(module.generator, CSS_MODULE_TYPE_MODULE, () => ({}));
  709. D(
  710. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
  711. (module.generator[CSS_MODULE_TYPE_MODULE]),
  712. "localIdentName",
  713. localIdentName
  714. );
  715. D(
  716. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_MODULE]>} */
  717. (module.generator[CSS_MODULE_TYPE_MODULE]),
  718. "exportsConvention",
  719. "as-is"
  720. );
  721. F(module.generator, CSS_MODULE_TYPE_GLOBAL, () => ({}));
  722. D(
  723. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  724. (module.generator[CSS_MODULE_TYPE_GLOBAL]),
  725. "localIdentName",
  726. localIdentName
  727. );
  728. D(
  729. /** @type {NonNullable<GeneratorOptionsByModuleTypeKnown[CSS_MODULE_TYPE_GLOBAL]>} */
  730. (module.generator[CSS_MODULE_TYPE_GLOBAL]),
  731. "exportsConvention",
  732. "as-is"
  733. );
  734. }
  735. A(module, "defaultRules", () => {
  736. const esm = {
  737. type: JAVASCRIPT_MODULE_TYPE_ESM,
  738. resolve: {
  739. byDependency: {
  740. esm: {
  741. fullySpecified: true
  742. }
  743. }
  744. }
  745. };
  746. const commonjs = {
  747. type: JAVASCRIPT_MODULE_TYPE_DYNAMIC
  748. };
  749. /** @type {RuleSetRules} */
  750. const rules = [
  751. {
  752. mimetype: "application/node",
  753. type: JAVASCRIPT_MODULE_TYPE_AUTO
  754. },
  755. {
  756. test: /\.json$/i,
  757. type: JSON_MODULE_TYPE
  758. },
  759. {
  760. mimetype: "application/json",
  761. type: JSON_MODULE_TYPE
  762. },
  763. {
  764. test: /\.mjs$/i,
  765. ...esm
  766. },
  767. {
  768. test: /\.js$/i,
  769. descriptionData: {
  770. type: "module"
  771. },
  772. ...esm
  773. },
  774. {
  775. test: /\.cjs$/i,
  776. ...commonjs
  777. },
  778. {
  779. test: /\.js$/i,
  780. descriptionData: {
  781. type: "commonjs"
  782. },
  783. ...commonjs
  784. },
  785. {
  786. mimetype: {
  787. or: ["text/javascript", "application/javascript"]
  788. },
  789. ...esm
  790. }
  791. ];
  792. if (asyncWebAssembly) {
  793. const wasm = {
  794. type: WEBASSEMBLY_MODULE_TYPE_ASYNC,
  795. rules: [
  796. {
  797. descriptionData: {
  798. type: "module"
  799. },
  800. resolve: {
  801. fullySpecified: true
  802. }
  803. }
  804. ]
  805. };
  806. rules.push({
  807. test: /\.wasm$/i,
  808. ...wasm
  809. });
  810. rules.push({
  811. mimetype: "application/wasm",
  812. ...wasm
  813. });
  814. } else if (syncWebAssembly) {
  815. const wasm = {
  816. type: WEBASSEMBLY_MODULE_TYPE_SYNC,
  817. rules: [
  818. {
  819. descriptionData: {
  820. type: "module"
  821. },
  822. resolve: {
  823. fullySpecified: true
  824. }
  825. }
  826. ]
  827. };
  828. rules.push({
  829. test: /\.wasm$/i,
  830. ...wasm
  831. });
  832. rules.push({
  833. mimetype: "application/wasm",
  834. ...wasm
  835. });
  836. }
  837. if (css) {
  838. const resolve = {
  839. fullySpecified: true,
  840. preferRelative: true
  841. };
  842. rules.push({
  843. test: /\.css$/i,
  844. type: CSS_MODULE_TYPE_AUTO,
  845. resolve
  846. });
  847. rules.push({
  848. mimetype: "text/css+module",
  849. type: CSS_MODULE_TYPE_MODULE,
  850. resolve
  851. });
  852. rules.push({
  853. mimetype: "text/css",
  854. type: CSS_MODULE_TYPE,
  855. resolve
  856. });
  857. }
  858. rules.push(
  859. {
  860. dependency: "url",
  861. oneOf: [
  862. {
  863. scheme: /^data$/,
  864. type: ASSET_MODULE_TYPE_INLINE
  865. },
  866. {
  867. type: ASSET_MODULE_TYPE_RESOURCE
  868. }
  869. ]
  870. },
  871. {
  872. assert: { type: JSON_MODULE_TYPE },
  873. type: JSON_MODULE_TYPE
  874. },
  875. {
  876. with: { type: JSON_MODULE_TYPE },
  877. type: JSON_MODULE_TYPE
  878. }
  879. );
  880. return rules;
  881. });
  882. };
  883. /**
  884. * @param {Output} output options
  885. * @param {object} options options
  886. * @param {string} options.context context
  887. * @param {TargetProperties | false} options.targetProperties target properties
  888. * @param {boolean} options.isAffectedByBrowserslist is affected by browserslist
  889. * @param {boolean} options.outputModule is outputModule experiment enabled
  890. * @param {boolean} options.development is development mode
  891. * @param {Entry} options.entry entry option
  892. * @param {boolean} options.futureDefaults is future defaults enabled
  893. * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
  894. * @returns {void}
  895. */
  896. const applyOutputDefaults = (
  897. output,
  898. {
  899. context,
  900. targetProperties: tp,
  901. isAffectedByBrowserslist,
  902. outputModule,
  903. development,
  904. entry,
  905. futureDefaults,
  906. asyncWebAssembly
  907. }
  908. ) => {
  909. /**
  910. * @param {Library=} library the library option
  911. * @returns {string} a readable library name
  912. */
  913. const getLibraryName = library => {
  914. const libraryName =
  915. typeof library === "object" &&
  916. library &&
  917. !Array.isArray(library) &&
  918. "type" in library
  919. ? library.name
  920. : /** @type {LibraryName} */ (library);
  921. if (Array.isArray(libraryName)) {
  922. return libraryName.join(".");
  923. } else if (typeof libraryName === "object") {
  924. return getLibraryName(libraryName.root);
  925. } else if (typeof libraryName === "string") {
  926. return libraryName;
  927. }
  928. return "";
  929. };
  930. F(output, "uniqueName", () => {
  931. const libraryName = getLibraryName(output.library).replace(
  932. /^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g,
  933. (m, a, d1, d2, b, c) => {
  934. const content = a || b || c;
  935. return content.startsWith("\\") && content.endsWith("\\")
  936. ? `${d2 || ""}[${content.slice(1, -1)}]${d1 || ""}`
  937. : "";
  938. }
  939. );
  940. if (libraryName) return libraryName;
  941. const pkgPath = path.resolve(context, "package.json");
  942. try {
  943. const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
  944. return packageInfo.name || "";
  945. } catch (err) {
  946. if (/** @type {Error & { code: string }} */ (err).code !== "ENOENT") {
  947. /** @type {Error & { code: string }} */
  948. (err).message +=
  949. `\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`;
  950. throw err;
  951. }
  952. return "";
  953. }
  954. });
  955. F(output, "module", () => Boolean(outputModule));
  956. const environment = /** @type {Environment} */ (output.environment);
  957. /**
  958. * @param {boolean | undefined} v value
  959. * @returns {boolean} true, when v is truthy or undefined
  960. */
  961. const optimistic = v => v || v === undefined;
  962. /**
  963. * @param {boolean | undefined} v value
  964. * @param {boolean | undefined} c condition
  965. * @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
  966. */
  967. const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
  968. F(
  969. environment,
  970. "globalThis",
  971. () => /** @type {boolean | undefined} */ (tp && tp.globalThis)
  972. );
  973. F(
  974. environment,
  975. "bigIntLiteral",
  976. () =>
  977. tp && optimistic(/** @type {boolean | undefined} */ (tp.bigIntLiteral))
  978. );
  979. F(
  980. environment,
  981. "const",
  982. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
  983. );
  984. F(
  985. environment,
  986. "arrowFunction",
  987. () =>
  988. tp && optimistic(/** @type {boolean | undefined} */ (tp.arrowFunction))
  989. );
  990. F(
  991. environment,
  992. "asyncFunction",
  993. () =>
  994. tp && optimistic(/** @type {boolean | undefined} */ (tp.asyncFunction))
  995. );
  996. F(
  997. environment,
  998. "forOf",
  999. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
  1000. );
  1001. F(
  1002. environment,
  1003. "destructuring",
  1004. () =>
  1005. tp && optimistic(/** @type {boolean | undefined} */ (tp.destructuring))
  1006. );
  1007. F(
  1008. environment,
  1009. "optionalChaining",
  1010. () =>
  1011. tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining))
  1012. );
  1013. F(
  1014. environment,
  1015. "nodePrefixForCoreModules",
  1016. () =>
  1017. tp &&
  1018. optimistic(
  1019. /** @type {boolean | undefined} */ (tp.nodePrefixForCoreModules)
  1020. )
  1021. );
  1022. F(
  1023. environment,
  1024. "templateLiteral",
  1025. () =>
  1026. tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral))
  1027. );
  1028. F(environment, "dynamicImport", () =>
  1029. conditionallyOptimistic(
  1030. /** @type {boolean | undefined} */ (tp && tp.dynamicImport),
  1031. output.module
  1032. )
  1033. );
  1034. F(environment, "dynamicImportInWorker", () =>
  1035. conditionallyOptimistic(
  1036. /** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker),
  1037. output.module
  1038. )
  1039. );
  1040. F(environment, "module", () =>
  1041. conditionallyOptimistic(
  1042. /** @type {boolean | undefined} */ (tp && tp.module),
  1043. output.module
  1044. )
  1045. );
  1046. F(
  1047. environment,
  1048. "document",
  1049. () => tp && optimistic(/** @type {boolean | undefined} */ (tp.document))
  1050. );
  1051. D(output, "filename", output.module ? "[name].mjs" : "[name].js");
  1052. F(output, "iife", () => !output.module);
  1053. D(output, "importFunctionName", "import");
  1054. D(output, "importMetaName", "import.meta");
  1055. F(output, "chunkFilename", () => {
  1056. const filename =
  1057. /** @type {NonNullable<Output["chunkFilename"]>} */
  1058. (output.filename);
  1059. if (typeof filename !== "function") {
  1060. const hasName = filename.includes("[name]");
  1061. const hasId = filename.includes("[id]");
  1062. const hasChunkHash = filename.includes("[chunkhash]");
  1063. const hasContentHash = filename.includes("[contenthash]");
  1064. // Anything changing depending on chunk is fine
  1065. if (hasChunkHash || hasContentHash || hasName || hasId) return filename;
  1066. // Otherwise prefix "[id]." in front of the basename to make it changing
  1067. return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");
  1068. }
  1069. return output.module ? "[id].mjs" : "[id].js";
  1070. });
  1071. F(output, "cssFilename", () => {
  1072. const filename =
  1073. /** @type {NonNullable<Output["cssFilename"]>} */
  1074. (output.filename);
  1075. if (typeof filename !== "function") {
  1076. return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
  1077. }
  1078. return "[id].css";
  1079. });
  1080. F(output, "cssChunkFilename", () => {
  1081. const chunkFilename =
  1082. /** @type {NonNullable<Output["cssChunkFilename"]>} */
  1083. (output.chunkFilename);
  1084. if (typeof chunkFilename !== "function") {
  1085. return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
  1086. }
  1087. return "[id].css";
  1088. });
  1089. D(output, "assetModuleFilename", "[hash][ext][query]");
  1090. D(output, "webassemblyModuleFilename", "[hash].module.wasm");
  1091. D(output, "compareBeforeEmit", true);
  1092. D(output, "charset", !futureDefaults);
  1093. const uniqueNameId = Template.toIdentifier(
  1094. /** @type {NonNullable<Output["uniqueName"]>} */ (output.uniqueName)
  1095. );
  1096. F(output, "hotUpdateGlobal", () => `webpackHotUpdate${uniqueNameId}`);
  1097. F(output, "chunkLoadingGlobal", () => `webpackChunk${uniqueNameId}`);
  1098. F(output, "globalObject", () => {
  1099. if (tp) {
  1100. if (tp.global) return "global";
  1101. if (tp.globalThis) return "globalThis";
  1102. }
  1103. return "self";
  1104. });
  1105. F(output, "chunkFormat", () => {
  1106. if (tp) {
  1107. const helpMessage = isAffectedByBrowserslist
  1108. ? "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."
  1109. : "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly.";
  1110. if (output.module) {
  1111. if (environment.dynamicImport) return "module";
  1112. if (tp.document) return "array-push";
  1113. throw new Error(
  1114. "For the selected environment is no default ESM chunk format available:\n" +
  1115. "ESM exports can be chosen when 'import()' is available.\n" +
  1116. `JSONP Array push can be chosen when 'document' is available.\n${
  1117. helpMessage
  1118. }`
  1119. );
  1120. } else {
  1121. if (tp.document) return "array-push";
  1122. if (tp.require) return "commonjs";
  1123. if (tp.nodeBuiltins) return "commonjs";
  1124. if (tp.importScripts) return "array-push";
  1125. throw new Error(
  1126. "For the selected environment is no default script chunk format available:\n" +
  1127. "JSONP Array push can be chosen when 'document' or 'importScripts' is available.\n" +
  1128. `CommonJs exports can be chosen when 'require' or node builtins are available.\n${
  1129. helpMessage
  1130. }`
  1131. );
  1132. }
  1133. }
  1134. throw new Error(
  1135. "Chunk format can't be selected by default when no target is specified"
  1136. );
  1137. });
  1138. D(output, "asyncChunks", true);
  1139. F(output, "chunkLoading", () => {
  1140. if (tp) {
  1141. switch (output.chunkFormat) {
  1142. case "array-push":
  1143. if (tp.document) return "jsonp";
  1144. if (tp.importScripts) return "import-scripts";
  1145. break;
  1146. case "commonjs":
  1147. if (tp.require) return "require";
  1148. if (tp.nodeBuiltins) return "async-node";
  1149. break;
  1150. case "module":
  1151. if (environment.dynamicImport) return "import";
  1152. break;
  1153. }
  1154. if (
  1155. (tp.require === null ||
  1156. tp.nodeBuiltins === null ||
  1157. tp.document === null ||
  1158. tp.importScripts === null) &&
  1159. output.module &&
  1160. environment.dynamicImport
  1161. ) {
  1162. return "universal";
  1163. }
  1164. }
  1165. return false;
  1166. });
  1167. F(output, "workerChunkLoading", () => {
  1168. if (tp) {
  1169. switch (output.chunkFormat) {
  1170. case "array-push":
  1171. if (tp.importScriptsInWorker) return "import-scripts";
  1172. break;
  1173. case "commonjs":
  1174. if (tp.require) return "require";
  1175. if (tp.nodeBuiltins) return "async-node";
  1176. break;
  1177. case "module":
  1178. if (environment.dynamicImportInWorker) return "import";
  1179. break;
  1180. }
  1181. if (
  1182. (tp.require === null ||
  1183. tp.nodeBuiltins === null ||
  1184. tp.importScriptsInWorker === null) &&
  1185. output.module &&
  1186. environment.dynamicImportInWorker
  1187. ) {
  1188. return "universal";
  1189. }
  1190. }
  1191. return false;
  1192. });
  1193. F(output, "wasmLoading", () => {
  1194. if (tp) {
  1195. if (tp.fetchWasm) return "fetch";
  1196. if (tp.nodeBuiltins) return "async-node";
  1197. if (
  1198. (tp.nodeBuiltins === null || tp.fetchWasm === null) &&
  1199. asyncWebAssembly &&
  1200. output.module &&
  1201. environment.dynamicImport
  1202. ) {
  1203. return "universal";
  1204. }
  1205. }
  1206. return false;
  1207. });
  1208. F(output, "workerWasmLoading", () => output.wasmLoading);
  1209. F(output, "devtoolNamespace", () => output.uniqueName);
  1210. if (output.library) {
  1211. F(output.library, "type", () => (output.module ? "module" : "var"));
  1212. }
  1213. F(output, "path", () => path.join(process.cwd(), "dist"));
  1214. F(output, "pathinfo", () => development);
  1215. D(output, "sourceMapFilename", "[file].map[query]");
  1216. D(
  1217. output,
  1218. "hotUpdateChunkFilename",
  1219. `[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
  1220. );
  1221. D(
  1222. output,
  1223. "hotUpdateMainFilename",
  1224. `[runtime].[fullhash].hot-update.${output.module ? "json.mjs" : "json"}`
  1225. );
  1226. D(output, "crossOriginLoading", false);
  1227. F(output, "scriptType", () => (output.module ? "module" : false));
  1228. D(
  1229. output,
  1230. "publicPath",
  1231. (tp && (tp.document || tp.importScripts)) || output.scriptType === "module"
  1232. ? "auto"
  1233. : ""
  1234. );
  1235. D(output, "workerPublicPath", "");
  1236. D(output, "chunkLoadTimeout", 120000);
  1237. F(output, "hashFunction", () => {
  1238. if (futureDefaults) {
  1239. DEFAULTS.HASH_FUNCTION = "xxhash64";
  1240. return "xxhash64";
  1241. }
  1242. return "md4";
  1243. });
  1244. D(output, "hashDigest", "hex");
  1245. D(output, "hashDigestLength", futureDefaults ? 16 : 20);
  1246. D(output, "strictModuleErrorHandling", false);
  1247. D(output, "strictModuleExceptionHandling", false);
  1248. const { trustedTypes } = output;
  1249. if (trustedTypes) {
  1250. F(
  1251. trustedTypes,
  1252. "policyName",
  1253. () =>
  1254. /** @type {NonNullable<Output["uniqueName"]>} */
  1255. (output.uniqueName).replace(/[^a-zA-Z0-9\-#=_/@.%]+/g, "_") || "webpack"
  1256. );
  1257. D(trustedTypes, "onPolicyCreationFailure", "stop");
  1258. }
  1259. /**
  1260. * @param {(entryDescription: EntryDescription) => void} fn iterator
  1261. * @returns {void}
  1262. */
  1263. const forEachEntry = fn => {
  1264. for (const name of Object.keys(entry)) {
  1265. fn(/** @type {{[k: string] : EntryDescription}} */ (entry)[name]);
  1266. }
  1267. };
  1268. A(output, "enabledLibraryTypes", () => {
  1269. /** @type {LibraryType[]} */
  1270. const enabledLibraryTypes = [];
  1271. if (output.library) {
  1272. enabledLibraryTypes.push(output.library.type);
  1273. }
  1274. forEachEntry(desc => {
  1275. if (desc.library) {
  1276. enabledLibraryTypes.push(desc.library.type);
  1277. }
  1278. });
  1279. return enabledLibraryTypes;
  1280. });
  1281. A(output, "enabledChunkLoadingTypes", () => {
  1282. const enabledChunkLoadingTypes = new Set();
  1283. if (output.chunkLoading) {
  1284. enabledChunkLoadingTypes.add(output.chunkLoading);
  1285. }
  1286. if (output.workerChunkLoading) {
  1287. enabledChunkLoadingTypes.add(output.workerChunkLoading);
  1288. }
  1289. forEachEntry(desc => {
  1290. if (desc.chunkLoading) {
  1291. enabledChunkLoadingTypes.add(desc.chunkLoading);
  1292. }
  1293. });
  1294. return [...enabledChunkLoadingTypes];
  1295. });
  1296. A(output, "enabledWasmLoadingTypes", () => {
  1297. const enabledWasmLoadingTypes = new Set();
  1298. if (output.wasmLoading) {
  1299. enabledWasmLoadingTypes.add(output.wasmLoading);
  1300. }
  1301. if (output.workerWasmLoading) {
  1302. enabledWasmLoadingTypes.add(output.workerWasmLoading);
  1303. }
  1304. forEachEntry(desc => {
  1305. if (desc.wasmLoading) {
  1306. enabledWasmLoadingTypes.add(desc.wasmLoading);
  1307. }
  1308. });
  1309. return [...enabledWasmLoadingTypes];
  1310. });
  1311. };
  1312. /**
  1313. * @param {ExternalsPresets} externalsPresets options
  1314. * @param {object} options options
  1315. * @param {TargetProperties | false} options.targetProperties target properties
  1316. * @param {boolean} options.buildHttp buildHttp experiment enabled
  1317. * @returns {void}
  1318. */
  1319. const applyExternalsPresetsDefaults = (
  1320. externalsPresets,
  1321. { targetProperties, buildHttp }
  1322. ) => {
  1323. D(
  1324. externalsPresets,
  1325. "web",
  1326. /** @type {boolean | undefined} */
  1327. (!buildHttp && targetProperties && targetProperties.web)
  1328. );
  1329. D(
  1330. externalsPresets,
  1331. "node",
  1332. /** @type {boolean | undefined} */
  1333. (targetProperties && targetProperties.node)
  1334. );
  1335. D(
  1336. externalsPresets,
  1337. "nwjs",
  1338. /** @type {boolean | undefined} */
  1339. (targetProperties && targetProperties.nwjs)
  1340. );
  1341. D(
  1342. externalsPresets,
  1343. "electron",
  1344. /** @type {boolean | undefined} */
  1345. (targetProperties && targetProperties.electron)
  1346. );
  1347. D(
  1348. externalsPresets,
  1349. "electronMain",
  1350. /** @type {boolean | undefined} */
  1351. (
  1352. targetProperties &&
  1353. targetProperties.electron &&
  1354. targetProperties.electronMain
  1355. )
  1356. );
  1357. D(
  1358. externalsPresets,
  1359. "electronPreload",
  1360. /** @type {boolean | undefined} */
  1361. (
  1362. targetProperties &&
  1363. targetProperties.electron &&
  1364. targetProperties.electronPreload
  1365. )
  1366. );
  1367. D(
  1368. externalsPresets,
  1369. "electronRenderer",
  1370. /** @type {boolean | undefined} */
  1371. (
  1372. targetProperties &&
  1373. targetProperties.electron &&
  1374. targetProperties.electronRenderer
  1375. )
  1376. );
  1377. };
  1378. /**
  1379. * @param {Loader} loader options
  1380. * @param {object} options options
  1381. * @param {TargetProperties | false} options.targetProperties target properties
  1382. * @param {Environment} options.environment environment
  1383. * @returns {void}
  1384. */
  1385. const applyLoaderDefaults = (loader, { targetProperties, environment }) => {
  1386. F(loader, "target", () => {
  1387. if (targetProperties) {
  1388. if (targetProperties.electron) {
  1389. if (targetProperties.electronMain) return "electron-main";
  1390. if (targetProperties.electronPreload) return "electron-preload";
  1391. if (targetProperties.electronRenderer) return "electron-renderer";
  1392. return "electron";
  1393. }
  1394. if (targetProperties.nwjs) return "nwjs";
  1395. if (targetProperties.node) return "node";
  1396. if (targetProperties.web) return "web";
  1397. }
  1398. });
  1399. D(loader, "environment", environment);
  1400. };
  1401. /**
  1402. * @param {WebpackNode} node options
  1403. * @param {object} options options
  1404. * @param {TargetProperties | false} options.targetProperties target properties
  1405. * @param {boolean} options.futureDefaults is future defaults enabled
  1406. * @param {boolean} options.outputModule is output type is module
  1407. * @returns {void}
  1408. */
  1409. const applyNodeDefaults = (
  1410. node,
  1411. { futureDefaults, outputModule, targetProperties }
  1412. ) => {
  1413. if (node === false) return;
  1414. F(node, "global", () => {
  1415. if (targetProperties && targetProperties.global) return false;
  1416. // TODO webpack 6 should always default to false
  1417. return futureDefaults ? "warn" : true;
  1418. });
  1419. const handlerForNames = () => {
  1420. if (targetProperties && targetProperties.node) {
  1421. return outputModule ? "node-module" : "eval-only";
  1422. }
  1423. // TODO webpack 6 should always default to false
  1424. return futureDefaults ? "warn-mock" : "mock";
  1425. };
  1426. F(node, "__filename", handlerForNames);
  1427. F(node, "__dirname", handlerForNames);
  1428. };
  1429. /**
  1430. * @param {Performance} performance options
  1431. * @param {object} options options
  1432. * @param {boolean} options.production is production
  1433. * @returns {void}
  1434. */
  1435. const applyPerformanceDefaults = (performance, { production }) => {
  1436. if (performance === false) return;
  1437. D(performance, "maxAssetSize", 250000);
  1438. D(performance, "maxEntrypointSize", 250000);
  1439. F(performance, "hints", () => (production ? "warning" : false));
  1440. };
  1441. /**
  1442. * @param {Optimization} optimization options
  1443. * @param {object} options options
  1444. * @param {boolean} options.production is production
  1445. * @param {boolean} options.development is development
  1446. * @param {boolean} options.css is css enabled
  1447. * @param {boolean} options.records using records
  1448. * @returns {void}
  1449. */
  1450. const applyOptimizationDefaults = (
  1451. optimization,
  1452. { production, development, css, records }
  1453. ) => {
  1454. D(optimization, "removeAvailableModules", false);
  1455. D(optimization, "removeEmptyChunks", true);
  1456. D(optimization, "mergeDuplicateChunks", true);
  1457. D(optimization, "flagIncludedChunks", production);
  1458. F(optimization, "moduleIds", () => {
  1459. if (production) return "deterministic";
  1460. if (development) return "named";
  1461. return "natural";
  1462. });
  1463. F(optimization, "chunkIds", () => {
  1464. if (production) return "deterministic";
  1465. if (development) return "named";
  1466. return "natural";
  1467. });
  1468. F(optimization, "sideEffects", () => (production ? true : "flag"));
  1469. D(optimization, "providedExports", true);
  1470. D(optimization, "usedExports", production);
  1471. D(optimization, "innerGraph", production);
  1472. D(optimization, "mangleExports", production);
  1473. D(optimization, "concatenateModules", production);
  1474. D(optimization, "avoidEntryIife", production);
  1475. D(optimization, "runtimeChunk", false);
  1476. D(optimization, "emitOnErrors", !production);
  1477. D(optimization, "checkWasmTypes", production);
  1478. D(optimization, "mangleWasmImports", false);
  1479. D(optimization, "portableRecords", records);
  1480. D(optimization, "realContentHash", production);
  1481. D(optimization, "minimize", production);
  1482. A(optimization, "minimizer", () => [
  1483. {
  1484. apply: compiler => {
  1485. // Lazy load the Terser plugin
  1486. const TerserPlugin = require("terser-webpack-plugin");
  1487. new TerserPlugin({
  1488. terserOptions: {
  1489. compress: {
  1490. passes: 2
  1491. }
  1492. }
  1493. }).apply(/** @type {EXPECTED_ANY} */ (compiler));
  1494. }
  1495. }
  1496. ]);
  1497. F(optimization, "nodeEnv", () => {
  1498. if (production) return "production";
  1499. if (development) return "development";
  1500. return false;
  1501. });
  1502. const { splitChunks } = optimization;
  1503. if (splitChunks) {
  1504. A(splitChunks, "defaultSizeTypes", () =>
  1505. css ? ["javascript", "css", "unknown"] : ["javascript", "unknown"]
  1506. );
  1507. D(splitChunks, "hidePathInfo", production);
  1508. D(splitChunks, "chunks", "async");
  1509. D(splitChunks, "usedExports", optimization.usedExports === true);
  1510. D(splitChunks, "minChunks", 1);
  1511. F(splitChunks, "minSize", () => (production ? 20000 : 10000));
  1512. F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined));
  1513. F(splitChunks, "enforceSizeThreshold", () => (production ? 50000 : 30000));
  1514. F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity));
  1515. F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity));
  1516. D(splitChunks, "automaticNameDelimiter", "-");
  1517. const cacheGroups =
  1518. /** @type {NonNullable<OptimizationSplitChunksOptions["cacheGroups"]>} */
  1519. (splitChunks.cacheGroups);
  1520. F(cacheGroups, "default", () => ({
  1521. idHint: "",
  1522. reuseExistingChunk: true,
  1523. minChunks: 2,
  1524. priority: -20
  1525. }));
  1526. F(cacheGroups, "defaultVendors", () => ({
  1527. idHint: "vendors",
  1528. reuseExistingChunk: true,
  1529. test: NODE_MODULES_REGEXP,
  1530. priority: -10
  1531. }));
  1532. }
  1533. };
  1534. /**
  1535. * @param {object} options options
  1536. * @param {boolean} options.cache is cache enable
  1537. * @param {string} options.context build context
  1538. * @param {TargetProperties | false} options.targetProperties target properties
  1539. * @param {Mode} options.mode mode
  1540. * @param {boolean} options.css is css enabled
  1541. * @returns {ResolveOptions} resolve options
  1542. */
  1543. const getResolveDefaults = ({
  1544. cache,
  1545. context,
  1546. targetProperties,
  1547. mode,
  1548. css
  1549. }) => {
  1550. /** @type {string[]} */
  1551. const conditions = ["webpack"];
  1552. conditions.push(mode === "development" ? "development" : "production");
  1553. if (targetProperties) {
  1554. if (targetProperties.webworker) conditions.push("worker");
  1555. if (targetProperties.node) conditions.push("node");
  1556. if (targetProperties.web) conditions.push("browser");
  1557. if (targetProperties.electron) conditions.push("electron");
  1558. if (targetProperties.nwjs) conditions.push("nwjs");
  1559. }
  1560. const jsExtensions = [".js", ".json", ".wasm"];
  1561. const tp = targetProperties;
  1562. const browserField =
  1563. tp && tp.web && (!tp.node || (tp.electron && tp.electronRenderer));
  1564. /** @type {() => ResolveOptions} */
  1565. const cjsDeps = () => ({
  1566. aliasFields: browserField ? ["browser"] : [],
  1567. mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
  1568. conditionNames: ["require", "module", "..."],
  1569. extensions: [...jsExtensions]
  1570. });
  1571. /** @type {() => ResolveOptions} */
  1572. const esmDeps = () => ({
  1573. aliasFields: browserField ? ["browser"] : [],
  1574. mainFields: browserField ? ["browser", "module", "..."] : ["module", "..."],
  1575. conditionNames: ["import", "module", "..."],
  1576. extensions: [...jsExtensions]
  1577. });
  1578. /** @type {ResolveOptions} */
  1579. const resolveOptions = {
  1580. cache,
  1581. modules: ["node_modules"],
  1582. conditionNames: conditions,
  1583. mainFiles: ["index"],
  1584. extensions: [],
  1585. aliasFields: [],
  1586. exportsFields: ["exports"],
  1587. roots: [context],
  1588. mainFields: ["main"],
  1589. importsFields: ["imports"],
  1590. byDependency: {
  1591. wasm: esmDeps(),
  1592. esm: esmDeps(),
  1593. loaderImport: esmDeps(),
  1594. url: {
  1595. preferRelative: true
  1596. },
  1597. worker: {
  1598. ...esmDeps(),
  1599. preferRelative: true
  1600. },
  1601. commonjs: cjsDeps(),
  1602. amd: cjsDeps(),
  1603. // for backward-compat: loadModule
  1604. loader: cjsDeps(),
  1605. // for backward-compat: Custom Dependency
  1606. unknown: cjsDeps(),
  1607. // for backward-compat: getResolve without dependencyType
  1608. undefined: cjsDeps()
  1609. }
  1610. };
  1611. if (css) {
  1612. const styleConditions = [];
  1613. styleConditions.push("webpack");
  1614. styleConditions.push(mode === "development" ? "development" : "production");
  1615. styleConditions.push("style");
  1616. /** @type {NonNullable<ResolveOptions["byDependency"]>} */
  1617. (resolveOptions.byDependency)["css-import"] = {
  1618. // We avoid using any main files because we have to be consistent with CSS `@import`
  1619. // and CSS `@import` does not handle `main` files in directories,
  1620. // you should always specify the full URL for styles
  1621. mainFiles: [],
  1622. mainFields: ["style", "..."],
  1623. conditionNames: styleConditions,
  1624. extensions: [".css"],
  1625. preferRelative: true
  1626. };
  1627. }
  1628. return resolveOptions;
  1629. };
  1630. /**
  1631. * @param {object} options options
  1632. * @param {boolean} options.cache is cache enable
  1633. * @returns {ResolveOptions} resolve options
  1634. */
  1635. const getResolveLoaderDefaults = ({ cache }) => {
  1636. /** @type {ResolveOptions} */
  1637. const resolveOptions = {
  1638. cache,
  1639. conditionNames: ["loader", "require", "node"],
  1640. exportsFields: ["exports"],
  1641. mainFields: ["loader", "main"],
  1642. extensions: [".js"],
  1643. mainFiles: ["index"]
  1644. };
  1645. return resolveOptions;
  1646. };
  1647. /**
  1648. * @param {InfrastructureLogging} infrastructureLogging options
  1649. * @returns {void}
  1650. */
  1651. const applyInfrastructureLoggingDefaults = infrastructureLogging => {
  1652. F(infrastructureLogging, "stream", () => process.stderr);
  1653. const tty =
  1654. /** @type {NonNullable<InfrastructureLogging["stream"]>} */
  1655. (infrastructureLogging.stream).isTTY && process.env.TERM !== "dumb";
  1656. D(infrastructureLogging, "level", "info");
  1657. D(infrastructureLogging, "debug", false);
  1658. D(infrastructureLogging, "colors", tty);
  1659. D(infrastructureLogging, "appendOnly", !tty);
  1660. };
  1661. module.exports.DEFAULTS = DEFAULTS;
  1662. module.exports.applyWebpackOptionsBaseDefaults =
  1663. applyWebpackOptionsBaseDefaults;
  1664. module.exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults;