source: frontend/node_modules/webpack/lib/config/defaults.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

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