From 9ba22d5f759c99e7418343209e57787168004167 Mon Sep 17 00:00:00 2001 From: Kirill Nagaitsev Date: Wed, 7 Aug 2019 12:44:32 -0500 Subject: [PATCH 1/3] fix(server): pass server data to exit signal setup as object --- bin/webpack-dev-server.js | 6 +++++- lib/utils/setupExitSignals.js | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 7c3456f5d3..f8a5ed20dc 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -19,8 +19,11 @@ const getVersions = require('../lib/utils/getVersions'); const options = require('./options'); let server; +const serverData = { + server: null, +}; -setupExitSignals(server); +setupExitSignals(serverData); // Prefer the local installation of webpack-dev-server if (importLocal(__filename)) { @@ -98,6 +101,7 @@ function startDevServer(config, options) { try { server = new Server(compiler, options, log); + serverData.server = server; } catch (err) { if (err.name === 'ValidationError') { log.error(colors.error(options.stats.colors, err.message)); diff --git a/lib/utils/setupExitSignals.js b/lib/utils/setupExitSignals.js index 786fc6b2f3..105b2b4273 100644 --- a/lib/utils/setupExitSignals.js +++ b/lib/utils/setupExitSignals.js @@ -2,11 +2,11 @@ const signals = ['SIGINT', 'SIGTERM']; -function setupExitSignals(server) { +function setupExitSignals(serverData) { signals.forEach((signal) => { process.on(signal, () => { - if (server) { - server.close(() => { + if (serverData.server) { + serverData.server.close(() => { // eslint-disable-next-line no-process-exit process.exit(); }); From 4d3637d0a247bf84170d2c61925138bb0c4a7f71 Mon Sep 17 00:00:00 2001 From: Kirill Nagaitsev Date: Wed, 7 Aug 2019 16:44:18 -0500 Subject: [PATCH 2/3] test(server): add exit signal tests --- bin/webpack-dev-server.js | 5 +- test/server/utils/setupExitSignals.test.js | 57 ++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/server/utils/setupExitSignals.test.js diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index f8a5ed20dc..23a788fb5a 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -22,7 +22,10 @@ let server; const serverData = { server: null, }; - +// we must pass an object that contains the server object as a property so that +// we can update this server property later, and setupExitSignals will be able to +// recognize that the server has been instantiated, because we will set +// serverData.server to the new server object. setupExitSignals(serverData); // Prefer the local installation of webpack-dev-server diff --git a/test/server/utils/setupExitSignals.test.js b/test/server/utils/setupExitSignals.test.js new file mode 100644 index 0000000000..774b88cb9d --- /dev/null +++ b/test/server/utils/setupExitSignals.test.js @@ -0,0 +1,57 @@ +'use strict'; + +const setupExitSignals = require('../../../lib/utils/setupExitSignals'); + +describe('setupExitSignals', () => { + let server; + let exitSpy; + const signals = ['SIGINT', 'SIGTERM']; + + beforeAll(() => { + exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => { }); + server = { + close: jest.fn((callback) => { + callback(); + }), + }; + }); + + afterEach(() => { + exitSpy.mockReset(); + server.close.mockClear(); + signals.forEach((signal) => { + process.removeAllListeners(signal); + }); + }); + + signals.forEach((signal) => { + it(`should exit process (${signal}, server never defined)`, (done) => { + setupExitSignals({ + server: null, + }); + process.emit(signal); + setTimeout(() => { + expect(exitSpy.mock.calls.length).toEqual(1); + done(); + }, 1000); + }); + + it(`should close server, then exit process (${signal}, server defined before signal)`, (done) => { + const serverData = { + server: null, + }; + setupExitSignals(serverData); + + setTimeout(() => { + serverData.server = server; + process.emit(signal); + }, 500); + + setTimeout(() => { + expect(server.close.mock.calls.length).toEqual(1); + expect(exitSpy.mock.calls.length).toEqual(1); + done(); + }, 1500); + }); + }); +}); From ef58382e855f68e12c2d19424e1986d662177cd6 Mon Sep 17 00:00:00 2001 From: Kirill Nagaitsev Date: Wed, 7 Aug 2019 17:19:49 -0500 Subject: [PATCH 3/3] style(test): fix lint problem --- bin/webpack-dev-server.js | 2 +- test/server/utils/setupExitSignals.test.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 23a788fb5a..286cad93b9 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -23,7 +23,7 @@ const serverData = { server: null, }; // we must pass an object that contains the server object as a property so that -// we can update this server property later, and setupExitSignals will be able to +// we can update this server property later, and setupExitSignals will be able to // recognize that the server has been instantiated, because we will set // serverData.server to the new server object. setupExitSignals(serverData); diff --git a/test/server/utils/setupExitSignals.test.js b/test/server/utils/setupExitSignals.test.js index 774b88cb9d..0f6f835591 100644 --- a/test/server/utils/setupExitSignals.test.js +++ b/test/server/utils/setupExitSignals.test.js @@ -8,7 +8,7 @@ describe('setupExitSignals', () => { const signals = ['SIGINT', 'SIGTERM']; beforeAll(() => { - exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => { }); + exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {}); server = { close: jest.fn((callback) => { callback(); @@ -41,12 +41,12 @@ describe('setupExitSignals', () => { server: null, }; setupExitSignals(serverData); - + setTimeout(() => { serverData.server = server; process.emit(signal); }, 500); - + setTimeout(() => { expect(server.close.mock.calls.length).toEqual(1); expect(exitSpy.mock.calls.length).toEqual(1);