webpack 教程 那些事儿03-webpack两大精华插件,热加载
本节主要讲述 webpack的两大经典开发调试插件,热插拔内存缓存机制
文章目录
- 1. html-webpack-plugin插件的使用
- 2. webpack-dev-middleware 插件登场
- 3. webpack-hot-middleware 为了左手
- 4. 实现html模版更改自动刷新
- 5. 本案例测试源码下载
html-webpack-plugin插件的使用
如果没记错,上篇的时候构建完成的js文件是我们在页面用 script 标签手动引入的, 聪明的您应该马上看出问题来了,难道每次更改输出path,都要手动更新引入链接吗?如果加上 hash防止缓存,那么一串,岂不头疼欲死。有需求就有解决方案,此款插件就是用来 将依赖自动写入html文件的。
1
|
sudo cnpm i html-webpack-plugin --save-dev
|
修改配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
plugins: [
new HtmlWebpackPlugin({
filename: '../index.html',
//渲染输出html文件名,路径相对于 output.path 的值
template: path.resolve(__dirname, './app/views/index.html'),
//渲染源模版文件
inject: true
//这个东西非常重要,true: 自动写入依赖文件; false: 不写入依赖,构建多页面非常有用
})
]
<body>
<mountain></mountain>
</body>
webpack
|
查看output目录,发现多了一个 index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
background: #f90;
}
h2{
text-align: center;
font-size: 30px;
padding: 10px 0;
}
</style>
</head>
<body>
<mountain></mountain>
<script type="text/javascript" src="static/app.js"></script></body>
</html>
# 上面的script就是自动写入的依赖,src路径就是 配置文件中 output.publicPath
# 终于用到了这个调试功能
|
用chrome 打开链接http://localhost:3000/output/index.html 可以看到一样的屎黄色结果
可能聪明的您又发现了一个问题,我们每次改动一句代码,哪怕更改一个字体大小,几像素留白,就要编译打包一次才能看到结果,有没有好烦呢?
webpack-dev-middleware 插件登场
1
|
sudo cnpm i webpack-dev-middleware --save-dev
|
此插件主要结合 express的 中间件使用,修改dev-server.js,方法如下:
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
|
var express = require("express");
var app = express();
var port = process.env.PORT || 3000;
/**
* 引入webpack 及其 配置config
*/
var webpack = require("webpack");
var webpackConfig = require("./webpack.config.js");
//调用配置,生成 compiler instance
var compiler = webpack(webpackConfig);
//这里是重点,使用 webpack-dev-middleware 插件
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
chunks: false
}
})
// 注册中间件
app.use(devMiddleware);
// 使用静态资源
app.use(express.static(__dirname+'/'));
app.listen(port, function (err){
if (err) {
throw err;
}
console.log('Listening at http://localhost:' + port + '\n')
})
|
为了方便调试 和 理解什么叫 内存缓存,不写入硬盘,我们修改一点webpack配置
- 修改 output.publicPath: “/“,修改为根目录
- plugins中的filename: “index.html” ,置换到根目录
12345678910111213output: {path: path.resolve(__dirname, "./output/static"), //输出路径publicPath: '/', //调试或者 CDN 之类的域名,稍候会用到filename: "[name].js" //配置生成的文件名}plugins: [new HtmlWebpackPlugin({filename: 'index.html',template: path.resolve(__dirname, './app/views/index.html'),inject: true})]
然后,重启服务 node dev-server.js
打来浏览器输入: http://localhost:3000/index.html
哇塞,又看到了记忆中 屎黄色 的界面,有木有很开心,打开控制台,会看到这句代码
1
|
<script type="text/javascript" src="/app.js"></script>
|
惊奇的事情发生了,我们的根目录根本没有index.html 和 app.js,这些东西哪里来的呢?
这就是我们的 伟大的中间件 webpack-dev-middleware 的功劳。
然后去mountains.vue文件中修改背景色或者其他,然后刷新浏览器就能看到效果了
有木有很赞,速度还超快哦,如图改动了背景色,只需 55ms,就是快
接下来就是解放我们的双手,自动实时刷新页面.
webpack-hot-middleware 为了左手
1
2
|
# 老套路 install
sudo cnpm i webpack-hot-middleware --save-dev
|
使用步骤,参照api,很简单
-
增加插件plugins
123456789101112131415plugins: [// Webpack 1.0new webpack.optimize.OccurenceOrderPlugin(),// Webpack 2.0 fixed this mispelling// new webpack.optimize.OccurrenceOrderPlugin(),new webpack.HotModuleReplacementPlugin(),new webpack.NoErrorsPlugin(),new HtmlWebpackPlugin({filename: 'index.html',template: path.resolve(__dirname, './app/views/index.html'),inject: true})] -
Add ‘webpack-hot-middleware/client’ into the entry array(添加xx到入口数组)
1234entry: {app: ['webpack-hot-middleware/client',path.resolve(__dirname, "./app/main.js")]}更好的方法是不动基本配置,稍候会在dev-server.js中 书写 -
Add webpack-hot-middleware attached to the same compiler instance
12# dev-server.js中 app.use(devMiddleware); 之后增加app.use(require("webpack-hot-middleware")(compiler));
重新启动服务 node der-server.js
然后修改一个 body 背景,切回浏览器,哇塞,自动刷新了哦
怀着激动的心情改了一下main.js,开心的切回浏览器哇靠靠,一切都没变化,错觉?果然手动刷新, 看到了你想看到的。
你没错,是我错了,更改上面第二部的 entry参数配置如下:
1
2
3
4
|
# 增加 参数reload=true
entry: {
app: ['webpack-hot-middleware/client?noInfo=true&reload=true',path.resolve(__dirname, "./app/main.js")]
}
|
果然重启服务,一切ok.
闲的蛋疼又去,更改了.vue文件里面的 data 数据,然后。。。。问题又来了,无热加载,控制台却能看到vue文件变化消息
查了查资料:发现这可能是vue的热加载机制和策略问题,目前我不知道怎么解决。
接下来还有一件事,那就是html模版改动的自动刷新,现在是没有这个功能的,不信你试试!
实现html模版更改自动刷新
- 更改entry注入参数方式,从dev-server.js写入,example:
1
2
3
4
|
# webpack.config.js 恢复初始设置
entry: {
app: path.resolve(__dirname, "./app/main.js")
}
|
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
|
# dev-server.js
# 增加文件,刷新client单独文件配置,配合html reload
var express = require("express");
var app = express();
var port = process.env.PORT || 3000;
/**
* 引入webpack 及其 配置config
*/
var webpack = require("webpack");
var webpackConfig = require("./webpack.config.js");
// var devClient = 'webpack-hot-middleware/client?noInfo=true&reload=true';
var devClient = './dev-client';
Object.keys(webpackConfig.entry).forEach(function (name, i) {
var extras = [devClient]
webpackConfig.entry[name] = extras.concat(webpackConfig.entry[name])
})
//调用配置
var compiler = webpack(webpackConfig);
//这里是重点,使用 webpack-dev-middleware 插件
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: '/',
stats: {
colors: true,
chunks: false
}
})
var hotMiddleware = require('webpack-hot-middleware')(compiler)
// 监听html文件改变事件
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
// 发布事件 reload,这个事件会在dev-client.js中接受到,然后刷新
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// 注册中间件
app.use(devMiddleware);
app.use(hotMiddleware);
// 使用静态资源
app.use(express.static(__dirname+'/'));
app.listen(port, function (err){
if (err) {
throw err;
}
console.log('Listening at http://localhost:' + port + '\n')
})
|
dev-client.js 接受reload事件
1
2
3
4
5
6
7
8
|
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
// 订阅事件,当 event.action === 'reload' 时执行页面刷新
// 还记得 dev-server.js中 派发的reload事件吧
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
|
重启服务,修改试试?不出意外,应该万事大吉了。
ok,至此,测试程序已经结束了。下篇讲解项目中的webpack配置.