最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Wait Until Webpack Dev Server Is Ready - Stack Overflow

programmeradmin2浏览0评论

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 badges
Add a comment  | 

3 Answers 3

Reset to default 8

The 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
});
发布评论

评论列表(0)

  1. 暂无评论