项目背景

最近做的几个vue项目都使用的webpack构建,也了解了下webpack其中调试的方法,主要有以下几种:

  1. devtool configuration option
  2. webpack-dev-server
  3. webpack-dev-middleware
    这里重点说下2和3的使用。

webpack-dev-server

这是一个小型的node.js express服务器,它使用webpack-dev-middleware去处理webpack bundle。

The server emits information about the compilation state to the client, which reacts to those events. You can choose between different modes, depending on your needs.

它支持两种自动刷新方式

  1. iframe模式(使用iframe模式很简单,只要启动dev-server之后直接访问类似http://localhost:8080/webpack-dev-server/index.html路径就可以了。这是页面会被嵌入到iframe)。它有这几个特点

    -.No configuration change needed.
    -.Nice information bar on top of your app.
    -.URL changes in the app are not reflected in the browser’s URL bar.

  2. inline模式
    inline模式又分为命令行模式和node api模式

命令行模式

直接在package.json中的script字段中加入webpack命令。比如vue-cli中simple模板生成的就是这种格式

1
2
3
4
"scripts": {
"dev": "webpack-dev-server --inline --hot --no-info --port 8081",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
}

可以看出dev模式下,只需要加入–inline参数启动就可以了,需要Hot Module Replacement也就是直接加上–hot参数,十分简单方便。这种情况下,都会默认去执行webpack.config.js文件

node api模式

这种模式比cli方式要复杂。一言不合直接上已经实践的代码吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//package.json
"scripts": {
"dev:index": "node build/webpack.index.conf.js -d",
"build:index": "node build/webpack.index.conf.js -p",
"dev:producer": "node build/webpack.producer.conf.js -d",
"build:producer": "node build/webpack.producer.conf.js -p"
},
//webpack.producer.conf.js
var webpack = require('webpack');
var path = require('path');
var WebpackDevServer = require('webpack-dev-server');
var isprd = process.argv[2] === '-p';
var config = {
entry: {
app: './producerSrc/main.js'
},
output: {
publicPath: 'http://localhost:8080/static/',
path: path.resolve(__dirname, '../static'),
filename: 'producerBuild.js'
},
module: {
noParse: /es6-promise\.js$/,
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
loader: 'babel'
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
}
]
},
babel: {
presets: ['es2015'],
plugins: ['transform-runtime']
},
plugins: [],
}
var compiler;
if (isprd) {
config.plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin()
);
compiler = webpack(config);
compiler.run(function(err,stats){
if(!err)
console.log("build success")
})
} else {
module.exports.devtool = '#source-map'
config.entry.app = ["webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server"].concat(config.entry.app);
config.plugins.push(
new webpack.HotModuleReplacementPlugin()
);
compiler = webpack(config);
var server = new WebpackDevServer(compiler, {
hot: true,
noInfo: true,
filename: config.output.filename,
publicPath: config.output.publicPath
});
server.listen(8080, '127.0.0.1',function(){
console.log('Listening at http://127.0.0.1:8080');
});
}

首先要使用node api inline模式,需要将webpack-dev-server/client?http://localhost:8080/加入到所有的entry point。
要支持Hot Module Replacement,则需要

  1. 在entry point中加入”webpack/hot/dev-server”
  2. 在plugin中加入new webpack.HotModuleReplacementPlugin()
  3. 在WebpackDevServer构造方法中设置hot:true
    这里的publicPath一定要设置http://localhost:8080/static/,否则生成不了bundle.js文件.
    另外也要注意到这里prd生成compiler之后还要调用一次run方法。

webpack-dev-middleware

The webpack-dev-middleware is a small middleware for a connect-based middleware stack. It uses webpack to compile assets in-memory and serve them. When a compilation is running every request to the served webpack assets is blocked until we have a stable bundle.

webpack-dev-server就是使用它作为中间件,这里当然也可以单独剥离这个中间件出来使用。vue-cli的标准模板生成的代码使用的就是webpack-dev-middleware+express.