package.lib.config.defaults.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webpack Show documentation
Show all versions of webpack Show documentation
Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
The newest version!
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const fs = require("fs");
const path = require("path");
const {
JAVASCRIPT_MODULE_TYPE_AUTO,
JSON_MODULE_TYPE,
WEBASSEMBLY_MODULE_TYPE_ASYNC,
JAVASCRIPT_MODULE_TYPE_ESM,
JAVASCRIPT_MODULE_TYPE_DYNAMIC,
WEBASSEMBLY_MODULE_TYPE_SYNC,
ASSET_MODULE_TYPE,
CSS_MODULE_TYPE_AUTO,
CSS_MODULE_TYPE,
CSS_MODULE_TYPE_MODULE
} = require("../ModuleTypeConstants");
const Template = require("../Template");
const { cleverMerge } = require("../util/cleverMerge");
const {
getTargetsProperties,
getTargetProperties,
getDefaultTarget
} = require("./target");
/** @typedef {import("../../declarations/WebpackOptions").CacheOptions} CacheOptions */
/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptionsNormalized */
/** @typedef {import("../../declarations/WebpackOptions").Context} Context */
/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
/** @typedef {import("../../declarations/WebpackOptions").CssParserOptions} CssParserOptions */
/** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
/** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
/** @typedef {import("../../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */
/** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */
/** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
/** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
/** @typedef {import("../../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */
/** @typedef {import("../../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */
/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../../declarations/WebpackOptions").Library} Library */
/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
/** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */
/** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */
/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
/** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */
/** @typedef {import("../../declarations/WebpackOptions").Optimization} Optimization */
/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */
/** @typedef {import("../../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */
/** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */
/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
/** @typedef {import("../../declarations/WebpackOptions").Target} Target */
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("./target").PlatformTargetProperties} PlatformTargetProperties */
/** @typedef {import("./target").TargetProperties} TargetProperties */
/**
* @typedef {object} ResolvedOptions
* @property {PlatformTargetProperties | false} platform - platform target properties
*/
const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
const DEFAULT_CACHE_NAME = "default";
/**
* Sets a constant default value when undefined
* @template T
* @template {keyof T} P
* @param {T} obj an object
* @param {P} prop a property of this object
* @param {T[P]} value a default value of the property
* @returns {void}
*/
const D = (obj, prop, value) => {
if (obj[prop] === undefined) {
obj[prop] = value;
}
};
/**
* Sets a dynamic default value when undefined, by calling the factory function
* @template T
* @template {keyof T} P
* @param {T} obj an object
* @param {P} prop a property of this object
* @param {function(): T[P]} factory a default value factory for the property
* @returns {void}
*/
const F = (obj, prop, factory) => {
if (obj[prop] === undefined) {
obj[prop] = factory();
}
};
/**
* Sets a dynamic default value when undefined, by calling the factory function.
* factory must return an array or undefined
* When the current value is already an array an contains "..." it's replaced with
* the result of the factory function
* @template T
* @template {keyof T} P
* @param {T} obj an object
* @param {P} prop a property of this object
* @param {function(): T[P]} factory a default value factory for the property
* @returns {void}
*/
const A = (obj, prop, factory) => {
const value = obj[prop];
if (value === undefined) {
obj[prop] = factory();
} else if (Array.isArray(value)) {
/** @type {any[] | undefined} */
let newArray = undefined;
for (let i = 0; i < value.length; i++) {
const item = value[i];
if (item === "...") {
if (newArray === undefined) {
newArray = value.slice(0, i);
obj[prop] = /** @type {T[P]} */ (/** @type {unknown} */ (newArray));
}
const items = /** @type {any[]} */ (/** @type {unknown} */ (factory()));
if (items !== undefined) {
for (const item of items) {
newArray.push(item);
}
}
} else if (newArray !== undefined) {
newArray.push(item);
}
}
}
};
/**
* @param {WebpackOptionsNormalized} options options to be modified
* @returns {void}
*/
const applyWebpackOptionsBaseDefaults = options => {
F(options, "context", () => process.cwd());
applyInfrastructureLoggingDefaults(options.infrastructureLogging);
};
/**
* @param {WebpackOptionsNormalized} options options to be modified
* @param {number} [compilerIndex] index of compiler
* @returns {ResolvedOptions} Resolved options after apply defaults
*/
const applyWebpackOptionsDefaults = (options, compilerIndex) => {
F(options, "context", () => process.cwd());
F(options, "target", () => {
return getDefaultTarget(/** @type {string} */ (options.context));
});
const { mode, name, target } = options;
let targetProperties =
target === false
? /** @type {false} */ (false)
: typeof target === "string"
? getTargetProperties(target, /** @type {Context} */ (options.context))
: getTargetsProperties(
/** @type {string[]} */ (target),
/** @type {Context} */ (options.context)
);
const development = mode === "development";
const production = mode === "production" || !mode;
if (typeof options.entry !== "function") {
for (const key of Object.keys(options.entry)) {
F(
options.entry[key],
"import",
() => /** @type {[string]} */ (["./src"])
);
}
}
F(options, "devtool", () => (development ? "eval" : false));
D(options, "watch", false);
D(options, "profile", false);
D(options, "parallelism", 100);
D(options, "recordsInputPath", false);
D(options, "recordsOutputPath", false);
applyExperimentsDefaults(options.experiments, {
production,
development,
targetProperties
});
const futureDefaults =
/** @type {NonNullable} */
(options.experiments.futureDefaults);
F(options, "cache", () =>
development ? { type: /** @type {"memory"} */ ("memory") } : false
);
applyCacheDefaults(options.cache, {
name: name || DEFAULT_CACHE_NAME,
mode: mode || "production",
development,
cacheUnaffected: options.experiments.cacheUnaffected,
compilerIndex
});
const cache = !!options.cache;
applySnapshotDefaults(options.snapshot, {
production,
futureDefaults
});
applyModuleDefaults(options.module, {
cache,
syncWebAssembly:
/** @type {NonNullable} */
(options.experiments.syncWebAssembly),
asyncWebAssembly:
/** @type {NonNullable} */
(options.experiments.asyncWebAssembly),
css:
/** @type {NonNullable} */
(options.experiments.css),
futureDefaults,
isNode: targetProperties && targetProperties.node === true,
targetProperties
});
applyOutputDefaults(options.output, {
context: /** @type {Context} */ (options.context),
targetProperties,
isAffectedByBrowserslist:
target === undefined ||
(typeof target === "string" && target.startsWith("browserslist")) ||
(Array.isArray(target) &&
target.some(target => target.startsWith("browserslist"))),
outputModule:
/** @type {NonNullable} */
(options.experiments.outputModule),
development,
entry: options.entry,
futureDefaults
});
applyExternalsPresetsDefaults(options.externalsPresets, {
targetProperties,
buildHttp: !!options.experiments.buildHttp
});
applyLoaderDefaults(
/** @type {NonNullable} */ (
options.loader
),
{ targetProperties, environment: options.output.environment }
);
F(options, "externalsType", () => {
const validExternalTypes = require("../../schemas/WebpackOptions.json")
.definitions.ExternalsType.enum;
return options.output.library &&
validExternalTypes.includes(options.output.library.type)
? /** @type {ExternalsType} */ (options.output.library.type)
: options.output.module
? "module"
: "var";
});
applyNodeDefaults(options.node, {
futureDefaults:
/** @type {NonNullable} */
(options.experiments.futureDefaults),
outputModule: options.output.module,
targetProperties
});
F(options, "performance", () =>
production &&
targetProperties &&
(targetProperties.browser || targetProperties.browser === null)
? {}
: false
);
applyPerformanceDefaults(
/** @type {NonNullable} */
(options.performance),
{
production
}
);
applyOptimizationDefaults(options.optimization, {
development,
production,
css:
/** @type {NonNullable} */
(options.experiments.css),
records: !!(options.recordsInputPath || options.recordsOutputPath)
});
options.resolve = cleverMerge(
getResolveDefaults({
cache,
context: /** @type {Context} */ (options.context),
targetProperties,
mode: /** @type {Mode} */ (options.mode),
css:
/** @type {NonNullable} */
(options.experiments.css)
}),
options.resolve
);
options.resolveLoader = cleverMerge(
getResolveLoaderDefaults({ cache }),
options.resolveLoader
);
return {
platform:
targetProperties === false
? targetProperties
: {
web: targetProperties.web,
browser: targetProperties.browser,
webworker: targetProperties.webworker,
node: targetProperties.node,
nwjs: targetProperties.nwjs,
electron: targetProperties.electron
}
};
};
/**
* @param {ExperimentsNormalized} experiments options
* @param {object} options options
* @param {boolean} options.production is production
* @param {boolean} options.development is development mode
* @param {TargetProperties | false} options.targetProperties target properties
* @returns {void}
*/
const applyExperimentsDefaults = (
experiments,
{ production, development, targetProperties }
) => {
D(experiments, "futureDefaults", false);
D(experiments, "backCompat", !experiments.futureDefaults);
D(experiments, "syncWebAssembly", false);
D(experiments, "asyncWebAssembly", experiments.futureDefaults);
D(experiments, "outputModule", false);
D(experiments, "layers", false);
D(experiments, "lazyCompilation", undefined);
D(experiments, "buildHttp", undefined);
D(experiments, "cacheUnaffected", experiments.futureDefaults);
F(experiments, "css", () => (experiments.futureDefaults ? true : undefined));
// TODO webpack 6: remove this. topLevelAwait should be enabled by default
let shouldEnableTopLevelAwait = true;
if (typeof experiments.topLevelAwait === "boolean") {
shouldEnableTopLevelAwait = experiments.topLevelAwait;
}
D(experiments, "topLevelAwait", shouldEnableTopLevelAwait);
if (typeof experiments.buildHttp === "object") {
D(experiments.buildHttp, "frozen", production);
D(experiments.buildHttp, "upgrade", false);
}
};
/**
* @param {CacheOptionsNormalized} cache options
* @param {object} options options
* @param {string} options.name name
* @param {Mode} options.mode mode
* @param {boolean} options.development is development mode
* @param {number} [options.compilerIndex] index of compiler
* @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled
* @returns {void}
*/
const applyCacheDefaults = (
cache,
{ name, mode, development, cacheUnaffected, compilerIndex }
) => {
if (cache === false) return;
switch (cache.type) {
case "filesystem":
F(cache, "name", () =>
compilerIndex !== undefined
? `${name + "-" + mode}__compiler${compilerIndex + 1}__`
: name + "-" + mode
);
D(cache, "version", "");
F(cache, "cacheDirectory", () => {
const cwd = process.cwd();
/** @type {string | undefined} */
let dir = cwd;
for (;;) {
try {
if (fs.statSync(path.join(dir, "package.json")).isFile()) break;
// eslint-disable-next-line no-empty
} catch (e) {}
const parent = path.dirname(dir);
if (dir === parent) {
dir = undefined;
break;
}
dir = parent;
}
if (!dir) {
return path.resolve(cwd, ".cache/webpack");
} else if (process.versions.pnp === "1") {
return path.resolve(dir, ".pnp/.cache/webpack");
} else if (process.versions.pnp === "3") {
return path.resolve(dir, ".yarn/.cache/webpack");
} else {
return path.resolve(dir, "node_modules/.cache/webpack");
}
});
F(cache, "cacheLocation", () =>
path.resolve(
/** @type {NonNullable} */
(cache.cacheDirectory),
/** @type {NonNullable} */ (cache.name)
)
);
D(cache, "hashAlgorithm", "md4");
D(cache, "store", "pack");
D(cache, "compression", false);
D(cache, "profile", false);
D(cache, "idleTimeout", 60000);
D(cache, "idleTimeoutForInitialStore", 5000);
D(cache, "idleTimeoutAfterLargeChanges", 1000);
D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
D(cache, "allowCollectingMemory", development);
D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
D(cache, "readonly", false);
D(
/** @type {NonNullable} */
(cache.buildDependencies),
"defaultWebpack",
[path.resolve(__dirname, "..") + path.sep]
);
break;
case "memory":
D(cache, "maxGenerations", Infinity);
D(cache, "cacheUnaffected", development && cacheUnaffected);
break;
}
};
/**
* @param {SnapshotOptions} snapshot options
* @param {object} options options
* @param {boolean} options.production is production
* @param {boolean} options.futureDefaults is future defaults enabled
* @returns {void}
*/
const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => {
if (futureDefaults) {
F(snapshot, "managedPaths", () =>
process.versions.pnp === "3"
? [
/^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/
]
: [/^(.+?[\\/]node_modules[\\/])/]
);
F(snapshot, "immutablePaths", () =>
process.versions.pnp === "3"
? [/^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/]
: []
);
} else {
A(snapshot, "managedPaths", () => {
if (process.versions.pnp === "3") {
const match =
/^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
require.resolve("watchpack")
);
if (match) {
return [path.resolve(match[1], "unplugged")];
}
} else {
const match = /^(.+?[\\/]node_modules[\\/])/.exec(
require.resolve("watchpack")
);
if (match) {
return [match[1]];
}
}
return [];
});
A(snapshot, "immutablePaths", () => {
if (process.versions.pnp === "1") {
const match =
/^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
require.resolve("watchpack")
);
if (match) {
return [match[1]];
}
} else if (process.versions.pnp === "3") {
const match =
/^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
require.resolve("watchpack")
);
if (match) {
return [match[1]];
}
}
return [];
});
}
F(snapshot, "unmanagedPaths", () => []);
F(snapshot, "resolveBuildDependencies", () => ({
timestamp: true,
hash: true
}));
F(snapshot, "buildDependencies", () => ({ timestamp: true, hash: true }));
F(snapshot, "module", () =>
production ? { timestamp: true, hash: true } : { timestamp: true }
);
F(snapshot, "resolve", () =>
production ? { timestamp: true, hash: true } : { timestamp: true }
);
};
/**
* @param {JavascriptParserOptions} parserOptions parser options
* @param {object} options options
* @param {boolean} options.futureDefaults is future defaults enabled
* @param {boolean} options.isNode is node target platform
* @returns {void}
*/
const applyJavascriptParserOptionsDefaults = (
parserOptions,
{ futureDefaults, isNode }
) => {
D(parserOptions, "unknownContextRequest", ".");
D(parserOptions, "unknownContextRegExp", false);
D(parserOptions, "unknownContextRecursive", true);
D(parserOptions, "unknownContextCritical", true);
D(parserOptions, "exprContextRequest", ".");
D(parserOptions, "exprContextRegExp", false);
D(parserOptions, "exprContextRecursive", true);
D(parserOptions, "exprContextCritical", true);
D(parserOptions, "wrappedContextRegExp", /.*/);
D(parserOptions, "wrappedContextRecursive", true);
D(parserOptions, "wrappedContextCritical", false);
D(parserOptions, "strictThisContextOnImports", false);
D(parserOptions, "importMeta", true);
D(parserOptions, "dynamicImportMode", "lazy");
D(parserOptions, "dynamicImportPrefetch", false);
D(parserOptions, "dynamicImportPreload", false);
D(parserOptions, "dynamicImportFetchPriority", false);
D(parserOptions, "createRequire", isNode);
if (futureDefaults) D(parserOptions, "exportsPresence", "error");
};
/**
* @param {CssGeneratorOptions} generatorOptions generator options
* @param {object} options options
* @param {TargetProperties | false} options.targetProperties target properties
* @returns {void}
*/
const applyCssGeneratorOptionsDefaults = (
generatorOptions,
{ targetProperties }
) => {
D(
generatorOptions,
"exportsOnly",
!targetProperties || !targetProperties.document
);
D(generatorOptions, "esModule", true);
};
/**
* @param {ModuleOptions} module options
* @param {object} options options
* @param {boolean} options.cache is caching enabled
* @param {boolean} options.syncWebAssembly is syncWebAssembly enabled
* @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled
* @param {boolean} options.css is css enabled
* @param {boolean} options.futureDefaults is future defaults enabled
* @param {boolean} options.isNode is node target platform
* @param {TargetProperties | false} options.targetProperties target properties
* @returns {void}
*/
const applyModuleDefaults = (
module,
{
cache,
syncWebAssembly,
asyncWebAssembly,
css,
futureDefaults,
isNode,
targetProperties
}
) => {
if (cache) {
D(
module,
"unsafeCache",
/**
* @param {Module} module module
* @returns {boolean | null | string} true, if we want to cache the module
*/
module => {
const name = module.nameForCondition();
return name && NODE_MODULES_REGEXP.test(name);
}
);
} else {
D(module, "unsafeCache", false);
}
F(module.parser, ASSET_MODULE_TYPE, () => ({}));
F(
/** @type {NonNullable} */
(module.parser.asset),
"dataUrlCondition",
() => ({})
);
if (
typeof (
/** @type {NonNullable} */
(module.parser.asset).dataUrlCondition
) === "object"
) {
D(
/** @type {NonNullable} */
(module.parser.asset).dataUrlCondition,
"maxSize",
8096
);
}
F(module.parser, "javascript", () => ({}));
applyJavascriptParserOptionsDefaults(
/** @type {NonNullable} */
(module.parser.javascript),
{
futureDefaults,
isNode
}
);
if (css) {
F(module.parser, "css", () => ({}));
D(module.parser.css, "namedExports", true);
F(module.generator, "css", () => ({}));
applyCssGeneratorOptionsDefaults(
/** @type {NonNullable} */
(module.generator.css),
{ targetProperties }
);
F(module.generator, "css/auto", () => ({}));
D(
module.generator["css/auto"],
"localIdentName",
"[uniqueName]-[id]-[local]"
);
D(module.generator["css/auto"], "exportsConvention", "as-is");
F(module.generator, "css/module", () => ({}));
D(
module.generator["css/module"],
"localIdentName",
"[uniqueName]-[id]-[local]"
);
D(module.generator["css/module"], "exportsConvention", "as-is");
F(module.generator, "css/global", () => ({}));
D(
module.generator["css/global"],
"localIdentName",
"[uniqueName]-[id]-[local]"
);
D(module.generator["css/global"], "exportsConvention", "as-is");
}
A(module, "defaultRules", () => {
const esm = {
type: JAVASCRIPT_MODULE_TYPE_ESM,
resolve: {
byDependency: {
esm: {
fullySpecified: true
}
}
}
};
const commonjs = {
type: JAVASCRIPT_MODULE_TYPE_DYNAMIC
};
/** @type {RuleSetRules} */
const rules = [
{
mimetype: "application/node",
type: JAVASCRIPT_MODULE_TYPE_AUTO
},
{
test: /\.json$/i,
type: JSON_MODULE_TYPE
},
{
mimetype: "application/json",
type: JSON_MODULE_TYPE
},
{
test: /\.mjs$/i,
...esm
},
{
test: /\.js$/i,
descriptionData: {
type: "module"
},
...esm
},
{
test: /\.cjs$/i,
...commonjs
},
{
test: /\.js$/i,
descriptionData: {
type: "commonjs"
},
...commonjs
},
{
mimetype: {
or: ["text/javascript", "application/javascript"]
},
...esm
}
];
if (asyncWebAssembly) {
const wasm = {
type: WEBASSEMBLY_MODULE_TYPE_ASYNC,
rules: [
{
descriptionData: {
type: "module"
},
resolve: {
fullySpecified: true
}
}
]
};
rules.push({
test: /\.wasm$/i,
...wasm
});
rules.push({
mimetype: "application/wasm",
...wasm
});
} else if (syncWebAssembly) {
const wasm = {
type: WEBASSEMBLY_MODULE_TYPE_SYNC,
rules: [
{
descriptionData: {
type: "module"
},
resolve: {
fullySpecified: true
}
}
]
};
rules.push({
test: /\.wasm$/i,
...wasm
});
rules.push({
mimetype: "application/wasm",
...wasm
});
}
if (css) {
const resolve = {
fullySpecified: true,
preferRelative: true
};
rules.push({
test: /\.css$/i,
type: CSS_MODULE_TYPE_AUTO,
resolve
});
rules.push({
mimetype: "text/css+module",
type: CSS_MODULE_TYPE_MODULE,
resolve
});
rules.push({
mimetype: "text/css",
type: CSS_MODULE_TYPE,
resolve
});
}
rules.push(
{
dependency: "url",
oneOf: [
{
scheme: /^data$/,
type: "asset/inline"
},
{
type: "asset/resource"
}
]
},
{
assert: { type: "json" },
type: JSON_MODULE_TYPE
},
{
with: { type: "json" },
type: JSON_MODULE_TYPE
}
);
return rules;
});
};
/**
* @param {Output} output options
* @param {object} options options
* @param {string} options.context context
* @param {TargetProperties | false} options.targetProperties target properties
* @param {boolean} options.isAffectedByBrowserslist is affected by browserslist
* @param {boolean} options.outputModule is outputModule experiment enabled
* @param {boolean} options.development is development mode
* @param {Entry} options.entry entry option
* @param {boolean} options.futureDefaults is future defaults enabled
* @returns {void}
*/
const applyOutputDefaults = (
output,
{
context,
targetProperties: tp,
isAffectedByBrowserslist,
outputModule,
development,
entry,
futureDefaults
}
) => {
/**
* @param {Library=} library the library option
* @returns {string} a readable library name
*/
const getLibraryName = library => {
const libraryName =
typeof library === "object" &&
library &&
!Array.isArray(library) &&
"type" in library
? library.name
: /** @type {LibraryName} */ (library);
if (Array.isArray(libraryName)) {
return libraryName.join(".");
} else if (typeof libraryName === "object") {
return getLibraryName(libraryName.root);
} else if (typeof libraryName === "string") {
return libraryName;
}
return "";
};
F(output, "uniqueName", () => {
const libraryName = getLibraryName(output.library).replace(
/^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g,
(m, a, d1, d2, b, c) => {
const content = a || b || c;
return content.startsWith("\\") && content.endsWith("\\")
? `${d2 || ""}[${content.slice(1, -1)}]${d1 || ""}`
: "";
}
);
if (libraryName) return libraryName;
const pkgPath = path.resolve(context, "package.json");
try {
const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
return packageInfo.name || "";
} catch (e) {
if (/** @type {Error & { code: string }} */ (e).code !== "ENOENT") {
/** @type {Error & { code: string }} */
(e).message +=
`\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`;
throw e;
}
return "";
}
});
F(output, "module", () => !!outputModule);
D(output, "filename", output.module ? "[name].mjs" : "[name].js");
F(output, "iife", () => !output.module);
D(output, "importFunctionName", "import");
D(output, "importMetaName", "import.meta");
F(output, "chunkFilename", () => {
const filename =
/** @type {NonNullable