Koa2 取代webpack-dev-server作为打包服务的部署方案

在上一篇热加载部署方案Koa2 + React + Eslint + Webpack热加载部署方案 中,我在后面是使用webpack-dev-server来完成热加载部署。webpack-dev-server内部是使用Express作为打包服务器。既然我们使用Koa2作为转发代理服务器,那么还不如把构建打包服务器也用Koa2来完成。

安装koa2相关的热加载模块

# 安装热加载模块
cnpm install koa-webpack-middleware -d
# koa2中使用的是async await异步中间件,
# koa-webpack-middleware返回的仍然是generator,需要用koa-convert转换下
cnpm install koa-convert -d

新建一个main.js作为构建打包服务器入口文件,文件的内容如下:

const Koa = require('koa');
const webpack = require('webpack');
const convert = require('koa-convert')
const koaWebpackMiddleware = require('koa-webpack-middleware');
const webpackDevMiddleware = koaWebpackMiddleware.devMiddleware;
const webpackHotMiddleware = koaWebpackMiddleware.hotMiddleware;
const config = require('./webpack.config')
const app = new Koa()
const compiler = webpack(config)
const PORT = process.env.PORT || 3000
const wdm = webpackDevMiddleware(compiler, {
watchOptions: {
aggregateTimeout: 300,
poll: true
},
reload: true,
publicPath: config.output.publicPath,
stats: {
colors: true
}
})
app.use(convert(wdm))
app.use(convert(webpackHotMiddleware(compiler)))
const server = app.listen(PORT, 'localhost', (err) => {
if (err) {
console.error(err)
return
}
console.log(`HMR Listening at http://localhost:${PORT}`)
})
process.on('SIGTERM', () => {
console.log('Stopping dev server')
wdm.close()
server.close(() => {
process.exit(0)
})
})

重新配置webpack.config.js

const webpack = require('webpack');
const path = require('path');
module.exports = {
context: path.resolve('./app'),
devtool: 'eval-source-map',
entry: {
index: [
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&reload=true',
'babel-polyfill',
'./main.js'
],
},
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:3000/build/',
// webpack-dev-server伺服的文件是相对publicPath这个路径的
chunkFilename: '[name].chunk.js'
},
resolve: {
// 定义了解析模块路径时的配置,常用的就是extensions,可以用来指定模块的后缀,这样在引入模块时就不需要写后缀了,会自动补全
extensions: ['.js', '.jsx']
},
module: {
loaders: [
{
test: /\.js$/,
enforce: "pre",
exclude: /node_modules/,
loader: ["eslint-loader"]
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: ['babel-loader']
},
{
test: /\.(jpg|png)$/,
loader: 'url?limit=8192'
},
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
// “If you are using the CLI, the webpack process will not exit with an error code by enabling this plugin.”
// https://github.com/webpack/docs/wiki/list-of-plugins#noerrorsplugin
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
})
]
};

这样就部署完成,但是这里有一个缺点是修改app/main.js(React代码)中的代码中,浏览器仍然无法自动更新。
这个问题我暂时没有解决方案。当然浏览器自动更新对我来说并不是完全的需求,有时候我需要用浏览器的开发者工具去查看上一个console.log(),如果浏览器自动刷新,就没法查看了。
所以如果想完全的使用热加载热更新功能,还是用上一篇博客Koa2 + React + Eslint + Webpack热加载部署方案 的方法去搭建。