追溯 React Hot Loader 的实现
文:萝卜(沪江金融前端开发工程师)
本文原创,转载请注明作者及出处
如果你使用 React ,你可以在各个工程里面看到 Dan Abramov 的身影。他于 2015 年加入 facebook,是 React Hot Loader 、React Transform、redux-thunk、redux-devtools 等等的开发者。同样也是 React、Redux、Create-React-App 的联合开发者。从他的签名 Building tools for humans. 或许表明了他想打造高效的开发环境以及调试过程。
作为 Dan 的小迷妹,如他说 is curious where the magic comes from。这篇文章会带你们去了解 React Hot Loader 的由来,它实现的原理,以及在实现中遇到的问题对应的解决方法。也许你认为这篇文章太过于底层,对日常的业务并没有帮助,但希望你和我一样能通过了解一个实现得到乐趣,以及收获一些思路。
首先,React Hot Loader 的产生
Dan 在自己的文章里面说到。React Hot Loader 起源一个来自 stackoverflow 上的一个问题 —— what exactly is hot module replacement in webpack,这个问题解释了 webpack 的 hot module replacement(下面简称 HMR)到底是什么,以及我们可以利用它做什么,Dan 当时想到也 React 可以和 webpack hot module 以一种有趣的方式结合在一起。
于是他在 Twitter 上录制了一个简单的视频(请看下面),事实上视频中的实现依赖于它在 React 源代码里面插入了很多自己的全局变量。他本没指望到这个视频能带来多大的关注,但结果是他收到了很多点赞,并且粉丝狂增,他意识到必须以一个真正的工程去实现。
初步尝试, 直接使用 HMR
HMR 是属于 webpack 范畴内的实现,你可以在 webpack 的官方文档 看到如何开启它以及它提供的接口。如果你有印象,你会记得使用它需要
在 webpack config 或者 webpack-dev-server cli 里面指定开启 hot reloading 模式,并且在你的代码里写上 module.hot.accept(xxx)。但 HMR 到底是什么?我们可以用一句话总结:当一个 import 进来的模块发生了变化,HMR 提供了一个接口让我们使用 callback 回调去做一些事情。
一个使用 HMR 实现自动刷新的 React App 像下面这样:
// index.js
var App = require('./App')
var React = require('react')
var ReactDOM = require('react-dom')
// 像通常一样 render Root Element
var rootEl = document.getElementById('root')
ReactDOM.render(<App />, rootEl)
// 我们是不是在 dev 环境 ?
if (module.hot) {
// 当 App.js 更新了
module.hot.accept('./App', function () {
// require 进来更新的 App.js 重新render
var NextApp = require('./App')
ReactDOM.render(<NextApp />, rootEl)
})
}
请注意,这个实现没有使用 React Hot Loader 或者 React Transform 或者任何其他的,这仅仅是 webpack 的HMR 的 api。而这里的 callback 回调函数当然是 re-render 我们的 app。
得益于 HMR API 的设计,在嵌套的组件也能实现更新。如果一个模块没有指明如何去更新自己,那么引入这个模块的另一个模块也会被包含在热更新的 bundle 里,这些更新会”冒泡“,直到某个 import 它们的模块 "接收" 更新。如果有些模块最终没有被"接受",那么热更新失败,控制台会打印出警告。为了“接受”更新,你只需要调用 module.hot.accept('./name', callback) 。
因为我们在 index.js 里的接受了 App.js 的更新 ,这使得我们隐性的接受了所有从 App.js 引入的所有模块(component)的更新。打个比方,假如我编辑了 Button.js 组件,而它被 UserProfile.js 以及 Navbar.js import, 而这两个模块都被 App.js import 引入了。因为 index.js import 了 App.js,并且它包含了 module.hot.accept('./App', callback) ,Webpack 会自动产生一个包含以上所有文件的 “updated bundle”, 并且运行我们提供的 callback。
你以为 hot reloading 就到此为止了吗,当然远远不够
追溯 React Hot Loader 的实现的更多相关文章
- [转] React Hot Loader 3 beta 升级指南
前言 在用 react-hot-loader v1.3 的时候有些深层组件不会很完美的热更新(可能是我使用有问题).然后在 react-hot-loader 首页中看到 React Hot Loade ...
- [转] Spring Boot and React hot loader
When I develop web applications, I love using React. I'm also a Spring and groovy addict. Those two ...
- npm scripts + webpack 实践经验(React、Nodejs)
最近用Webpack+npm scripts+Mongodb+Nodejs+React写了个后台项目,在用Webpack构建过程中遇到了许多坑,就写出来分享一下. 构建工具五花八门,想当年刚学会Gru ...
- Rails + React +antd + Redux环境搭建
前提条件:node和ruby on rails必须已经安装好(相关安装流程不再此处介绍) 1.nvm.node 2.npm or yarn装一个就好 3.rvm.ruby on rails 4.for ...
- Webpack+React项目入门——入门及配置Webpack
一.入门Webpack 参考文章:<入门Webpack,看这篇就够了> 耐心看完这篇非常有帮助 二.React+Webpack环境配置 参考文章:<webpack+react项目初体 ...
- webpack学习(五)—webpack+react+es6(第1篇)
如果你看过webpack学习系列的前一个文章,接下来做的东西会比较简单 :webpack学习(四)— webpack-dev-server react发展的很快,现在大部分开发react相关的项目,都 ...
- 蒲公英 · JELLY技术周刊 Vol 27: 平平无奇 React 17
蒲公英 · JELLY技术周刊 Vol.27 这个热闹的十月终于要走到尾声,React 17 历经 4 个 RC 版本之后,也于数天前正式发布了,而同在几天前发布的 CRA 4.0 也已经完成了 Re ...
- [react]react创建app,路由,mobx 全教程
1.创建app, npx create-react-app my-app Cmd Copy 2.进入项目目录 cd my-app Cmd Copy 3.启用配置文件(默认是不开启配置文件的) ya ...
- JavaScript 踩坑心得— 为了高速(下)
一.前言 本文的上一篇 JavaScript 踩坑心得- 为了高速(上) 主要和大家分享的是 JavaScript 使用过程中的基本原则以及编写过程中的心得分享,本文主要和大家聊聊在各个使用场景下的 ...
随机推荐
- apache编译安装参数说明
apache编译安装参数说明 ./configure //配置源代码树--prefix=/usr/local/apache2 //体系无关文件的顶级安装目录prefix ,也就apache的安装目录. ...
- [DeeplearningAI笔记]Multi-class classification多类别分类Softmax regression_02_3.8-3.9
Multi-class classification多类别分类 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.8 Softmax regression 原有课程我们主要介绍的是二分分类( ...
- Python+PyCharm的一些基本设置:安装使用、注册码、显示行号、字体大小和快捷键等常用设置
一 下载与安装 软件下载,软件文档下载:http://www.jetbrains.com/pycharm/download/ 如下图: 官方网站下载:http://www.oschina.net/p/ ...
- C# Ioc 接口注册实例以及注入MVC Controller
当弄一个小程序时,就忽略了使用Ioc这种手段,作为一个帅气程序员,代码规范,你懂的~,废话不多说,快速搭建一个Ioc接口实例以及直接注入到 MVC Controller 构造函数中如下: MVC in ...
- wpf timePicker 时间选择控件
wpf里有日期选择控件,但没有时间选择控件.其他地方也有类似的,但效果并不太好,而且复杂.所以就自己写了个.参考codeproject上的. 分两部分. 第一部分是.cs文件.也就是control控件 ...
- 安装RRDtool 1.4.5
安装rrdtoolRrdtool安装需要cairo.libxml2.pango库支持,可通过yum安装安装libart_lgpl-devel这个包yum -y install libart_lgpl- ...
- XBIM 基于 WexBIM 文件在 WebGL 浏览和加载
目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...
- BZOJ 2242: [SDOI2011]计算器 [快速幂 BSGS]
2242: [SDOI2011]计算器 题意:求\(a^b \mod p,\ ax \equiv b \mod p,\ a^x \equiv b \mod p\),p是质数 这种裸题我竟然WA了好多次 ...
- BZOJ 3884: 上帝与集合的正确用法 [欧拉降幂]
PoPoQQQ大爷太神了 只要用欧拉定理递归下去就好了.... 然而还是有些细节没考虑好: $(P,2) \neq 1$时分解$P=2^k*q$的形式,然后变成$2^k(2^{(2^{2^{...}} ...
- BZOJ 4031: [HEOI2015]小Z的房间 [矩阵树定理 行列式取模]
http://www.lydsy.com/JudgeOnline/problem.php?id=4031 裸题........ 问题在于模数是$10^9$ 我们发现消元的目的是让一个地方为0 辗转相除 ...