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(模块热替换)相关推荐

  1. webpack实践之路(七):模块热替换HMR

    HMR 模块热替换(Hot Module Replacement 或 HMR)允许在运行时更新各种模块,而无需进行完全刷新. HMR主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面 ...

  2. 手把手教你webpack3(14)HMR模块热加载

    前注: 文档全文请查看 根目录的文档说明. 如果可以,请给本项目加[Star]和[Fork]持续关注. 有疑义请点击这里,发[Issues]. 点击这里查看DEMO 7.模块热加载 HMR 7.0.使 ...

  3. webpack 3 零基础入门教程 #12 - 如何使用模块热替换 HMR 来处理 CSS

    模块热替换 是什么意思? 以前我们使用的 webpack --watch 或 webpack-dev-server 的功能是监听文件改变,就自动刷新浏览器,而这个 模块热替换 不用刷新浏览器,它是只让 ...

  4. 【webpack】-- 模块热替换

    全称是Hot Module ReplaceMent(HMR),理解成热模块替换或者模块热替换都可以吧,和.net中的热插拔一个意思,就是在运行中对程序的模块进行更新.这个功能主要是用于开发过程中,对生 ...

  5. webpack5 基础配置8 devServer 模块热替换HMR, 框架的HRM, HRM原理

    dev Server 之前运行一直是手动打开页面,修改代码后,每次都要run build非常麻烦. 第一种是通过watch来解决,每次代码一修改就自动编译然后重新渲染. 可以看到刚我们修改了代码,重新 ...

  6. react 动态修改路由_升级到 React Router 4 并实现动态加载和模块热替换

    这篇文章是升级到Webpack2坑--模块热替换失效页面不自动刷新?的后续.那篇文章主要说明了,升级到 Webpack 2 之后,通过升级webpack-dev-server和react-hot-lo ...

  7. vue-cli3项目移动设备调试访问报错WDS:Disconnected,无法自动刷新或模块热替换

    原文地址:https://blog.csdn.net/qq_42420120/article/details/82912944 因为默认情况下,cli3中devServer开启时默认使用的IP不是局域 ...

  8. Android Browser学习七 书签历史模块: 书签UI的实现

    2019独角兽企业重金招聘Python工程师标准>>> 浏览器的书签界面功能还是比较丰富的, 主要有 1.可以按照列表和grid两种方式展示 2.同步后会显示不同用户的书签 3.可以 ...

  9. android browser 书签 路径,Android Browser学习七 书签历史模块: 书签UI的实现(2)

    由于书签模块还是比较复杂的, 为了不让博客变得太长, 故拆分为两篇. 上一篇介绍了书签大致的实现, 本篇主要介绍 1.书签模块BreadCrumb的实现, 2.书签模块与Activity之间的通讯, ...

最新文章

  1. golang中的互斥锁
  2. Java-js处理textarea自动生成的制表符(空格,换行,tab等)
  3. 数据卡片_E015 如何批量汇总工作簿数据,形成独立工作簿信息卡片
  4. HTML5 API详解(4):最实用的API DeviceOrientation设备传感器
  5. Esper 7.x集成SparkStream 2.x
  6. C语言霍夫曼编码压缩,数据结构大作业——哈夫曼编码压缩BMP格式文件
  7. P3800 Power收集
  8. 拦截JQuery的ajax
  9. 073:【Django数据库】ORM聚合函数详解-Count
  10. 服务器系统怎样设置定时开关机,如何配置服务器定时开关机
  11. Threejs/Webgl智慧城市部分效果实现
  12. 遥感原理与应用【Ⅱ】
  13. 体胖还需勤跑步,人丑就该多读书!
  14. C++:剑指Offer精讲1.整数除法
  15. 25个技巧和诀窍可以用来提高你的app性能
  16. ubuntu安装I219-LM网卡驱动
  17. 微型计算机地址总线是16位,某微型计算机的地址总线的位数是16位,最大的寻址空间可为()。A.32KBB.64KBC.128KBD.256KB...
  18. ubuntu完全卸载CUDA
  19. MATLAN图像处理之盲去卷积
  20. 找工作再也不愁之面试题全覆盖-Java基础篇

热门文章

  1. mysql+连接每一行数据_MySQL_深入mysql基础知识的详解,1.每个客户端连接都会从服务 - phpStudy...
  2. Java修炼之凡界篇 筑基期 第01卷 入门 番外3 认识IDE和IDEA
  3. 修改鼠标光标的形状(二)
  4. 基于java+mysql智慧旅游平台网站
  5. 2020计算机组装与维护,2020年计算机组装与维护[教案].docx
  6. ISAM and VSAM
  7. python中self.no = no的意思_这部豆瓣评分9.4的古董沙雕剧和Python ...
  8. 计算机音乐一次就好歌词,杨宗纬 - 一次就好歌词 - 歌曲歌词大全
  9. Marshal用法汇总
  10. windons下远程提交任务到linux上的spark集群