Merge branch 'main' into feat-platform-target-properties-in-compiler

# Conflicts:
#	lib/config/defaults.js
#	lib/webpack.js
#	types.d.ts
This commit is contained in:
Ivan Kopeykin 2024-05-08 19:21:41 +03:00
commit ba6ace7f30
28 changed files with 274 additions and 22 deletions

View File

@ -11,6 +11,7 @@ const { SyncHook, MultiHook } = require("tapable");
const ConcurrentCompilationError = require("./ConcurrentCompilationError");
const MultiStats = require("./MultiStats");
const MultiWatching = require("./MultiWatching");
const WebpackError = require("./WebpackError");
const ArrayQueue = require("./util/ArrayQueue");
/** @template T @typedef {import("tapable").AsyncSeriesHook<T>} AsyncSeriesHook<T> */
@ -109,6 +110,40 @@ module.exports = class MultiCompiler {
}
});
}
this._validateCompilersOptions();
}
_validateCompilersOptions() {
if (this.compilers.length < 2) return;
/**
* @param {Compiler} compiler compiler
* @param {WebpackError} warning warning
*/
const addWarning = (compiler, warning) => {
compiler.hooks.thisCompilation.tap("MultiCompiler", compilation => {
compilation.warnings.push(warning);
});
};
const cacheNames = new Set();
for (const compiler of this.compilers) {
if (compiler.options.cache && "name" in compiler.options.cache) {
const name = compiler.options.cache.name;
if (cacheNames.has(name)) {
addWarning(
compiler,
new WebpackError(
`${
compiler.name
? `Compiler with name "${compiler.name}" doesn't use unique cache name. `
: ""
}Please set unique "cache.name" option. Name "${name}" already used.`
)
);
} else {
cacheNames.add(name);
}
}
}
}
get options() {

View File

@ -27,7 +27,8 @@ const {
getDefaultTarget
} = require("./target");
/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */
/** @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 */
@ -60,13 +61,15 @@ const {
/** @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("../../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 */
const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
const DEFAULT_CACHE_NAME = "default";
/**
* Sets a constant default value when undefined
@ -138,7 +141,7 @@ const A = (obj, prop, factory) => {
};
/**
* @param {WebpackOptions} options options to be modified
* @param {WebpackOptionsNormalized} options options to be modified
* @returns {void}
*/
const applyWebpackOptionsBaseDefaults = options => {
@ -147,10 +150,14 @@ const applyWebpackOptionsBaseDefaults = options => {
};
/**
* @param {WebpackOptions} options options to be modified
* @param {WebpackOptionsNormalized} options options to be modified
* @param {number} [compilerIndex] index of compiler
* @returns {PlatformTargetProperties|false} platform target properties
*/
const applyWebpackOptionsDefaultsAndResolveTargetProperties = options => {
const applyWebpackOptionsDefaultsAndResolveTargetProperties = (
options,
compilerIndex
) => {
F(options, "context", () => process.cwd());
F(options, "target", () => {
return getDefaultTarget(/** @type {string} */ (options.context));
@ -211,10 +218,11 @@ const applyWebpackOptionsDefaultsAndResolveTargetProperties = options => {
development ? { type: /** @type {"memory"} */ ("memory") } : false
);
applyCacheDefaults(options.cache, {
name: name || "default",
name: name || DEFAULT_CACHE_NAME,
mode: mode || "production",
development,
cacheUnaffected: options.experiments.cacheUnaffected
cacheUnaffected: options.experiments.cacheUnaffected,
compilerIndex
});
const cache = !!options.cache;
@ -261,7 +269,9 @@ const applyWebpackOptionsDefaultsAndResolveTargetProperties = options => {
});
applyLoaderDefaults(
/** @type {NonNullable<WebpackOptions["loader"]>} */ (options.loader),
/** @type {NonNullable<WebpackOptionsNormalized["loader"]>} */ (
options.loader
),
{ targetProperties, environment: options.output.environment }
);
@ -278,7 +288,7 @@ const applyWebpackOptionsDefaultsAndResolveTargetProperties = options => {
applyNodeDefaults(options.node, {
futureDefaults:
/** @type {NonNullable<WebpackOptions["experiments"]["futureDefaults"]>} */
/** @type {NonNullable<WebpackOptionsNormalized["experiments"]["futureDefaults"]>} */
(options.experiments.futureDefaults),
outputModule: options.output.module,
targetProperties
@ -292,7 +302,7 @@ const applyWebpackOptionsDefaultsAndResolveTargetProperties = options => {
: false
);
applyPerformanceDefaults(
/** @type {NonNullable<WebpackOptions["performance"]>} */
/** @type {NonNullable<WebpackOptionsNormalized["performance"]>} */
(options.performance),
{
production
@ -374,22 +384,27 @@ const applyExperimentsDefaults = (
};
/**
* @param {CacheOptions} cache options
* @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 }
{ name, mode, development, cacheUnaffected, compilerIndex }
) => {
if (cache === false) return;
switch (cache.type) {
case "filesystem":
F(cache, "name", () => name + "-" + mode);
F(cache, "name", () =>
compilerIndex !== undefined
? `${name + "-" + mode}__compiler${compilerIndex + 1}__`
: name + "-" + mode
);
D(cache, "version", "");
F(cache, "cacheDirectory", () => {
const cwd = process.cwd();

View File

@ -390,6 +390,7 @@ const subtractRuntime = (a, b) => {
}
const set = new SortableSet(a);
set.delete(b);
return set;
} else {
const set = new SortableSet();
for (const item of a) {

View File

@ -42,7 +42,9 @@ const getValidateSchema = memoize(() => require("./validateSchema"));
* @returns {MultiCompiler} a multi-compiler
*/
const createMultiCompiler = (childOptions, options) => {
const compilers = childOptions.map(options => createCompiler(options));
const compilers = childOptions.map((options, index) =>
createCompiler(options, index)
);
const compiler = new MultiCompiler(compilers, options);
for (const childCompiler of compilers) {
if (childCompiler.options.dependencies) {
@ -57,9 +59,10 @@ const createMultiCompiler = (childOptions, options) => {
/**
* @param {WebpackOptions} rawOptions options object
* @param {number} [compilerIndex] index of compiler
* @returns {Compiler} a compiler
*/
const createCompiler = rawOptions => {
const createCompiler = (rawOptions, compilerIndex) => {
const options = getNormalizedWebpackOptions(rawOptions);
applyWebpackOptionsBaseDefaults(options);
const compiler = new Compiler(
@ -80,7 +83,10 @@ const createCompiler = rawOptions => {
}
}
const platform =
applyWebpackOptionsDefaultsAndResolvePlatformTargetProperties(options);
applyWebpackOptionsDefaultsAndResolvePlatformTargetProperties(
options,
compilerIndex
);
if (platform) {
compiler.platform = platform;
}

View File

@ -66,7 +66,7 @@ const describeCases = config => {
describe(testName, function () {
const testDirectory = path.join(casesPath, category.name, testName);
const filterPath = path.join(testDirectory, "test.filter.js");
if (fs.existsSync(filterPath) && !require(filterPath)()) {
if (fs.existsSync(filterPath) && !require(filterPath)(config)) {
describe.skip(testName, () => {
it("filtered", () => {});
});
@ -113,9 +113,14 @@ const describeCases = config => {
if (config.cache) {
options.cache = {
cacheDirectory,
name: `config-${idx}`,
name:
options.cache && options.cache !== true
? options.cache.name
: `config-${idx}`,
...config.cache
};
}
if (config.cache) {
options.infrastructureLogging = {
debug: true,
console: createLogger(infraStructureLog)

View File

@ -78,6 +78,17 @@ describe("StatsTestCases", () => {
if (!options.optimization) options.optimization = {};
if (options.optimization.minimize === undefined)
options.optimization.minimize = false;
if (
options.cache &&
options.cache !== true &&
options.cache.type === "filesystem"
) {
options.cache.cacheDirectory = path.resolve(
outputBase,
".cache",
testName
);
}
});
const c = webpack(options);
const compilers = c.compilers ? c.compilers : [c];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1,33 @@
"use strict";
// default settings. should just work
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem",
name: "name2"
}
},
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem",
name: "name1"
}
},
{
mode: "production",
entry: "./index",
cache: true
},
{
mode: "production",
entry: "./index",
cache: true
}
];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1,29 @@
"use strict";
// no cache names
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem"
}
},
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem"
}
},
{
name: "3rd compiler",
mode: "production",
entry: "./index",
cache: {
type: "filesystem"
}
}
];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1,4 @@
module.exports = [
/Please set unique "cache\.name" option/,
/Compiler with name "3rd compiler" doesn't use unique cache name/
];

View File

@ -0,0 +1,32 @@
"use strict";
// with explicit cache names
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
name: "filesystem",
type: "filesystem"
}
},
{
mode: "production",
entry: "./index",
cache: {
name: "filesystem",
type: "filesystem"
}
},
{
name: "3rd compiler",
mode: "production",
entry: "./index",
cache: {
name: "filesystem",
type: "filesystem"
}
}
];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1 @@
module.exports = [/Please set unique "cache\.name" option/];

View File

@ -0,0 +1,23 @@
"use strict";
// with explicit cache names
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
name: "default",
type: "filesystem"
}
},
{
mode: "production",
entry: "./index",
cache: {
name: "default",
type: "filesystem"
}
}
];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1,22 @@
"use strict";
// no cache names
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem",
name: "default"
}
},
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem"
}
}
];

View File

@ -0,0 +1 @@
it("should build", () => {});

View File

@ -0,0 +1 @@
module.exports = config => config.cache;

View File

@ -0,0 +1,22 @@
"use strict";
// no cache names
/** @type {import("../../../../").Configuration} */
module.exports = [
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem"
}
},
{
mode: "production",
entry: "./index",
cache: {
type: "filesystem",
name: "default"
}
}
];

3
types.d.ts vendored
View File

@ -15098,7 +15098,8 @@ declare namespace exports {
config: Configuration
) => WebpackOptionsNormalized;
export const applyWebpackOptionsDefaults: (
options: WebpackOptionsNormalized
options: WebpackOptionsNormalized,
compilerIndex?: number
) => false | PlatformTargetProperties;
}
export namespace dependencies {

View File

@ -2518,9 +2518,9 @@ emojis-list@^3.0.0:
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.16.0:
version "5.16.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787"
integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==
version "5.16.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz#e8bc63d51b826d6f1cbc0a150ecb5a8b0c62e567"
integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"