From e6caf32afd709a5fbf5ff984b2eadba86cddb033 Mon Sep 17 00:00:00 2001 From: alexander-akait Date: Tue, 17 Mar 2026 14:33:40 +0300 Subject: [PATCH] fix: resolve configuration path for build dependencies --- .changeset/wild-papers-turn.md | 5 + packages/webpack-cli/src/webpack-cli.ts | 12 +- test/build/cache/base-override.config.js | 3 + test/build/cache/base.config.js | 23 +++ test/build/cache/cache.test.js | 140 ++++++++++++++++++ .../no-build-dependencies-absolute.config.js | 13 ++ .../no-build-dependencies-file.config.js | 13 ++ .../cache/no-build-dependencies.config.js | 13 ++ 8 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 .changeset/wild-papers-turn.md create mode 100644 test/build/cache/base-override.config.js create mode 100644 test/build/cache/base.config.js create mode 100644 test/build/cache/no-build-dependencies-absolute.config.js create mode 100644 test/build/cache/no-build-dependencies-file.config.js create mode 100644 test/build/cache/no-build-dependencies.config.js diff --git a/.changeset/wild-papers-turn.md b/.changeset/wild-papers-turn.md new file mode 100644 index 00000000000..55d8bac5717 --- /dev/null +++ b/.changeset/wild-papers-turn.md @@ -0,0 +1,5 @@ +--- +"webpack-cli": patch +--- + +Resolve configuration path for cache build dependencies. diff --git a/packages/webpack-cli/src/webpack-cli.ts b/packages/webpack-cli/src/webpack-cli.ts index edae3031ccb..ecdd3196373 100644 --- a/packages/webpack-cli/src/webpack-cli.ts +++ b/packages/webpack-cli/src/webpack-cli.ts @@ -2597,12 +2597,20 @@ class WebpackCLI { configuration.cache.buildDependencies.defaultConfig = []; } + const normalizeConfigPath = (configPath: string) => + configPath.startsWith("file://") ? fileURLToPath(configPath) : path.resolve(configPath); + if (Array.isArray(configPath)) { for (const oneOfConfigPath of configPath) { - configuration.cache.buildDependencies.defaultConfig.push(oneOfConfigPath); + configuration.cache.buildDependencies.defaultConfig.push( + normalizeConfigPath(oneOfConfigPath), + ); } } else { - configuration.cache.buildDependencies.defaultConfig.push(configPath); + configuration.cache.buildDependencies.defaultConfig.push( + // TODO fix `file:` support on webpack side and remove it in the next major release + normalizeConfigPath(configPath), + ); } } } diff --git a/test/build/cache/base-override.config.js b/test/build/cache/base-override.config.js new file mode 100644 index 00000000000..7dbc6cf1ead --- /dev/null +++ b/test/build/cache/base-override.config.js @@ -0,0 +1,3 @@ +module.exports = { + name: "base-override", +}; diff --git a/test/build/cache/base.config.js b/test/build/cache/base.config.js new file mode 100644 index 00000000000..4d4fbe124c0 --- /dev/null +++ b/test/build/cache/base.config.js @@ -0,0 +1,23 @@ +const path = require("node:path"); + +module.exports = { + mode: "development", + cache: { + type: "filesystem", + buildDependencies: { + config: [__filename], + }, + }, + infrastructureLogging: { + debug: /cache/, + }, + entry: { + app: "./src/main.js", + }, + output: { + filename: "[name].bundle.js", + chunkFilename: "[name].bundle.js", + path: path.resolve(__dirname, "dist"), + publicPath: "/", + }, +}; diff --git a/test/build/cache/cache.test.js b/test/build/cache/cache.test.js index 94af6a45448..d495b43395f 100644 --- a/test/build/cache/cache.test.js +++ b/test/build/cache/cache.test.js @@ -2,6 +2,7 @@ const fs = require("node:fs"); const path = require("node:path"); +const url = require("node:url"); const { isWindows, processKill, run, runWatch } = require("../../utils/test-utils"); describe("cache", () => { @@ -219,6 +220,145 @@ describe("cache", () => { expect(stdout).toBeTruthy(); }); + it("should work with relative path to configuration without build dependencies", async () => { + fs.rmSync( + path.join( + __dirname, + "../../../node_modules/.cache/webpack/no-build-dependencies-development", + ), + { recursive: true, force: true }, + ); + + let { exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + "./no-build-dependencies.config.js", + ]); + + expect(exitCode).toBe(0); + expect(stderr.match(/No pack exists at/g)).toHaveLength(1); + expect(stderr.match(/Stored pack/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + + ({ exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + "./no-build-dependencies.config.js", + ])); + + expect(exitCode).toBe(0); + expect(stderr.match(/restore cache container:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content metadata:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content \d+ \(.+\):/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + }); + + it("should work with file path to configuration without build dependencies", async () => { + fs.rmSync( + path.join( + __dirname, + "../../../node_modules/.cache/webpack/no-build-dependencies-file-development", + ), + { recursive: true, force: true }, + ); + + let { exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + path.resolve(__dirname, "./no-build-dependencies-file.config.js"), + ]); + + expect(exitCode).toBe(0); + expect(stderr.match(/No pack exists at/g)).toHaveLength(1); + expect(stderr.match(/Stored pack/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + + ({ exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + path.resolve(__dirname, "./no-build-dependencies-file.config.js"), + ])); + + expect(exitCode).toBe(0); + expect(stderr.match(/restore cache container:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content metadata:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content \d+ \(.+\):/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + }); + + it("should work with absolute path to configuration without build dependencies", async () => { + fs.rmSync( + path.join( + __dirname, + "../../../node_modules/.cache/webpack/no-build-dependencies-absolute-development", + ), + { recursive: true, force: true }, + ); + + let { exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + url + .pathToFileURL(path.resolve(__dirname, "./no-build-dependencies-absolute.config.js")) + .toString(), + ]); + + expect(exitCode).toBe(0); + expect(stderr.match(/No pack exists at/g)).toHaveLength(1); + expect(stderr.match(/Stored pack/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + + ({ exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + url + .pathToFileURL(path.resolve(__dirname, "./no-build-dependencies-absolute.config.js")) + .toString(), + ])); + + expect(exitCode).toBe(0); + expect(stderr.match(/restore cache container:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content metadata:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content \d+ \(.+\):/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + }); + + it("should work with multiple configuration and merge", async () => { + fs.rmSync( + path.join(__dirname, "../../../node_modules/.cache/webpack/base-override-development"), + { recursive: true, force: true }, + ); + + let { exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + "./base.config.js", + "-c", + url.pathToFileURL(path.resolve(__dirname, "./base-override.config.js")).toString(), + "--merge", + ]); + + expect(exitCode).toBe(0); + expect(stderr.match(/No pack exists at/g)).toHaveLength(1); + expect(stderr.match(/Stored pack/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + + ({ exitCode, stderr, stdout } = await run(__dirname, [ + "-c", + "./base.config.js", + "-c", + url.pathToFileURL(path.resolve(__dirname, "./base-override.config.js")).toString(), + "--merge", + ])); + + expect(exitCode).toBe(0); + expect(stderr.match(/restore cache container:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content metadata:/g)).toHaveLength(1); + expect(stderr.match(/restore cache content \d+ \(.+\):/g)).toHaveLength(1); + expect(stderr).toBeTruthy(); + expect(stdout).toBeTruthy(); + }); + if (!isWindows) { it("should graceful shutdown", async () => { fs.rmSync( diff --git a/test/build/cache/no-build-dependencies-absolute.config.js b/test/build/cache/no-build-dependencies-absolute.config.js new file mode 100644 index 00000000000..972d489d17b --- /dev/null +++ b/test/build/cache/no-build-dependencies-absolute.config.js @@ -0,0 +1,13 @@ +module.exports = { + name: "no-build-dependencies-absolute", + entry: { + app: "./src/main.js", + }, + mode: "development", + cache: { + type: "filesystem", + }, + infrastructureLogging: { + debug: /cache/, + }, +}; diff --git a/test/build/cache/no-build-dependencies-file.config.js b/test/build/cache/no-build-dependencies-file.config.js new file mode 100644 index 00000000000..c0c73424451 --- /dev/null +++ b/test/build/cache/no-build-dependencies-file.config.js @@ -0,0 +1,13 @@ +module.exports = { + name: "no-build-dependencies-file", + entry: { + app: "./src/main.js", + }, + mode: "development", + cache: { + type: "filesystem", + }, + infrastructureLogging: { + debug: /cache/, + }, +}; diff --git a/test/build/cache/no-build-dependencies.config.js b/test/build/cache/no-build-dependencies.config.js new file mode 100644 index 00000000000..89a041f95d0 --- /dev/null +++ b/test/build/cache/no-build-dependencies.config.js @@ -0,0 +1,13 @@ +module.exports = { + name: "no-build-dependencies", + entry: { + app: "./src/main.js", + }, + mode: "development", + cache: { + type: "filesystem", + }, + infrastructureLogging: { + debug: /cache/, + }, +};