We have a block of code where we run webpack-dev-server and then kick off Cypress and Lighthouse. In each of these blocks of code our webpack builds fine, and the server runs. However, we can no longer kill the server with server.close. It does nothing (seemingly) and just leaves the process open and running.
// webpack.config.js
new Promise((resolve, reject) => {
server.listen(port, '0.0.0.0', async () => {
try {
const results = await (open ? cypress.open(cypressConfig) : cypress.run(cypressConfig));
// Fail if there are tests that failed
if (results.totalFailed > 0) {
throw new CLIError(
`Some tests failed. See results for more details ${emoji.get('point_up')}`,
);
}
resolve(results);
} catch (err) {
// Reject on any other failures
reject(err);
} finally {
console.log('server :', server);
// Always close the server
server.close();
}
});
});
The server should close when I call server.close
The process remains open (we know this because our integration tests are failing because they hang on CI)
Use the node api to start the server and then call close on it. I can't provide a good example right now since this is code internal to the company I work for. From what I can tell though in debugging:
https://github.com/webpack/webpack-dev-server/blob/master/lib/servers/SockJSServer.js#L57
The above line doesn't work because the instance it is calling close on doesn't expose a close function. Below is the object I get back if I log out what connection is.
[ SockJSConnection {
_session:
Session {
session_id: undefined,
heartbeat_delay: 25000,
disconnect_delay: 5000,
prefix: '/sockjs-node',
send_buffer: [],
is_closing: false,
readyState: 1,
timeout_cb: [Function],
to_tref:
Timeout {
_called: false,
_idleTimeout: 25000,
_idlePrev: [TimersList],
_idleNext: [TimersList],
_idleStart: 37401,
_onTimeout: [Function],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(unrefed)]: false,
[Symbol(asyncId)]: 21090,
[Symbol(triggerId)]: 21084 },
connection: [Circular],
emit_open: null,
recv: [WebSocketReceiver] },
id: '5af72c23-aeb9-45bd-a321-0577443d1ea5',
headers:
{ host: 'localhost:34212',
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15',
origin: 'http://localhost:34212' },
prefix: '/sockjs-node',
remoteAddress: '127.0.0.1',
remotePort: 57216,
address: { address: '127.0.0.1', family: 'IPv4', port: 34212 },
url: '/sockjs-node/261/ciymzuaz/websocket',
pathname: '/sockjs-node/261/ciymzuaz/websocket',
protocol: 'websocket',
_events: [Object: null prototype] { close: [Function] },
_eventsCount: 1 } ]
The above is called via
https://github.com/webpack/webpack-dev-server/blob/master/lib/Server.js#L765
Which prior to 3.4.0, was an empty array in our case.
What I'm trying to figure out is how the change to the internal SockJS server setup is effecting this.
Can't reproduce please provide example
Hi,
A follow up on here:
We want to control what error to display to user if Webpack compilation fails in cypress command. So if webpack fails, we want to close server and exit without the Webpack long stack error message.
As below, we have a class extends from @oclif/command which this.exit should end the process
compiler.hooks.done.tap('done', (stats) => {
const fail = // Code to get if Webpack fails;
if(fail) {
server.close();
this.log(errorMessage we decide to show);
this.exit(1);
}
}
But with this.exit(1), it still shows a long error message from Webpack after our custom log. Only process.exit(1) will block the error. But it will also stop our integration test. Do you have any suggestion to close the server with out showing the long error message from Webpack?
Thanks!
@ruijieshi I can't understand you. It is related to this issue? Please provide more information (better reproducible test repo)
/cc @Aghassi Can you provide more information? Maybe problem in code? We want to freeze currently master branch and start working on next major release, so if you want to fix it asap, please provide more context and information (better simple example), thanks
@ruijieshi using compiler.hooks.done.tap for catching error from webpack-dev-server is unsafe, we return server and server have error callback, please use error callback for catching errors
@evilebottnawi I will get a demo repo together. I have not had a chance today to do so. Many meetings.
I was able to reproduce the odd behavior. See code below. The key thing is the behavior of open.
On 3.3.1 and 3.3.0 (at least) open: true doesn't actually open anything for me. This allowed server.close to function because as of 3.4.0 open: true does open a browser for me, and this blocks the server.close functionality. Expected? You tell me :)
| Version | Open Flag | Behavior |
| ---- | ---- | ---- |
| 3.3.0 | true | Browser does not open (not expected), but server.close works (process exits) |
| 3.3.0 | false | Browser does not open (expected), and server.close works (process exits) |
| 3.3.1 | true | Browser does not open (not expected), but server.close works (process exits) |
| 3.3.1 | false | Browser does not open (expected), and server.close works (process exits) |
| 3.4.0 | true | Browser does open (expected), but server.close does not work (process hangs) |
| 3.4.0 | false | Browser does not open (expected), and server.close works (process exits) |
馃棐 Latest (3.7.1) has the same behavior as 3.4.0
const WebpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');
const compiler = webpack({
module: {
rules: []
},
plugins: []
});
const server = new WebpackDevServer(compiler, {
open: true, // fails on 3.4.0, works on < 3.4.0
open: false // works on 3.4.0
});
(new Promise((resolve, reject) => {
server.listen(3000, '0.0.0.0', () => {
console.log('waiting 3s then close server and resolve');
setTimeout(() => {
server.close(() => resolve({
success: true
}));
}, 10000)
});
})).then((...args) => console.log('done', args));
@krohrsb Thank you for submitting the code. I created a pr to fix this issue. https://github.com/webpack/webpack-dev-server/pull/2001
Most helpful comment
I was able to reproduce the odd behavior. See code below. The key thing is the behavior of
open.On 3.3.1 and 3.3.0 (at least)
open: truedoesn't actually open anything for me. This allowedserver.closeto function because as of3.4.0open: truedoes open a browser for me, and this blocks theserver.closefunctionality. Expected? You tell me :)| Version | Open Flag | Behavior |
| ---- | ---- | ---- |
| 3.3.0 |
true| Browser does not open (not expected), butserver.closeworks (process exits) || 3.3.0 |
false| Browser does not open (expected), andserver.closeworks (process exits) || 3.3.1 |
true| Browser does not open (not expected), butserver.closeworks (process exits) || 3.3.1 |
false| Browser does not open (expected), andserver.closeworks (process exits) || 3.4.0 |
true| Browser does open (expected), butserver.closedoes not work (process hangs) || 3.4.0 |
false| Browser does not open (expected), andserver.closeworks (process exits) |馃棐 Latest (3.7.1) has the same behavior as 3.4.0