Requirements
I need to run the webpack-dev-server and wait until the server is ready to serve pages.
Solution
// Start a webpack-dev-server
new WebpackDevServer(webpack(myConfig), {
publicPath: myConfig.output.publicPath,
hot: true,
historyApiFallback: true,
// It suppress error shown in console, so it has to be set to false.
quiet: false,
// It suppress everything except error, so it has to be set to false as well
// to see success build.
noInfo: false,
stats: {
// Config for minimal console.log mess.
assets: false,
colors: true,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
}
}).listen(3000, '0.0.0.0', function(err) {
if(err) throw new gutil.PluginError('webpack-dev-server', err);
gutil.log('[webpack-dev-server]', ':3000/webpack-dev-server/index.html');
//this is to ensure that end to end test wouldn't start running until the server is ready
http.get({
hostname: '0.0.0.0',
port: 3000,
path: '/',
agent: false // create a new agent just for this one request
}, (/*res*/) => {
// Do stuff with response
done();
});
});
Problem
On Linux a have a wait until the server is ready. On Windows I get an exception because there is no wait and the server is not ready
C:\development\ucms-react>gulp webpack-dev-server [11:03:01] Requiring external module babel-register [11:03:07] Using gulpfile C:\development\ucms-react\gulpfile.babel.js [11:03:07] Starting 'webpack-dev-server'... [11:03:07] [webpack-dev-server] :3000/webpack-dev-server/index.html error events.js:141 throw er; // Unhandled 'error' event ^
Error: connect EADDRNOTAVAIL 0.0.0.0:3000 at Object.exports._errnoException (util.js:907:11) at exports._exceptionWithHostPort (util.js:930:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1077:14)
C:\development\ucms-react>
How can I solve this issue?
Requirements
I need to run the webpack-dev-server and wait until the server is ready to serve pages.
Solution
// Start a webpack-dev-server
new WebpackDevServer(webpack(myConfig), {
publicPath: myConfig.output.publicPath,
hot: true,
historyApiFallback: true,
// It suppress error shown in console, so it has to be set to false.
quiet: false,
// It suppress everything except error, so it has to be set to false as well
// to see success build.
noInfo: false,
stats: {
// Config for minimal console.log mess.
assets: false,
colors: true,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
}
}).listen(3000, '0.0.0.0', function(err) {
if(err) throw new gutil.PluginError('webpack-dev-server', err);
gutil.log('[webpack-dev-server]', 'http://0.0.0.0:3000/webpack-dev-server/index.html');
//this is to ensure that end to end test wouldn't start running until the server is ready
http.get({
hostname: '0.0.0.0',
port: 3000,
path: '/',
agent: false // create a new agent just for this one request
}, (/*res*/) => {
// Do stuff with response
done();
});
});
Problem
On Linux a have a wait until the server is ready. On Windows I get an exception because there is no wait and the server is not ready
C:\development\ucms-react>gulp webpack-dev-server [11:03:01] Requiring external module babel-register [11:03:07] Using gulpfile C:\development\ucms-react\gulpfile.babel.js [11:03:07] Starting 'webpack-dev-server'... [11:03:07] [webpack-dev-server] http://0.0.0.0:3000/webpack-dev-server/index.html error events.js:141 throw er; // Unhandled 'error' event ^
Error: connect EADDRNOTAVAIL 0.0.0.0:3000 at Object.exports._errnoException (util.js:907:11) at exports._exceptionWithHostPort (util.js:930:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1077:14)
C:\development\ucms-react>
How can I solve this issue?
Share Improve this question asked Mar 22, 2017 at 0:18 Marco CMarco C 3,2133 gold badges31 silver badges49 bronze badges3 Answers
Reset to default 8The other answer here by Brett DeWoody is partially correct. It does properly wait until the server is started. However this does not wait for the bundle to be created. So if you ask webpack for a page at this point, it will return something akin to "still compiling".
To wait for the bundle to be fully compiled (and that the server is listening) before trying to access a page, you'll need something like this:
function makeServer(config) {
return new Promise((resolve, reject) => {
const compiler = webpack(config);
let compiled = false;
let listening = false;
compiler.hooks.done.tap('IDoNotUnderstandWhatThisStringIsForButItCannotBeEmpty', () => {
// console.log('compiled');
if (listening) resolve(server);
else compiled = true;
});
const server = new WebpackDevServer(compiler, config.devServer);
server.listen(port, '0.0.0.0', err => {
if (err) return reject(err);
// console.log('listening');
if (compiled) resolve(server);
else listening = true;
});
});
}
Then, just like Brett's answer, await
the result:
var server = await makeServer(config);
Or without async
/await
:
makeServer(config).then(server => {
// Do something with server
});
Here's another solution (inspired by @CameronTacklind's answer). The setImmediate
makes the log output show up below the initial compiler log output.
const PORT = process.env.PORT || 3000
const compiler = webpack(config)
new WebpackDevServer(compiler).listen(PORT, '0.0.0.0', err => {
if (err) {
console.log(err)
}
})
compiler.hooks.done.tap('done', () => {
setImmediate(() => {
console.log()
console.log(`Running at http://localhost:${PORT}`)
})
})
UPDATE
Here's an alternative version that doesn't require a custom server script—you can just add this to your webpack config options. It also preserves the built-in feature of automatically using a different port if the default one isn't available...of course, if you'd rather specify your port, you don't have to use that part.
const chalk = require('chalk')
...
module.exports = {
....
devServer: {
onListening: server => {
const { port } = server.listeningApp.address()
server.compiler.hooks.done.tap('done', () => {
setImmediate(() => {
console.log()
console.log(
chalk.cyan.bold(`Running at http://localhost:${port}`)
)
})
})
},
}
}
One way to handle this is to wrap the server setup in a function that returns a Promise
. The Promise is resolved when the server connects, or is rejected if there's an error.
Here's a simplified example:
function startServer() {
return new Promise((resolve, reject) => {
new WebpackDevServer(webpack(myConfig), {
// Do stuff
}).listen(3000, '0.0.0.0', function(err) {
resolve();
}).on('error', (error) => {
reject(error);
});
});
}
and then provide a callback for when the server is started:
var server = startServer();
server.then(function() {
// Run tests
});