mirror of https://github.com/webpack/webpack.git
Merge pull request #17247 from webpack/refactor-strict-types-for-config
refactor: `strict` for config
This commit is contained in:
commit
4ca7c01e7e
|
@ -23,7 +23,7 @@ const inputRx = /^(?:((?:[A-Z]:)?[/\\].*?))?(?::(.+?))?$/i;
|
|||
*/
|
||||
|
||||
/**
|
||||
* @param {string} input input string
|
||||
* @param {string | null | undefined} input input string
|
||||
* @param {string} context the context directory
|
||||
* @returns {BrowserslistHandlerConfig} config
|
||||
*/
|
||||
|
@ -47,7 +47,7 @@ const parse = (input, context) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {string} input input string
|
||||
* @param {string | null | undefined} input input string
|
||||
* @param {string} context the context directory
|
||||
* @returns {string[] | undefined} selected browsers
|
||||
*/
|
||||
|
@ -66,7 +66,7 @@ const load = (input, context) => {
|
|||
})
|
||||
: browserslist.loadConfig({ path: context, env });
|
||||
|
||||
if (!config) return null;
|
||||
if (!config) return;
|
||||
return browserslist(config);
|
||||
};
|
||||
|
||||
|
|
|
@ -25,30 +25,39 @@ const {
|
|||
} = require("./target");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").Context} Context */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").CssExperimentOptions} CssExperimentOptions */
|
||||
/** @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").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").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Module")} Module */
|
||||
/** @typedef {import("./target").TargetProperties} TargetProperties */
|
||||
|
||||
const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
|
||||
|
@ -100,7 +109,7 @@ const A = (obj, prop, factory) => {
|
|||
if (value === undefined) {
|
||||
obj[prop] = factory();
|
||||
} else if (Array.isArray(value)) {
|
||||
/** @type {any[]} */
|
||||
/** @type {any[] | undefined} */
|
||||
let newArray = undefined;
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const item = value[i];
|
||||
|
@ -138,7 +147,7 @@ const applyWebpackOptionsBaseDefaults = options => {
|
|||
const applyWebpackOptionsDefaults = options => {
|
||||
F(options, "context", () => process.cwd());
|
||||
F(options, "target", () => {
|
||||
return getDefaultTarget(options.context);
|
||||
return getDefaultTarget(/** @type {string} */ (options.context));
|
||||
});
|
||||
|
||||
const { mode, name, target } = options;
|
||||
|
@ -147,8 +156,11 @@ const applyWebpackOptionsDefaults = options => {
|
|||
target === false
|
||||
? /** @type {false} */ (false)
|
||||
: typeof target === "string"
|
||||
? getTargetProperties(target, options.context)
|
||||
: getTargetsProperties(target, options.context);
|
||||
? getTargetProperties(target, /** @type {Context} */ (options.context))
|
||||
: getTargetsProperties(
|
||||
/** @type {string[]} */ (target),
|
||||
/** @type {Context} */ (options.context)
|
||||
);
|
||||
|
||||
const development = mode === "development";
|
||||
const production = mode === "production" || !mode;
|
||||
|
@ -176,7 +188,9 @@ const applyWebpackOptionsDefaults = options => {
|
|||
targetProperties
|
||||
});
|
||||
|
||||
const futureDefaults = options.experiments.futureDefaults;
|
||||
const futureDefaults =
|
||||
/** @type {NonNullable<ExperimentsNormalized["futureDefaults"]>} */
|
||||
(options.experiments.futureDefaults);
|
||||
|
||||
F(options, "cache", () =>
|
||||
development ? { type: /** @type {"memory"} */ ("memory") } : false
|
||||
|
@ -196,22 +210,30 @@ const applyWebpackOptionsDefaults = options => {
|
|||
|
||||
applyModuleDefaults(options.module, {
|
||||
cache,
|
||||
syncWebAssembly: options.experiments.syncWebAssembly,
|
||||
asyncWebAssembly: options.experiments.asyncWebAssembly,
|
||||
css: options.experiments.css,
|
||||
syncWebAssembly:
|
||||
/** @type {NonNullable<ExperimentsNormalized["syncWebAssembly"]>} */
|
||||
(options.experiments.syncWebAssembly),
|
||||
asyncWebAssembly:
|
||||
/** @type {NonNullable<ExperimentsNormalized["asyncWebAssembly"]>} */
|
||||
(options.experiments.asyncWebAssembly),
|
||||
css:
|
||||
/** @type {NonNullable<ExperimentsNormalized["css"]>} */
|
||||
(options.experiments.css),
|
||||
futureDefaults,
|
||||
isNode: targetProperties && targetProperties.node === true
|
||||
});
|
||||
|
||||
applyOutputDefaults(options.output, {
|
||||
context: options.context,
|
||||
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: options.experiments.outputModule,
|
||||
outputModule:
|
||||
/** @type {NonNullable<ExperimentsNormalized["outputModule"]>} */
|
||||
(options.experiments.outputModule),
|
||||
development,
|
||||
entry: options.entry,
|
||||
module: options.module,
|
||||
|
@ -223,7 +245,10 @@ const applyWebpackOptionsDefaults = options => {
|
|||
buildHttp: !!options.experiments.buildHttp
|
||||
});
|
||||
|
||||
applyLoaderDefaults(options.loader, { targetProperties });
|
||||
applyLoaderDefaults(
|
||||
/** @type {NonNullable<WebpackOptions["loader"]>} */ (options.loader),
|
||||
{ targetProperties }
|
||||
);
|
||||
|
||||
F(options, "externalsType", () => {
|
||||
const validExternalTypes = require("../../schemas/WebpackOptions.json")
|
||||
|
@ -237,7 +262,9 @@ const applyWebpackOptionsDefaults = options => {
|
|||
});
|
||||
|
||||
applyNodeDefaults(options.node, {
|
||||
futureDefaults: options.experiments.futureDefaults,
|
||||
futureDefaults:
|
||||
/** @type {NonNullable<WebpackOptions["experiments"]["futureDefaults"]>} */
|
||||
(options.experiments.futureDefaults),
|
||||
targetProperties
|
||||
});
|
||||
|
||||
|
@ -248,23 +275,29 @@ const applyWebpackOptionsDefaults = options => {
|
|||
? {}
|
||||
: false
|
||||
);
|
||||
applyPerformanceDefaults(options.performance, {
|
||||
production
|
||||
});
|
||||
applyPerformanceDefaults(
|
||||
/** @type {NonNullable<WebpackOptions["performance"]>} */
|
||||
(options.performance),
|
||||
{
|
||||
production
|
||||
}
|
||||
);
|
||||
|
||||
applyOptimizationDefaults(options.optimization, {
|
||||
development,
|
||||
production,
|
||||
css: options.experiments.css,
|
||||
css:
|
||||
/** @type {NonNullable<ExperimentsNormalized["css"]>} */
|
||||
(options.experiments.css),
|
||||
records: !!(options.recordsInputPath || options.recordsOutputPath)
|
||||
});
|
||||
|
||||
options.resolve = cleverMerge(
|
||||
getResolveDefaults({
|
||||
cache,
|
||||
context: options.context,
|
||||
context: /** @type {Context} */ (options.context),
|
||||
targetProperties,
|
||||
mode: options.mode
|
||||
mode: /** @type {Mode} */ (options.mode)
|
||||
}),
|
||||
options.resolve
|
||||
);
|
||||
|
@ -323,9 +356,9 @@ const applyExperimentsDefaults = (
|
|||
* @param {CacheOptions} cache options
|
||||
* @param {Object} options options
|
||||
* @param {string} options.name name
|
||||
* @param {string} options.mode mode
|
||||
* @param {Mode} options.mode mode
|
||||
* @param {boolean} options.development is development mode
|
||||
* @param {boolean} options.cacheUnaffected the cacheUnaffected experiment is enabled
|
||||
* @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyCacheDefaults = (
|
||||
|
@ -339,6 +372,7 @@ const applyCacheDefaults = (
|
|||
D(cache, "version", "");
|
||||
F(cache, "cacheDirectory", () => {
|
||||
const cwd = process.cwd();
|
||||
/** @type {string | undefined} */
|
||||
let dir = cwd;
|
||||
for (;;) {
|
||||
try {
|
||||
|
@ -363,7 +397,11 @@ const applyCacheDefaults = (
|
|||
}
|
||||
});
|
||||
F(cache, "cacheLocation", () =>
|
||||
path.resolve(cache.cacheDirectory, cache.name)
|
||||
path.resolve(
|
||||
/** @type {NonNullable<FileCacheOptions["cacheDirectory"]>} */
|
||||
(cache.cacheDirectory),
|
||||
/** @type {NonNullable<FileCacheOptions["name"]>} */ (cache.name)
|
||||
)
|
||||
);
|
||||
D(cache, "hashAlgorithm", "md4");
|
||||
D(cache, "store", "pack");
|
||||
|
@ -376,9 +414,12 @@ const applyCacheDefaults = (
|
|||
D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
|
||||
D(cache, "allowCollectingMemory", development);
|
||||
D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
|
||||
D(cache.buildDependencies, "defaultWebpack", [
|
||||
path.resolve(__dirname, "..") + path.sep
|
||||
]);
|
||||
D(
|
||||
/** @type {NonNullable<FileCacheOptions["buildDependencies"]>} */
|
||||
(cache.buildDependencies),
|
||||
"defaultWebpack",
|
||||
[path.resolve(__dirname, "..") + path.sep]
|
||||
);
|
||||
break;
|
||||
case "memory":
|
||||
D(cache, "maxGenerations", Infinity);
|
||||
|
@ -510,25 +551,53 @@ const applyModuleDefaults = (
|
|||
{ cache, syncWebAssembly, asyncWebAssembly, css, futureDefaults, isNode }
|
||||
) => {
|
||||
if (cache) {
|
||||
D(module, "unsafeCache", module => {
|
||||
const name = module.nameForCondition();
|
||||
return name && NODE_MODULES_REGEXP.test(name);
|
||||
});
|
||||
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(module.parser.asset, "dataUrlCondition", () => ({}));
|
||||
if (typeof module.parser.asset.dataUrlCondition === "object") {
|
||||
D(module.parser.asset.dataUrlCondition, "maxSize", 8096);
|
||||
F(
|
||||
/** @type {NonNullable<ParserOptionsByModuleTypeKnown["asset"]>} */
|
||||
(module.parser.asset),
|
||||
"dataUrlCondition",
|
||||
() => ({})
|
||||
);
|
||||
if (
|
||||
typeof (
|
||||
/** @type {NonNullable<ParserOptionsByModuleTypeKnown["asset"]>} */
|
||||
(module.parser.asset).dataUrlCondition
|
||||
) === "object"
|
||||
) {
|
||||
D(
|
||||
/** @type {NonNullable<ParserOptionsByModuleTypeKnown["asset"]>} */
|
||||
(module.parser.asset).dataUrlCondition,
|
||||
"maxSize",
|
||||
8096
|
||||
);
|
||||
}
|
||||
|
||||
F(module.parser, "javascript", () => ({}));
|
||||
applyJavascriptParserOptionsDefaults(module.parser.javascript, {
|
||||
futureDefaults,
|
||||
isNode
|
||||
});
|
||||
|
||||
applyJavascriptParserOptionsDefaults(
|
||||
/** @type {NonNullable<ParserOptionsByModuleTypeKnown["javascript"]>} */
|
||||
(module.parser.javascript),
|
||||
{
|
||||
futureDefaults,
|
||||
isNode
|
||||
}
|
||||
);
|
||||
|
||||
A(module, "defaultRules", () => {
|
||||
const esm = {
|
||||
|
@ -726,7 +795,7 @@ const applyOutputDefaults = (
|
|||
!Array.isArray(library) &&
|
||||
"type" in library
|
||||
? library.name
|
||||
: /** @type {LibraryName=} */ (library);
|
||||
: /** @type {LibraryName} */ (library);
|
||||
if (Array.isArray(libraryName)) {
|
||||
return libraryName.join(".");
|
||||
} else if (typeof libraryName === "object") {
|
||||
|
@ -753,8 +822,11 @@ const applyOutputDefaults = (
|
|||
const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
||||
return packageInfo.name || "";
|
||||
} catch (e) {
|
||||
if (e.code !== "ENOENT") {
|
||||
e.message += `\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`;
|
||||
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 "";
|
||||
|
@ -767,7 +839,9 @@ const applyOutputDefaults = (
|
|||
D(output, "importFunctionName", "import");
|
||||
D(output, "importMetaName", "import.meta");
|
||||
F(output, "chunkFilename", () => {
|
||||
const filename = output.filename;
|
||||
const filename =
|
||||
/** @type {NonNullable<Output["chunkFilename"]>} */
|
||||
(output.filename);
|
||||
if (typeof filename !== "function") {
|
||||
const hasName = filename.includes("[name]");
|
||||
const hasId = filename.includes("[id]");
|
||||
|
@ -781,14 +855,18 @@ const applyOutputDefaults = (
|
|||
return output.module ? "[id].mjs" : "[id].js";
|
||||
});
|
||||
F(output, "cssFilename", () => {
|
||||
const filename = output.filename;
|
||||
const filename =
|
||||
/** @type {NonNullable<Output["cssFilename"]>} */
|
||||
(output.filename);
|
||||
if (typeof filename !== "function") {
|
||||
return filename.replace(/\.[mc]?js(\?|$)/, ".css$1");
|
||||
}
|
||||
return "[id].css";
|
||||
});
|
||||
F(output, "cssChunkFilename", () => {
|
||||
const chunkFilename = output.chunkFilename;
|
||||
const chunkFilename =
|
||||
/** @type {NonNullable<Output["cssChunkFilename"]>} */
|
||||
(output.chunkFilename);
|
||||
if (typeof chunkFilename !== "function") {
|
||||
return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1");
|
||||
}
|
||||
|
@ -800,12 +878,18 @@ const applyOutputDefaults = (
|
|||
D(output, "charset", true);
|
||||
F(output, "hotUpdateGlobal", () =>
|
||||
Template.toIdentifier(
|
||||
"webpackHotUpdate" + Template.toIdentifier(output.uniqueName)
|
||||
"webpackHotUpdate" +
|
||||
Template.toIdentifier(
|
||||
/** @type {NonNullable<Output["uniqueName"]>} */ (output.uniqueName)
|
||||
)
|
||||
)
|
||||
);
|
||||
F(output, "chunkLoadingGlobal", () =>
|
||||
Template.toIdentifier(
|
||||
"webpackChunk" + Template.toIdentifier(output.uniqueName)
|
||||
"webpackChunk" +
|
||||
Template.toIdentifier(
|
||||
/** @type {NonNullable<Output["uniqueName"]>} */ (output.uniqueName)
|
||||
)
|
||||
)
|
||||
);
|
||||
F(output, "globalObject", () => {
|
||||
|
@ -938,26 +1022,56 @@ const applyOutputDefaults = (
|
|||
D(output, "hashDigestLength", futureDefaults ? 16 : 20);
|
||||
D(output, "strictModuleExceptionHandling", false);
|
||||
|
||||
const environment = /** @type {Environment} */ (output.environment);
|
||||
/**
|
||||
* @param {boolean | undefined} v value
|
||||
* @returns {boolean} true, when v is truthy or undefined
|
||||
*/
|
||||
const optimistic = v => v || v === undefined;
|
||||
/**
|
||||
* @param {boolean | undefined} v value
|
||||
* @param {boolean | undefined} c condition
|
||||
* @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
|
||||
*/
|
||||
const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
|
||||
F(
|
||||
output.environment,
|
||||
environment,
|
||||
"arrowFunction",
|
||||
() => tp && optimistic(tp.arrowFunction)
|
||||
() =>
|
||||
tp && optimistic(/** @type {boolean | undefined} */ (tp.arrowFunction))
|
||||
);
|
||||
F(output.environment, "const", () => tp && optimistic(tp.const));
|
||||
F(
|
||||
output.environment,
|
||||
environment,
|
||||
"const",
|
||||
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
|
||||
);
|
||||
F(
|
||||
environment,
|
||||
"destructuring",
|
||||
() => tp && optimistic(tp.destructuring)
|
||||
() =>
|
||||
tp && optimistic(/** @type {boolean | undefined} */ (tp.destructuring))
|
||||
);
|
||||
F(output.environment, "forOf", () => tp && optimistic(tp.forOf));
|
||||
F(output.environment, "bigIntLiteral", () => tp && tp.bigIntLiteral);
|
||||
F(output.environment, "dynamicImport", () =>
|
||||
conditionallyOptimistic(tp && tp.dynamicImport, output.module)
|
||||
F(
|
||||
environment,
|
||||
"forOf",
|
||||
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
|
||||
);
|
||||
F(output.environment, "module", () =>
|
||||
conditionallyOptimistic(tp && tp.module, output.module)
|
||||
F(
|
||||
environment,
|
||||
"bigIntLiteral",
|
||||
() => /** @type {boolean | undefined} */ (tp && tp.bigIntLiteral)
|
||||
);
|
||||
F(environment, "dynamicImport", () =>
|
||||
conditionallyOptimistic(
|
||||
/** @type {boolean | undefined} */ (tp && tp.dynamicImport),
|
||||
output.module
|
||||
)
|
||||
);
|
||||
F(environment, "module", () =>
|
||||
conditionallyOptimistic(
|
||||
/** @type {boolean | undefined} */ (tp && tp.module),
|
||||
output.module
|
||||
)
|
||||
);
|
||||
|
||||
const { trustedTypes } = output;
|
||||
|
@ -966,7 +1080,8 @@ const applyOutputDefaults = (
|
|||
trustedTypes,
|
||||
"policyName",
|
||||
() =>
|
||||
output.uniqueName.replace(/[^a-zA-Z0-9\-#=_/@.%]+/g, "_") || "webpack"
|
||||
/** @type {NonNullable<Output["uniqueName"]>} */
|
||||
(output.uniqueName).replace(/[^a-zA-Z0-9\-#=_/@.%]+/g, "_") || "webpack"
|
||||
);
|
||||
D(trustedTypes, "onPolicyCreationFailure", "stop");
|
||||
}
|
||||
|
@ -977,10 +1092,11 @@ const applyOutputDefaults = (
|
|||
*/
|
||||
const forEachEntry = fn => {
|
||||
for (const name of Object.keys(entry)) {
|
||||
fn(entry[name]);
|
||||
fn(/** @type {{[k: string] : EntryDescription}} */ (entry)[name]);
|
||||
}
|
||||
};
|
||||
A(output, "enabledLibraryTypes", () => {
|
||||
/** @type {LibraryType[]} */
|
||||
const enabledLibraryTypes = [];
|
||||
if (output.library) {
|
||||
enabledLibraryTypes.push(output.library.type);
|
||||
|
@ -1040,35 +1156,56 @@ const applyExternalsPresetsDefaults = (
|
|||
D(
|
||||
externalsPresets,
|
||||
"web",
|
||||
!buildHttp && targetProperties && targetProperties.web
|
||||
/** @type {boolean | undefined} */
|
||||
(!buildHttp && targetProperties && targetProperties.web)
|
||||
);
|
||||
D(
|
||||
externalsPresets,
|
||||
"node",
|
||||
/** @type {boolean | undefined} */
|
||||
(targetProperties && targetProperties.node)
|
||||
);
|
||||
D(
|
||||
externalsPresets,
|
||||
"nwjs",
|
||||
/** @type {boolean | undefined} */
|
||||
(targetProperties && targetProperties.nwjs)
|
||||
);
|
||||
D(externalsPresets, "node", targetProperties && targetProperties.node);
|
||||
D(externalsPresets, "nwjs", targetProperties && targetProperties.nwjs);
|
||||
D(
|
||||
externalsPresets,
|
||||
"electron",
|
||||
targetProperties && targetProperties.electron
|
||||
/** @type {boolean | undefined} */
|
||||
(targetProperties && targetProperties.electron)
|
||||
);
|
||||
D(
|
||||
externalsPresets,
|
||||
"electronMain",
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronMain
|
||||
/** @type {boolean | undefined} */
|
||||
(
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronMain
|
||||
)
|
||||
);
|
||||
D(
|
||||
externalsPresets,
|
||||
"electronPreload",
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronPreload
|
||||
/** @type {boolean | undefined} */
|
||||
(
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronPreload
|
||||
)
|
||||
);
|
||||
D(
|
||||
externalsPresets,
|
||||
"electronRenderer",
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronRenderer
|
||||
/** @type {boolean | undefined} */
|
||||
(
|
||||
targetProperties &&
|
||||
targetProperties.electron &&
|
||||
targetProperties.electronRenderer
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1209,7 +1346,9 @@ const applyOptimizationDefaults = (
|
|||
F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity));
|
||||
F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity));
|
||||
D(splitChunks, "automaticNameDelimiter", "-");
|
||||
const { cacheGroups } = splitChunks;
|
||||
const cacheGroups =
|
||||
/** @type {NonNullable<OptimizationSplitChunksOptions["cacheGroups"]>} */
|
||||
(splitChunks.cacheGroups);
|
||||
F(cacheGroups, "default", () => ({
|
||||
idHint: "",
|
||||
reuseExistingChunk: true,
|
||||
|
|
|
@ -7,17 +7,28 @@
|
|||
|
||||
const util = require("util");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").EntryStatic} EntryStatic */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").Externals} Externals */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptionsNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunk} OptimizationRuntimeChunk */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunkNormalized} OptimizationRuntimeChunkNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputNormalized */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").Plugins} Plugins */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */
|
||||
/** @typedef {import("../Entrypoint")} Entrypoint */
|
||||
|
||||
const handledDeprecatedNoEmitOnErrors = util.deprecate(
|
||||
/**
|
||||
* @param {boolean} noEmitOnErrors no emit on errors
|
||||
* @param {boolean | undefined} emitOnErrors emit on errors
|
||||
* @returns {boolean} emit on errors
|
||||
*/
|
||||
(noEmitOnErrors, emitOnErrors) => {
|
||||
if (emitOnErrors !== undefined && !noEmitOnErrors === !emitOnErrors) {
|
||||
throw new Error(
|
||||
|
@ -117,45 +128,50 @@ const getNormalizedWebpackOptions = config => {
|
|||
return {
|
||||
amd: config.amd,
|
||||
bail: config.bail,
|
||||
cache: optionalNestedConfig(config.cache, cache => {
|
||||
if (cache === false) return false;
|
||||
if (cache === true) {
|
||||
return {
|
||||
type: "memory",
|
||||
maxGenerations: undefined
|
||||
};
|
||||
}
|
||||
switch (cache.type) {
|
||||
case "filesystem":
|
||||
return {
|
||||
type: "filesystem",
|
||||
allowCollectingMemory: cache.allowCollectingMemory,
|
||||
maxMemoryGenerations: cache.maxMemoryGenerations,
|
||||
maxAge: cache.maxAge,
|
||||
profile: cache.profile,
|
||||
buildDependencies: cloneObject(cache.buildDependencies),
|
||||
cacheDirectory: cache.cacheDirectory,
|
||||
cacheLocation: cache.cacheLocation,
|
||||
hashAlgorithm: cache.hashAlgorithm,
|
||||
compression: cache.compression,
|
||||
idleTimeout: cache.idleTimeout,
|
||||
idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
|
||||
idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges,
|
||||
name: cache.name,
|
||||
store: cache.store,
|
||||
version: cache.version
|
||||
};
|
||||
case undefined:
|
||||
case "memory":
|
||||
return {
|
||||
type: "memory",
|
||||
maxGenerations: cache.maxGenerations
|
||||
};
|
||||
default:
|
||||
// @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
|
||||
throw new Error(`Not implemented cache.type ${cache.type}`);
|
||||
}
|
||||
}),
|
||||
cache:
|
||||
/** @type {NonNullable<CacheOptions>} */
|
||||
(
|
||||
optionalNestedConfig(config.cache, cache => {
|
||||
if (cache === false) return false;
|
||||
if (cache === true) {
|
||||
return {
|
||||
type: "memory",
|
||||
maxGenerations: undefined
|
||||
};
|
||||
}
|
||||
switch (cache.type) {
|
||||
case "filesystem":
|
||||
return {
|
||||
type: "filesystem",
|
||||
allowCollectingMemory: cache.allowCollectingMemory,
|
||||
maxMemoryGenerations: cache.maxMemoryGenerations,
|
||||
maxAge: cache.maxAge,
|
||||
profile: cache.profile,
|
||||
buildDependencies: cloneObject(cache.buildDependencies),
|
||||
cacheDirectory: cache.cacheDirectory,
|
||||
cacheLocation: cache.cacheLocation,
|
||||
hashAlgorithm: cache.hashAlgorithm,
|
||||
compression: cache.compression,
|
||||
idleTimeout: cache.idleTimeout,
|
||||
idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
|
||||
idleTimeoutAfterLargeChanges:
|
||||
cache.idleTimeoutAfterLargeChanges,
|
||||
name: cache.name,
|
||||
store: cache.store,
|
||||
version: cache.version
|
||||
};
|
||||
case undefined:
|
||||
case "memory":
|
||||
return {
|
||||
type: "memory",
|
||||
maxGenerations: cache.maxGenerations
|
||||
};
|
||||
default:
|
||||
// @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
|
||||
throw new Error(`Not implemented cache.type ${cache.type}`);
|
||||
}
|
||||
})
|
||||
),
|
||||
context: config.context,
|
||||
dependencies: config.dependencies,
|
||||
devServer: optionalNestedConfig(config.devServer, devServer => ({
|
||||
|
@ -184,7 +200,7 @@ const getNormalizedWebpackOptions = config => {
|
|||
options === true ? {} : options
|
||||
)
|
||||
})),
|
||||
externals: config.externals,
|
||||
externals: /** @type {NonNullable<Externals>} */ (config.externals),
|
||||
externalsPresets: cloneObject(config.externalsPresets),
|
||||
externalsType: config.externalsType,
|
||||
ignoreWarnings: config.ignoreWarnings
|
||||
|
@ -215,32 +231,36 @@ const getNormalizedWebpackOptions = config => {
|
|||
infrastructureLogging: cloneObject(config.infrastructureLogging),
|
||||
loader: cloneObject(config.loader),
|
||||
mode: config.mode,
|
||||
module: nestedConfig(config.module, module => ({
|
||||
noParse: module.noParse,
|
||||
unsafeCache: module.unsafeCache,
|
||||
parser: keyedNestedConfig(module.parser, cloneObject, {
|
||||
javascript: parserOptions => ({
|
||||
unknownContextRequest: module.unknownContextRequest,
|
||||
unknownContextRegExp: module.unknownContextRegExp,
|
||||
unknownContextRecursive: module.unknownContextRecursive,
|
||||
unknownContextCritical: module.unknownContextCritical,
|
||||
exprContextRequest: module.exprContextRequest,
|
||||
exprContextRegExp: module.exprContextRegExp,
|
||||
exprContextRecursive: module.exprContextRecursive,
|
||||
exprContextCritical: module.exprContextCritical,
|
||||
wrappedContextRegExp: module.wrappedContextRegExp,
|
||||
wrappedContextRecursive: module.wrappedContextRecursive,
|
||||
wrappedContextCritical: module.wrappedContextCritical,
|
||||
// TODO webpack 6 remove
|
||||
strictExportPresence: module.strictExportPresence,
|
||||
strictThisContextOnImports: module.strictThisContextOnImports,
|
||||
...parserOptions
|
||||
})
|
||||
}),
|
||||
generator: cloneObject(module.generator),
|
||||
defaultRules: optionalNestedArray(module.defaultRules, r => [...r]),
|
||||
rules: nestedArray(module.rules, r => [...r])
|
||||
})),
|
||||
module:
|
||||
/** @type {ModuleOptionsNormalized} */
|
||||
(
|
||||
nestedConfig(config.module, module => ({
|
||||
noParse: module.noParse,
|
||||
unsafeCache: module.unsafeCache,
|
||||
parser: keyedNestedConfig(module.parser, cloneObject, {
|
||||
javascript: parserOptions => ({
|
||||
unknownContextRequest: module.unknownContextRequest,
|
||||
unknownContextRegExp: module.unknownContextRegExp,
|
||||
unknownContextRecursive: module.unknownContextRecursive,
|
||||
unknownContextCritical: module.unknownContextCritical,
|
||||
exprContextRequest: module.exprContextRequest,
|
||||
exprContextRegExp: module.exprContextRegExp,
|
||||
exprContextRecursive: module.exprContextRecursive,
|
||||
exprContextCritical: module.exprContextCritical,
|
||||
wrappedContextRegExp: module.wrappedContextRegExp,
|
||||
wrappedContextRecursive: module.wrappedContextRecursive,
|
||||
wrappedContextCritical: module.wrappedContextCritical,
|
||||
// TODO webpack 6 remove
|
||||
strictExportPresence: module.strictExportPresence,
|
||||
strictThisContextOnImports: module.strictThisContextOnImports,
|
||||
...parserOptions
|
||||
})
|
||||
}),
|
||||
generator: cloneObject(module.generator),
|
||||
defaultRules: optionalNestedArray(module.defaultRules, r => [...r]),
|
||||
rules: nestedArray(module.rules, r => [...r])
|
||||
}))
|
||||
),
|
||||
name: config.name,
|
||||
node: nestedConfig(
|
||||
config.node,
|
||||
|
@ -387,7 +407,7 @@ const getNormalizedWebpackOptions = config => {
|
|||
...performance
|
||||
};
|
||||
}),
|
||||
plugins: nestedArray(config.plugins, p => [...p]),
|
||||
plugins: /** @type {Plugins} */ (nestedArray(config.plugins, p => [...p])),
|
||||
profile: config.profile,
|
||||
recordsInputPath:
|
||||
config.recordsInputPath !== undefined
|
||||
|
@ -488,8 +508,11 @@ const getNormalizedEntryStatic = entry => {
|
|||
} else {
|
||||
result[key] = {
|
||||
import:
|
||||
value.import &&
|
||||
(Array.isArray(value.import) ? value.import : [value.import]),
|
||||
/** @type {EntryDescriptionNormalized["import"]} */
|
||||
(
|
||||
value.import &&
|
||||
(Array.isArray(value.import) ? value.import : [value.import])
|
||||
),
|
||||
filename: value.filename,
|
||||
layer: value.layer,
|
||||
runtime: value.runtime,
|
||||
|
@ -499,8 +522,13 @@ const getNormalizedEntryStatic = entry => {
|
|||
asyncChunks: value.asyncChunks,
|
||||
wasmLoading: value.wasmLoading,
|
||||
dependOn:
|
||||
value.dependOn &&
|
||||
(Array.isArray(value.dependOn) ? value.dependOn : [value.dependOn]),
|
||||
/** @type {EntryDescriptionNormalized["dependOn"]} */
|
||||
(
|
||||
value.dependOn &&
|
||||
(Array.isArray(value.dependOn)
|
||||
? value.dependOn
|
||||
: [value.dependOn])
|
||||
),
|
||||
library: value.library
|
||||
};
|
||||
}
|
||||
|
@ -522,6 +550,10 @@ const getNormalizedOptimizationRuntimeChunk = runtimeChunk => {
|
|||
}
|
||||
if (runtimeChunk === true || runtimeChunk === "multiple") {
|
||||
return {
|
||||
/**
|
||||
* @param {Entrypoint} entrypoint entrypoint
|
||||
* @returns {string} runtime chunk name
|
||||
*/
|
||||
name: entrypoint => `runtime~${entrypoint.name}`
|
||||
};
|
||||
}
|
||||
|
|
|
@ -64,20 +64,39 @@ const getDefaultTarget = context => {
|
|||
*/
|
||||
|
||||
///** @typedef {PlatformTargetProperties | ApiTargetProperties | EcmaTargetProperties | PlatformTargetProperties & ApiTargetProperties | PlatformTargetProperties & EcmaTargetProperties | ApiTargetProperties & EcmaTargetProperties} TargetProperties */
|
||||
/** @template T @typedef {{ [P in keyof T]?: never }} Never<T> */
|
||||
/** @template A @template B @typedef {(A & Never<B>) | (Never<A> & B) | (A & B)} Mix<A,B> */
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {{ [P in keyof T]?: never }} Never<T>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template A
|
||||
* @template B
|
||||
* @typedef {(A & Never<B>) | (Never<A> & B) | (A & B)} Mix<A, B>
|
||||
*/
|
||||
|
||||
/** @typedef {Mix<Mix<PlatformTargetProperties, ElectronContextTargetProperties>, Mix<ApiTargetProperties, EcmaTargetProperties>>} TargetProperties */
|
||||
|
||||
/**
|
||||
* @param {string} major major version
|
||||
* @param {string | undefined} minor minor version
|
||||
* @returns {(vMajor: number, vMinor?: number) => boolean | undefined} check if version is greater or equal
|
||||
*/
|
||||
const versionDependent = (major, minor) => {
|
||||
if (!major) return () => /** @type {undefined} */ (undefined);
|
||||
major = +major;
|
||||
minor = minor ? +minor : 0;
|
||||
if (!major) {
|
||||
return () => /** @type {undefined} */ (undefined);
|
||||
}
|
||||
/** @type {number} */
|
||||
const nMajor = +major;
|
||||
/** @type {number} */
|
||||
const nMinor = minor ? +minor : 0;
|
||||
return (vMajor, vMinor = 0) => {
|
||||
return major > vMajor || (major === vMajor && minor >= vMinor);
|
||||
return nMajor > vMajor || (nMajor === vMajor && nMinor >= vMinor);
|
||||
};
|
||||
};
|
||||
|
||||
/** @type {[string, string, RegExp, (...args: string[]) => TargetProperties | false][]} */
|
||||
/** @type {[string, string, RegExp, (...args: string[]) => Partial<TargetProperties>][]} */
|
||||
const TARGETS = [
|
||||
[
|
||||
"browserslist / browserslist:env / browserslist:query / browserslist:path-to-config / browserslist:path-to-config:env",
|
||||
|
@ -95,6 +114,7 @@ See https://github.com/browserslist/browserslist#queries for possible ways to pr
|
|||
The recommended way is to add a 'browserslist' key to your package.json and list supported browsers (resp. node.js versions).
|
||||
You can also more options via the 'target' option: 'browserslist' / 'browserslist:env' / 'browserslist:query' / 'browserslist:path-to-config' / 'browserslist:path-to-config:env'`);
|
||||
}
|
||||
|
||||
return browserslistTargetHandler.resolve(browsers);
|
||||
}
|
||||
],
|
||||
|
@ -294,7 +314,7 @@ const getTargetProperties = (target, context) => {
|
|||
if (match) {
|
||||
const [, ...args] = match;
|
||||
const result = handler(...args, context);
|
||||
if (result) return result;
|
||||
if (result) return /** @type {TargetProperties} */ (result);
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
|
@ -304,13 +324,19 @@ const getTargetProperties = (target, context) => {
|
|||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {TargetProperties[]} targetProperties array of target properties
|
||||
* @returns {TargetProperties} merged target properties
|
||||
*/
|
||||
const mergeTargetProperties = targetProperties => {
|
||||
/** @type {Set<keyof TargetProperties>} */
|
||||
const keys = new Set();
|
||||
for (const tp of targetProperties) {
|
||||
for (const key of Object.keys(tp)) {
|
||||
keys.add(key);
|
||||
keys.add(/** @type {keyof TargetProperties} */ (key));
|
||||
}
|
||||
}
|
||||
/** @type {Object} */
|
||||
const result = {};
|
||||
for (const key of keys) {
|
||||
let hasTrue = false;
|
||||
|
@ -327,7 +353,8 @@ const mergeTargetProperties = targetProperties => {
|
|||
}
|
||||
}
|
||||
if (hasTrue || hasFalse)
|
||||
result[key] = hasFalse && hasTrue ? null : hasTrue ? true : false;
|
||||
/** @type {TargetProperties} */
|
||||
(result)[key] = hasFalse && hasTrue ? null : hasTrue ? true : false;
|
||||
}
|
||||
return /** @type {TargetProperties} */ (result);
|
||||
};
|
||||
|
|
|
@ -50,6 +50,9 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
return hooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ReadonlySet<string>} runtimeRequirements runtime requirements
|
||||
*/
|
||||
constructor(runtimeRequirements) {
|
||||
super("import chunk loading", RuntimeModule.STAGE_ATTACH);
|
||||
this._runtimeRequirements = runtimeRequirements;
|
||||
|
@ -112,7 +115,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
);
|
||||
const rootOutputDir = getUndoPath(
|
||||
outputName,
|
||||
this.compilation.outputOptions.path,
|
||||
/** @type {string} */ (this.compilation.outputOptions.path),
|
||||
true
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue