webpack hmr
参考:
https://webpack.js.org/concepts/hot-module-replacement/
https://webpack.js.org/guides/hot-module-replacement/
hmr技术支持程序运行时的模块(amd、commonJS等)的修改、添加和删除,而不用整个程序重新加载,这可以提升开发的效率:
- hmr后程序的状态可以得到保存
- 仅仅改变变化的部分,其余不变
- 调样式更加快捷,基本比得上在浏览器中的样式修改
以下步骤允许模块在应用程序中切换:
- app请求hmr runtime来检查模块更新
- runtime异步下载更新和通知app
- app请求runtime去应用这些更新
- runtime同步地应用这些更新
在编译器中
编译器需要提交一个update来执行更新,更新的内容有如下两部分:
- 清单文件(json),包含了新的编译hash和要更新的chunk列表。
- 一个或多个chunk(js),每个chunk包含了所有要更新的模块的新代码(或者一个标志位代表模块要被移除)
编译器能保证这些模块和chunk的id在构建中始终是唯一的,这些id保存在webpack-dev-server的内存中,也可以保存在一个json文件中。
在模块中
hmr是一个可选的功能,仅仅会影响包含了hmr代码的模块。如style-loader实现了hmr接口,当它受到一个hmr的更新,这个loader就会去用新的样式去替换旧的样式。
当在模块中实现hmr接口,我们可以决定当模块需要更新的时候,让模块去做我们想做的事情。当模块没有写hmr时,对应的更新就会被往上冒泡,会导致整颗依赖树都被重新加载。
对于module.hot 的更多信息可以在 HMR API page 查看。
在运行时
这里关注的是更加细节的东西,如果不感兴趣,可以直接去了解 HMR API page 或者 HMR guide
对于模块系统的运行,额外的代码用于追踪模块parents和children。有两个方法check和apply可以用来管理。
check:创建一个http请求来更新清单文件。http请求失败的话则更新不可用,请求成功的话,一个新的chunk列表会用于与当前已经加载好的chunk进行对比,当所有需要更新的chunk已经下载好而且准备好了,则进入ready状态。
apply:这个函数把所有的模块标记为不可用,不可用的模块或者父模块需要有一个update handler,否则这个这个标记会冒泡,使所有的祖先模块被标记为不可用。标记会一直冒泡,直到到达app的入口文件或者被update handler所处理。
最后,所有的不可用模块都被配置(通过dispose handler)和卸载,当前的hash值被更新,所有的accept handler都被调用。hmr rumtime到这里切换为空闲状态。
webpack-dev-server
webpack-dev-server通过hot模式来支持hmr。以下记录以下步骤:
- 使bundle的内存输出路径与硬盘路径一致,具体可以去参考 自动刷新
- 然后启用插件
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
] - 启用devServer的hot模式
devServer: {
hot: true
} - 在模块中进行处理
if(module.hot){
module.hot.accept("./modules/utils",function(){
console.log("当上面的模块发生修改,这里的代码会执行")
})
} - 最重要的一点,导入的模块不能使用require,而是使用import .. from形式。以上回调函数执行的时候,可以认为导入的内容已经发生变化(ES6只读地址指向的内容已经变化,可以直接使用)
对于样式的处理,以上123点,接着配置添加style、css-loader,然后在入口文件中引入样式:import './stl.css' 这样配置之后,修改样式文件,浏览器界面马上发生变化,效果就像是F12来修改样式一样。
React Hot Loader
按照 文档 的步骤:
配置文件
var path = require('path');
const webpack = require('webpack')
module.exports = {
entry: {
app:['react-hot-loader/patch', './main.jsx']
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath:"dist"
},
devServer: {
contentBase: '.',
hot: true
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [["es2015", { "modules": false }],'react'],
plugins:["react-hot-loader/babel"]
}
}
}
]
}
};
入口文件
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './App.jsx' const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root')
)
} render(App) if (module.hot) {
module.hot.accept('./App.jsx', () => {
render(App)
})
}
App.jsx
import React from "react"
export default class App extends React.Component{
render(){
return <div>123</div>
}
}
依赖
{
"name": "h2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"srv": "webpack-dev-server",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-hot-loader": "^3.1.3",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.10.1"
}
}
实践的时候发现有一点很重要:要求webpack和webpack-dev-server必须都在本地安装,而不是一个全局安装,一个本地安装。否则会导致热更新无效,而且不报错,bundle.js引入了不同的文件:


两个都本地本地安装就可以解决问题了,再次查看bundle.js,引用的emitter.js路径就都一样了。
Vue Loader
其他链接
https://juejin.im/post/5a41ab5b51882560b65290eb
https://zhuanlan.zhihu.com/p/30669007
webpack hmr的更多相关文章
- webpack HMR是如何工作的?
https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack https://www.jianshu.com/p/9 ...
- webpack HMR原理
在启动 devServer 的时候,sockjs 在服务端和浏览器端建立了一个 webSocket 长连接,以便将 webpack 编译和打包的各个阶段状态告知浏览器,最关键的步骤还是 webpack ...
- 细说前端自动化打包工具--webpack
背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...
- webpack 插件拾趣 (1) —— webpack-dev-server
结束了一季的忙碌,我这封笔已久的博客也终究该从春困的咒印中复苏,想来写些实用易读的作为开篇,自然是最好不过. 新开个 webpack 插件/工具介绍的文章系列,约莫每周更新一篇篇幅适中的文章聊以共勉, ...
- 从零开始配置TypeScript + React + React-Router + Redux + Webpack开发环境
转载请注明出处! 说在前面的话: 1.为什么不使用现成的脚手架?脚手架配置的东西太多太重了,一股脑全塞给你,我只想先用一些我能懂的库和插件,然后慢慢的添加其他的.而且自己从零开始配置也能学到更多的东西 ...
- webpack热更新和常见错误处理
时间:2016-11-03 10:50:54 地址:https://github.com/zhongxia245/blog/issues/45 webpack热更新 一.要求 局部刷新修改的地方 二. ...
- Webpack & The Hot Module Replacement热模块替换原理解析
Webpack & The Hot Module Replacement热模块替换原理解析 The Hot Module Replacement(HMR)俗称热模块替换.主要用来当代码产生变化 ...
- [前端进阶课] 构建自己的 webpack 知识体系
webpack webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件. Webpack 核心概念: Entry(入口):Webpack 执 ...
- 浅谈Webpack模块打包工具三
Source Map 生产代码与开发代码完全不同,如果需要调试应用的话会非常的麻烦,错误信息无法定位,Soutce Map就会逆向得到源代码, 须在打包之后的代码文件的末尾位置例如添加//# sour ...
随机推荐
- UINavigationController 的一些坑
坑一:自定义导航栏返回键 iOS7及之后版本 手势边缘右滑返回失效 解决方案: -(void)viewDidLoad{ [super viewDidLoad]; //self 为 UINavigati ...
- pwnhub 相对路径覆盖
这个pwnhub小m师傅的题,做的时候完全没有思路. 首先是注册然后可以看到一个加载css的地方,是相对路径加载(当然我并没有觉得有什么问题). 服务端和浏览器解析URL是有区别的,就是%2f 服务器 ...
- JQuery基础知识梳理篇
这周没事,优化线上项目,因为前端都在赶项目,我又若菜.于是前端数据展示也要自己来.看javascript看到吐,决定梳理一下Jquery基础知识.敲黑板) 闲扯结束,进入正题. 选择器 介绍 jque ...
- bzoj4059 [Cerc2012]Non-boring sequences && bzoj5200 [NWERC2017]Factor-Free Tree
https://konnyakuxzy.github.io/BZPRO/JudgeOnline/4059.html https://cn.vjudge.net/problem/Gym-100624D ...
- 洛谷 P1593 因子和 || Sumdiv POJ - 1845
以下弃用 这是一道一样的题(poj1845)的数据 没错,所有宣称直接用逆元/快速幂+费马小定理可做的,都会被hack掉(包括大量题解及AC代码) 什么原因呢?只是因为此题的模数太小了...虽然990 ...
- chrome浏览器历史版本
持续更新中······ google-chrome 浏览器 win64位 版本号 大小 官网更新日期 66.0.3359.181 48.58 MB 2018年5月16日 65.0.3325.181 4 ...
- 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...
- Ubuntu16.04 + cuda8.0 + GTX1080安装教程
1. 安装Ubuntu16.04 不考虑双系统,直接安装 Ubuntu16.04,从 ubuntu官方 下载64位版本: ubuntu-16.04-desktop-amd64.iso . 在MAC下制 ...
- COGS 1427. zwei
★☆ 输入文件:zwei.in 输出文件:zwei.out 简单对比时间限制:1 s 内存限制:256 MB [样例输入] 5 5 1 2 3 4 5 1 1 3 1 3 5 0 ...
- Error:(3, 32) java: 程序包org.springframework.boot不存在
解决方案一: 找同事传一份D:\maven_repository\org\springframework\boot ,如图所示的位置,添加进去立刻就不报红.我也可以给你发.... 解决方案二: ...