Skip to content

Commit bbe410e

Browse files
knagaitsevhiroppy
authored andcommitted
fix(server): fix setupExitSignals usage (#2181)
* fix(server): pass server data to exit signal setup as object * test(server): add exit signal tests * style(test): fix lint problem
1 parent 21e7646 commit bbe410e

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

bin/webpack-dev-server.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ const getVersions = require('../lib/utils/getVersions');
1919
const options = require('./options');
2020

2121
let server;
22-
23-
setupExitSignals(server);
22+
const serverData = {
23+
server: null,
24+
};
25+
// we must pass an object that contains the server object as a property so that
26+
// we can update this server property later, and setupExitSignals will be able to
27+
// recognize that the server has been instantiated, because we will set
28+
// serverData.server to the new server object.
29+
setupExitSignals(serverData);
2430

2531
// Prefer the local installation of webpack-dev-server
2632
if (importLocal(__filename)) {
@@ -98,6 +104,7 @@ function startDevServer(config, options) {
98104

99105
try {
100106
server = new Server(compiler, options, log);
107+
serverData.server = server;
101108
} catch (err) {
102109
if (err.name === 'ValidationError') {
103110
log.error(colors.error(options.stats.colors, err.message));

lib/utils/setupExitSignals.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
const signals = ['SIGINT', 'SIGTERM'];
44

5-
function setupExitSignals(server) {
5+
function setupExitSignals(serverData) {
66
signals.forEach((signal) => {
77
process.on(signal, () => {
8-
if (server) {
9-
server.close(() => {
8+
if (serverData.server) {
9+
serverData.server.close(() => {
1010
// eslint-disable-next-line no-process-exit
1111
process.exit();
1212
});
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
const setupExitSignals = require('../../../lib/utils/setupExitSignals');
4+
5+
describe('setupExitSignals', () => {
6+
let server;
7+
let exitSpy;
8+
const signals = ['SIGINT', 'SIGTERM'];
9+
10+
beforeAll(() => {
11+
exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {});
12+
server = {
13+
close: jest.fn((callback) => {
14+
callback();
15+
}),
16+
};
17+
});
18+
19+
afterEach(() => {
20+
exitSpy.mockReset();
21+
server.close.mockClear();
22+
signals.forEach((signal) => {
23+
process.removeAllListeners(signal);
24+
});
25+
});
26+
27+
signals.forEach((signal) => {
28+
it(`should exit process (${signal}, server never defined)`, (done) => {
29+
setupExitSignals({
30+
server: null,
31+
});
32+
process.emit(signal);
33+
setTimeout(() => {
34+
expect(exitSpy.mock.calls.length).toEqual(1);
35+
done();
36+
}, 1000);
37+
});
38+
39+
it(`should close server, then exit process (${signal}, server defined before signal)`, (done) => {
40+
const serverData = {
41+
server: null,
42+
};
43+
setupExitSignals(serverData);
44+
45+
setTimeout(() => {
46+
serverData.server = server;
47+
process.emit(signal);
48+
}, 500);
49+
50+
setTimeout(() => {
51+
expect(server.close.mock.calls.length).toEqual(1);
52+
expect(exitSpy.mock.calls.length).toEqual(1);
53+
done();
54+
}, 1500);
55+
});
56+
});
57+
});

0 commit comments

Comments
 (0)