Skip to content

Commit 4167dc8

Browse files
committed
fix: gracefull shutdown on watch/cache
1 parent f407b24 commit 4167dc8

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"test": "jest --reporters=default",
4242
"test:smoketests": "nyc node smoketests",
4343
"test:coverage": "nyc --no-clean jest",
44-
"test:cli": "jest test --reporters=default",
44+
"test:cli": "jest test/build/cache --reporters=default",
4545
"test:packages": "jest packages/ --reporters=default",
4646
"test:ci": "yarn test:cli && yarn test:packages",
4747
"test:watch": "jest test/ packages/ --watch",

packages/webpack-cli/src/webpack-cli.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,18 +2484,22 @@ class WebpackCLI implements IWebpackCLI {
24842484

24852485
compiler = await this.createCompiler(options as WebpackDevServerOptions, callback);
24862486

2487-
if (!compiler) {
2488-
return;
2489-
}
2487+
if (!compiler) return;
24902488

24912489
const isWatch = (compiler: WebpackCompiler): boolean =>
24922490
Boolean(
24932491
this.isMultipleCompiler(compiler)
24942492
? compiler.compilers.some((compiler) => compiler.options.watch)
24952493
: compiler.options.watch,
24962494
);
2495+
const isFileSystemCacheEnabled = (compiler: WebpackCompiler): boolean =>
2496+
Boolean(
2497+
this.isMultipleCompiler(compiler)
2498+
? compiler.compilers.some((compiler) => compiler.options.cache)
2499+
: compiler.options.cache,
2500+
);
24972501

2498-
if (isWatch(compiler)) {
2502+
if (isWatch(compiler) || isFileSystemCacheEnabled(compiler)) {
24992503
let needForceShutdown = false;
25002504

25012505
for (const signal of EXIT_SIGNALS) {
@@ -2508,7 +2512,6 @@ class WebpackCLI implements IWebpackCLI {
25082512
this.logger.info(
25092513
"Gracefully shutting down. To force exit, press ^C again. Please wait...",
25102514
);
2511-
25122515
needForceShutdown = true;
25132516

25142517
compiler.close(() => {

test/build/cache/cache.test.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const fs = require("node:fs");
44
const path = require("node:path");
5-
const { run } = require("../../utils/test-utils");
5+
const { processKill, run, runAndGetProcess } = require("../../utils/test-utils");
66

77
describe("cache", () => {
88
it("should work", async () => {
@@ -218,4 +218,30 @@ describe("cache", () => {
218218
expect(stderr).toBeTruthy();
219219
expect(stdout).toBeTruthy();
220220
});
221+
222+
it("should gracefully exit when cache is true", (done) => {
223+
fs.rmSync(path.join(__dirname, "../../../node_modules/.cache/webpack/graceful-exit-test"), {
224+
recursive: true,
225+
force: true,
226+
});
227+
228+
const proc = runAndGetProcess(__dirname, [
229+
"--config",
230+
"./graceful-exit.webpack.config.js",
231+
"--name",
232+
"graceful-exit-test",
233+
]);
234+
proc.stdout.on("data", (chunk) => {
235+
const data = chunk.toString();
236+
if (data.includes("app.bundle.js")) {
237+
processKill(proc);
238+
return;
239+
}
240+
expect(data).toContain(
241+
"Gracefully shutting down. To force exit, press ^C again. Please wait...",
242+
);
243+
});
244+
245+
proc.on("exit", () => done());
246+
});
221247
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const path = require("node:path");
2+
3+
class InfiniteWaitPlugin {
4+
constructor(options = {}) {
5+
this.wait = options.wait || 10e3;
6+
}
7+
8+
apply(compiler) {
9+
compiler.hooks.done.tapPromise("Graceful Exit Test", async () => {
10+
// eslint-disable-next-line no-new
11+
new Promise((res) => {
12+
setTimeout(res, this.wait);
13+
});
14+
});
15+
}
16+
}
17+
18+
module.exports = {
19+
mode: "development",
20+
name: "graceful-exit-test",
21+
cache: {
22+
type: "filesystem",
23+
buildDependencies: {
24+
config: [__filename],
25+
},
26+
},
27+
infrastructureLogging: {
28+
debug: /cache/,
29+
},
30+
entry: {
31+
app: "./src/main.js",
32+
},
33+
output: {
34+
filename: "[name].bundle.js",
35+
chunkFilename: "[name].bundle.js",
36+
path: path.resolve(__dirname, "dist"),
37+
publicPath: "/",
38+
},
39+
plugins: [new InfiniteWaitPlugin()],
40+
};

0 commit comments

Comments
 (0)