webpack学习(七):启用 HMR(模块热替换)
demo地址: https://github.com/Lkkkkkkg/webpack-demo
上次使用 webpack-dev-serve : https://blog.csdn.net/qq593249106/article/details/84922572
当前目录结构 :
|- /dist //用于放打包后文件的文件夹|- app.bundle.js //出口文件|- print.bundle.js //出口文件|- index.html //模板文件
|- /node_modules
|- /src //用于放源文件的文件夹|- index.js //入口文件|- print.js
|- package.json
|- webpack.config.js //webpack配置文件
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');module.exports = {entry: {app: './src/index.js'// print: './src/print.js'},devtool: 'inline-source-map', // 不同选项适用于不同环境devServer: {contentBase: './dist', //将dist目录下的文件(index.html)作为可访问文件, 如果不写这个参数则默认与webpack.cofig.js的同级目录port: 8080 //端口号设为8080, 默认也是8080},plugins: [ //webpack 通过 plugins 实现各种功能, 比如 html-webpack-plugin 使用模版生成 html 文件new CleanWebpackPlugin(['dist']), //设置清除的目录new HtmlWebpackPlugin({filename: 'index.html', //设置生成的HTML文件的名称, 支持指定子目录,如:assets/admin.html})],output: {filename: '[name].bundle.js', //根据入口文件输出不同出口文件path: path.resolve(__dirname, 'dist')}
};
这里把配置的 入口文件 print.js 给去掉了, 因为 print.js 被 入口文件 index.js 应用了
HMR(模块热替换)
模块热替换(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一, 它允许在运行时更新各种模块, 而无需进行完全刷新
比如在这个现在修改 print.js 里面的内容, 使用 HMR 就可以只更新 print.js 里面的内容而不用重新加在整个页面
启用HMR
启用这个功能很简答, 只需要修改一下 webpack.config.js 的配置, 使用 webpack 内置的 HMR 插件就可以了
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack'); //引入 webpackmodule.exports = {entry: {app: './src/index.js'// print: './src/print.js'},devtool: 'inline-source-map', // 不同选项适用于不同环境devServer: {contentBase: './dist', //将dist目录下的文件(index.html)作为可访问文件, 如果不写这个参数则默认与webpack.cofig.js的同级目录port: 8080, //端口号设为8080, 默认也是8080,hot: true },plugins: [ //webpack 通过 plugins 实现各种功能, 比如 html-webpack-plugin 使用模版生成 html 文件new CleanWebpackPlugin(['dist']), //设置清除的目录new HtmlWebpackPlugin({filename: 'index.html', //设置生成的HTML文件的名称, 支持指定子目录,如:assets/admin.html}),new webpack.HotModuleReplacementPlugin() //启用 webpack 内置的 HMR插件],output: {filename: '[name].bundle.js', //根据入口文件输出不同出口文件path: path.resolve(__dirname, 'dist')}
};
启用 webpack 内置的 HMR插件后, module.hot 接口就会暴露在 index.js 中, 接下来需要在 index.js 中配置告诉 webpack 接受HMR的模块( print.js ):
index.js
import _ from 'lodash';
import printMe from './print.js';function component() {var element = document.createElement('div');var btn = document.createElement('button'); //新建一个button对象element.innerHTML = _.join(['Hello', 'webpack'], ' '); //要用到lodash的语法btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe; //button触发的事件是引用的print.js暴露的事件element.appendChild(btn); //把button对象插入div中return element;
}document.body.appendChild(component());if (module.hot) {module.hot.accept('./print.js', function() { //告诉 webpack 接受热替换的模块console.log('Accepting the updated printMe module!');printMe();})
}
启动 webpack-dev-server
终端输入 npm run dev 启动, 打开 index.html, 然后去修改 print.js 里面的内容:
print.js
export default function printMe() {//console.log('I get called from print.js!');console.log('change');
}
回到网页看控制台:
可以看到 HMR 的字眼, 并且看到了 index.js下的输出(‘Accepting the updated printMe module!’) 和 print.js 修改后的输出(‘change’), 说明服务器检测到了 print.js 的代码变化并且执行了 module.hot.accept 的回调函数,
但是现在只成功了50%, 因为点击 button 按钮, 会发现输出还是之前的(‘I get called from print.js!’), 说明 print.js 虽然被修改了, 但在 index.js 上还没有被修改之后的替换, 所以 button 绑定的还是之前的事件, 这里需要在检测到代码修改后, 用修改之后的js重新渲染页面:
index.js
import _ from 'lodash';
import printMe from './print.js';function component() {var element = document.createElement('div');var btn = document.createElement('button'); //新建一个button对象element.innerHTML = _.join(['Hello', 'webpack'], ' '); //要用到lodash的语法btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe; //button触发的事件是引用的print.js暴露的事件element.appendChild(btn); //把button对象插入div中return element;
}var element = component(); //改用一个element保存一下
document.body.appendChild(element);if (module.hot) { //告诉 webpack 接受热替换的模块module.hot.accept('./print.js', function() {console.log('Accepting the updated printMe module!');document.body.removeChild(element); //删掉旧的elementelement = component(); //获得一个修改后的elementdocument.body.appendChild(element); //重新插入到网页中})
}
热重载
因为之前配置过热重载功能 , 所以修改了 index.js 之后会自动重载, 页面刷新说明重载完成, 这个时候再次修改 print.js 的输出, 热替换后再点击按钮, 发现输出的是修改后的代码:
实现了 HMR(模块热替换功能), 这样修改模块的代码就不用热重载重新加载整个文件了, 它只会更新修改的模块部分, 对于开发来说很方便
HMR 修改样式表(CSS)
借助于 style-loader 的帮助, CSS 的模块热替换实际上是相当简单的, 当更新 CSS 依赖模块时, 此 loader 在后台使用 module.hot.accept 来修补(patch) < style> 标签
安装
npm install style-loader css-loader --save-dev
配置 webpack.config.js
相关 style-loader 配置教程可以看 https://blog.csdn.net/qq593249106/article/details/84894989
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack'); //引入 webpackmodule.exports = {entry: {app: './src/index.js'// print: './src/print.js'},devtool: 'inline-source-map', // 不同选项适用于不同环境devServer: {contentBase: './dist', //将dist目录下的文件(index.html)作为可访问文件, 如果不写这个参数则默认与webpack.cofig.js的同级目录port: 8080, //端口号设为8080, 默认也是8080,hot: true},module: {rules: [ //配置加载器, 用来处理源文件, 可以把es6, jsx等转换成js, sass, less等转换成css{test: /\.css$/, //配置要处理的文件格式,一般使用正则表达式匹配use: ['style-loader', 'css-loader'] //使用的加载器名称}]},plugins: [ //webpack 通过 plugins 实现各种功能, 比如 html-webpack-plugin 使用模版生成 html 文件new CleanWebpackPlugin(['dist']), //设置清除的目录new HtmlWebpackPlugin({filename: 'index.html', //设置生成的HTML文件的名称, 支持指定子目录,如:assets/admin.html}),new webpack.HotModuleReplacementPlugin() //启用 webpack 内置的 HMR插件],output: {filename: '[name].bundle.js', //根据入口文件输出不同出口文件path: path.resolve(__dirname, 'dist')}
};
现在新建一个 style.css 在 src 文件夹下用来做本次测试:
|- /dist //用于放打包后文件的文件夹|- app.bundle.js //出口文件|- print.bundle.js //出口文件|- index.html //模板文件
|- /node_modules
|- /src //用于放源文件的文件夹|- index.js //入口文件|- print.js |- style.css //样式文件
|- package.json
|- webpack.config.js //webpack配置文件
style.css
body {background-color: red;
}
别忘了在 index.js 引入 style.css:
index.js
import _ from 'lodash';
import printMe from './print.js';
import './style.css'function component() {var element = document.createElement('div');var btn = document.createElement('button'); //新建一个button对象element.innerHTML = _.join(['Hello', 'webpack'], ' '); //要用到lodash的语法btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe; //button触发的事件是引用的print.js暴露的事件element.appendChild(btn); //把button对象插入div中return element;
}var element = component(); //改用一个element保存一下
document.body.appendChild(element);if (module.hot) { //告诉 webpack 接受热替换的模块module.hot.accept('./print.js', function() {console.log('Accepting the updated printMe module!');document.body.removeChild(element); //删掉旧的elementelement = component(); //获得一个修改后的elementdocument.body.appendChild(element); //重新插入到网页中})
}
启动服务器
终端输入 npm run dev, 打开网页:
style.css 文件生效了, 现在修改一下在 style.css 中修改一下, 将颜色改为绿色:
style.css
body {/*background-color: red;*/background-color: green;
}
这时, 网页没有重载直接变成了绿色, 实现了 css 的 HMR(热替换)
webpack学习(七):启用 HMR(模块热替换)相关推荐
- webpack实践之路(七):模块热替换HMR
HMR 模块热替换(Hot Module Replacement 或 HMR)允许在运行时更新各种模块,而无需进行完全刷新. HMR主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面 ...
- 手把手教你webpack3(14)HMR模块热加载
前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. 点击这里查看DEMO 7.模块热加载 HMR 7.0.使 ...
- webpack 3 零基础入门教程 #12 - 如何使用模块热替换 HMR 来处理 CSS
模块热替换 是什么意思? 以前我们使用的 webpack --watch 或 webpack-dev-server 的功能是监听文件改变,就自动刷新浏览器,而这个 模块热替换 不用刷新浏览器,它是只让 ...
- 【webpack】-- 模块热替换
全称是Hot Module ReplaceMent(HMR),理解成热模块替换或者模块热替换都可以吧,和.net中的热插拔一个意思,就是在运行中对程序的模块进行更新.这个功能主要是用于开发过程中,对生 ...
- webpack5 基础配置8 devServer 模块热替换HMR, 框架的HRM, HRM原理
dev Server 之前运行一直是手动打开页面,修改代码后,每次都要run build非常麻烦. 第一种是通过watch来解决,每次代码一修改就自动编译然后重新渲染. 可以看到刚我们修改了代码,重新 ...
- react 动态修改路由_升级到 React Router 4 并实现动态加载和模块热替换
这篇文章是升级到Webpack2坑--模块热替换失效页面不自动刷新?的后续.那篇文章主要说明了,升级到 Webpack 2 之后,通过升级webpack-dev-server和react-hot-lo ...
- vue-cli3项目移动设备调试访问报错WDS:Disconnected,无法自动刷新或模块热替换
原文地址:https://blog.csdn.net/qq_42420120/article/details/82912944 因为默认情况下,cli3中devServer开启时默认使用的IP不是局域 ...
- Android Browser学习七 书签历史模块: 书签UI的实现
2019独角兽企业重金招聘Python工程师标准>>> 浏览器的书签界面功能还是比较丰富的, 主要有 1.可以按照列表和grid两种方式展示 2.同步后会显示不同用户的书签 3.可以 ...
- android browser 书签 路径,Android Browser学习七 书签历史模块: 书签UI的实现(2)
由于书签模块还是比较复杂的, 为了不让博客变得太长, 故拆分为两篇. 上一篇介绍了书签大致的实现, 本篇主要介绍 1.书签模块BreadCrumb的实现, 2.书签模块与Activity之间的通讯, ...
最新文章
- golang中的互斥锁
- Java-js处理textarea自动生成的制表符(空格,换行,tab等)
- 数据卡片_E015 如何批量汇总工作簿数据,形成独立工作簿信息卡片
- HTML5 API详解(4):最实用的API DeviceOrientation设备传感器
- Esper 7.x集成SparkStream 2.x
- C语言霍夫曼编码压缩,数据结构大作业——哈夫曼编码压缩BMP格式文件
- P3800 Power收集
- 拦截JQuery的ajax
- 073:【Django数据库】ORM聚合函数详解-Count
- 服务器系统怎样设置定时开关机,如何配置服务器定时开关机
- Threejs/Webgl智慧城市部分效果实现
- 遥感原理与应用【Ⅱ】
- 体胖还需勤跑步,人丑就该多读书!
- C++:剑指Offer精讲1.整数除法
- 25个技巧和诀窍可以用来提高你的app性能
- ubuntu安装I219-LM网卡驱动
- 微型计算机地址总线是16位,某微型计算机的地址总线的位数是16位,最大的寻址空间可为()。A.32KBB.64KBC.128KBD.256KB...
- ubuntu完全卸载CUDA
- MATLAN图像处理之盲去卷积
- 找工作再也不愁之面试题全覆盖-Java基础篇
热门文章
- mysql+连接每一行数据_MySQL_深入mysql基础知识的详解,1.每个客户端连接都会从服务 - phpStudy...
- Java修炼之凡界篇 筑基期 第01卷 入门 番外3 认识IDE和IDEA
- 修改鼠标光标的形状(二)
- 基于java+mysql智慧旅游平台网站
- 2020计算机组装与维护,2020年计算机组装与维护[教案].docx
- ISAM and VSAM
- python中self.no = no的意思_这部豆瓣评分9.4的古董沙雕剧和Python ...
- 计算机音乐一次就好歌词,杨宗纬 - 一次就好歌词 - 歌曲歌词大全
- Marshal用法汇总
- windons下远程提交任务到linux上的spark集群