本节主要讲述 webpack的两大经典开发调试插件,热插拔内存缓存机制

文章目录

  1. 1. html-webpack-plugin插件的使用
  2. 2. webpack-dev-middleware 插件登场
  3. 3. webpack-hot-middleware 为了左手
  4. 4. 实现html模版更改自动刷新
  5. 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 功能选项,已经快遗忘在角落了
plugins: [
new HtmlWebpackPlugin({
filename: '../index.html',
//渲染输出html文件名,路径相对于 output.path 的值
 
template: path.resolve(__dirname, './app/views/index.html'),
//渲染源模版文件
 
inject: true
//这个东西非常重要,true: 自动写入依赖文件; false: 不写入依赖,构建多页面非常有用
})
]
 
# 自动写入依赖,所以删除app/views/index.html 的script标签链接
<body>
<mountain></mountain>
</body>
# 执行命令: webpack
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
<!DOCTYPE html>
<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” ,置换到根目录
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    output: {
    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,就是快
time

接下来就是解放我们的双手,自动实时刷新页面.

webpack-hot-middleware 为了左手

1
2
# 老套路 install
sudo cnpm i webpack-hot-middleware --save-dev

使用步骤,参照api,很简单

  • 增加插件plugins

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 注意先行引入 webpack
    # var webpack = require("webpack");
    plugins: [
    // Webpack 1.0
    new 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到入口数组)

    1
    2
    3
    4
    entry: {
    app: ['webpack-hot-middleware/client',path.resolve(__dirname, "./app/main.js")]
    }
    更好的方法是不动基本配置,稍候会在dev-server.js中 书写
  • Add webpack-hot-middleware attached to the same compiler instance

    1
    2
    # 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配置.

本案例测试源码下载

webpack 教程 那些事儿03-webpack两大精华插件,热加载的更多相关文章

  1. webpack 教程 那些事儿06-gulp+webpack多页

    本篇主要讲述用gulp+webpack构建多页应用 折腾到现在,项目还必须要进行,.vue文件必须要加载,也就是webpack必须引入.时间不多了,抛弃上个方案之后,只能牺牲热加载性能,用gulp+w ...

  2. webpack--运行npm run dev自动打开浏览器运行首页的两种方式以及热加载

    作为开发人员,我们在修改了代码之后,在vscode终端运行npm run dev指令后,希望它可以自动打开浏览器方便我们调试,有两种方式可以实现: 自动打开浏览器的两种方式: 方式一: 1.webpa ...

  3. webpack在nodejs中应用(支持es6语法及热加载)

    安装 npm i webpack webpack-cli @babel/core babel-loader @babel/preset-env @babel/node clean-webpack-pl ...

  4. webpack 教程 那些事儿04-webpack项目实战分析

    这节主要讲解真正项目用用到的 webpack配置问题,项目实战篇 就像我们不会完全做一个项目,不用别人的轮子一样.这个配置我们借用 vue-cli 搭建的配置来研究,因为它已经足够优秀. 有了前面的基 ...

  5. Webpack热加载和React(其中有关于include和exclude的路径问题)

    看了几个React配合webpack的教程,大部分都因为版本问题过时了.终于找到了一个不错的教程.记录下其中的知识点. 首先万分感谢这个教程的制作者.少走了许多弯路,正在学习webpack的小伙伴可以 ...

  6. webpack+express实现“热更新”和“热加载”(webpack3.6以前的做法)

    “热更新”:对应的是 'webpack-dev-middleware' 中间件 “热加载”:对应的是 'webpack-hot-middleware' 中间件 为了使用这两个中间件,必须修改“webp ...

  7. 如何通过webpack和node来实现多个静态页面html,多个入口,能打包能热加载开发环境调试

    demo已经传到了github,地址:https://github.com/13476075014/04.node-vue-project/tree/master/03.singlewebpack: ...

  8. 使用webpack热加载,开发多页面web应用

    我们一般使用webpack热加载开发SPA应用,但工作中难免会遇到一些多页面的demo或项目. 故参考 kingvid-chan 的代码,搭了一个使用HRM开发多页面web应用的脚手架,刚好也进一步学 ...

  9. webpack无法热加载(__webpack_hmr 502)

    最近本地开发项目代码一直无法热加载,于是就抽空想办法解决 我们线上的地址是:https://aitest.ichuanyi.com/ai-admin/#/  其实ai-admin是线上的一个目录 所以 ...

随机推荐

  1. HTML 速查列表

    HTML 基本文档 <!DOCTYPE html> <html> <head> <title>文档标题</title> </head& ...

  2. python 遍历文件夹 文件

    python 遍历文件夹 文件   import os import os.path rootdir = "d:\data" # 指明被遍历的文件夹 for parent,dirn ...

  3. js013-事件

    js013-事件 本章内容 理解事件流 使用时间处理程序 不同的事件类型 JS与HTML之间的交互是通过实践实现的.时间就还文档或浏览器窗口发生的一些特定的交互 瞬间.可以使用侦听器来预定事件,以便时 ...

  4. EnableViewState

    EnableViewState 系统默认的值为true,在传递状态值时就包括该控件: 为false,则传递状态值时则不包括它. 可以提高网络访问的速度. 某些控件是不需要接受用户的操作或只需要接受一次 ...

  5. re正则表达式5_*

    *表示匹配[0,正无穷大]次 * means math zero or more-----occur any number of times in the text. # -*- coding: ut ...

  6. Winsock 入门 Echo 示例

    #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32") /* Win ...

  7. Apple Instruments

    启动Xcode,选择Xcode > Open Developer Tool > Instruments. 如果无法选择当前设备,请尝试重启设备. 将设备设置为Use for develop ...

  8. ecshop广告-》单张,多张

    //读取广告 function get_ad_id($ad_id){ //读取指定ad_id广告 $sql = 'select * from '. $GLOBALS['ecs']->table( ...

  9. ecshop变量介绍

    获得商品的信息,get_goods_info($goods_id) 获取前10销量排名,get_top10()

  10. MFS文件系统

    一.MFS文件系统概论 MFS是linux下的开源存储系统,是由波兰人开发的.MFS文件系统能够实现RAID的功能,不但能够节约存储成本,而且不逊于专业的存储系统,能够实现在线扩展.MFS是一种半分布 ...