等到Webpack Dev Server准备就绪

时间:2017-03-22 00:18:41

标签: javascript node.js webpack webpack-dev-server

要求

我需要运行webpack-dev-server并等到服务器准备好提供页面。

解决方案

// 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();
    });
});

问题

在Linux上,等待服务器准备就绪。在Windows上,我得到一个例外,因为没有等待,服务器没有准备好

  

C:\ development \ ucms-react> gulp webpack-dev-server [11:03:01]要求   外部模块babel-register [11:03:07]使用gulpfile   C:\ development \ ucms-react \ gulpfile.babel.js [11:03:07]开始   'webpack-dev-server'... [11:03:07] [webpack-dev-server]   http://0.0.0.0:3000/webpack-dev-server/index.html错误events.js:141         扔掉//未处理的'错误'事件         ^

     

错误:连接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:\发展\ UCMS反应的>

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

处理此问题的一种方法是将服务器设置包装在返回Promise的函数中。 Promise在服务器连接时解析,如果出现错误则被拒绝。

这是一个简单的例子:

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);
    });
  });
}

然后提供服务器启动时的回调:

var server = startServer();

server.then(function() {
  // Run tests
});

答案 1 :(得分:3)

这是另一种解决方案(受@CameronTacklind的回答启发)。 setImmediate使日志输出显示在初始编译器日志输出的下方。

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}`)
    })
})

更新

这是不需要自定义服务器脚本的替代版本,您可以将其添加到webpack配置选项中。它还保留了默认端口不可用时自动使用其他端口的内置功能……当然,如果您希望指定端口,则不必使用该端口。

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}`)
                    )
                })
            })
        },
    }
}

答案 2 :(得分:1)

布雷特·迪伍德迪(Brett DeWoody)在这里的其他答案部分正确。它确实会等到服务器启动。但是,这并不等待创建捆绑包。因此,如果您此时要求webpack提供页面,它将返回类似于“仍在编译”的内容。


要在尝试访问页面之前等待捆绑包完全编译,您将需要以下内容:

inline style

然后,就像布雷特的回答一样,function makeServer(config) { return new Promise((resolve, reject) => { const compiler = webpack(config); const server = new WebpackDevServer(compiler, config.devServer); compiler.hooks.done.tap('IDoNotUnderstandWhatThisStringIsForButItCannotBeEmpty', () => { // console.log('Done compiling'); resolve(server); }); server.listen(port, '0.0.0.0', err => { if (err) { reject(err); } // console.log('listening'); }); }); } 结果:

await

或者没有var server = await makeServer(config); / async

await
相关问题