文:萝卜(沪江金融前端开发工程师)

本文原创,转载请注明作者及出处

如果你使用 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 的实现的更多相关文章

  1. [转] React Hot Loader 3 beta 升级指南

    前言 在用 react-hot-loader v1.3 的时候有些深层组件不会很完美的热更新(可能是我使用有问题).然后在 react-hot-loader 首页中看到 React Hot Loade ...

  2. [转] 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 ...

  3. npm scripts + webpack 实践经验(React、Nodejs)

    最近用Webpack+npm scripts+Mongodb+Nodejs+React写了个后台项目,在用Webpack构建过程中遇到了许多坑,就写出来分享一下. 构建工具五花八门,想当年刚学会Gru ...

  4. Rails + React +antd + Redux环境搭建

    前提条件:node和ruby on rails必须已经安装好(相关安装流程不再此处介绍) 1.nvm.node 2.npm or yarn装一个就好 3.rvm.ruby on rails 4.for ...

  5. Webpack+React项目入门——入门及配置Webpack

    一.入门Webpack 参考文章:<入门Webpack,看这篇就够了> 耐心看完这篇非常有帮助 二.React+Webpack环境配置 参考文章:<webpack+react项目初体 ...

  6. webpack学习(五)—webpack+react+es6(第1篇)

    如果你看过webpack学习系列的前一个文章,接下来做的东西会比较简单 :webpack学习(四)— webpack-dev-server react发展的很快,现在大部分开发react相关的项目,都 ...

  7. 蒲公英 · JELLY技术周刊 Vol 27: 平平无奇 React 17

    蒲公英 · JELLY技术周刊 Vol.27 这个热闹的十月终于要走到尾声,React 17 历经 4 个 RC 版本之后,也于数天前正式发布了,而同在几天前发布的 CRA 4.0 也已经完成了 Re ...

  8. [react]react创建app,路由,mobx 全教程

    ​ 1.创建app, npx create-react-app my-app Cmd Copy 2.进入项目目录 cd my-app Cmd Copy 3.启用配置文件(默认是不开启配置文件的) ya ...

  9. JavaScript 踩坑心得— 为了高速(下)

    一.前言 本文的上一篇 JavaScript 踩坑心得- 为了高速(上) 主要和大家分享的是 JavaScript 使用过程中的基本原则以及编写过程中的心得分享,本文主要和大家聊聊在各个使用场景下的 ...

随机推荐

  1. DELL服务器硬件信息采集SHELL脚本

    DELL服务器硬件信息采集SHELL脚本最近需要做资产列表,要采集DELL服务器的硬件信息,包括如下信息:1.操作系统信息(类型,版本,内核,平台,主机名)2.主板信息(厂商,机型,序列号)3.CPU ...

  2. windows 7 wifi热点配置

    自我总结,有什么不足或更好的解决方案,请告知,感激不尽! 目的:闲来无事的童鞋,可以试一试自己配置wifi热点. ps:其实wifi热点配置是系统存在的功能,只不过需要配置. 现在win桌面wifi热 ...

  3. java之静态代理和动态代理

    我们以几个问题,来开始我们今天的学习,如果下面几个问题,你都能说出个一二,那么恭喜你,你已经掌握了这方面的知识.1,什么是代理模式?2,Java中,静态代理与动态代理的区别?3,Spring使用的是J ...

  4. Yii框架中使用mongodb扩展

    前提条件:安装了mongodb数据库 安装了mongo的php驱动 下载Yii的mongo扩展:这是YiiMongoDbSuite的1.3.6版本支持PHP Mongo驱动的版本为1.0.5及以下 下 ...

  5. Go笔记-垃圾回收集和SetFinalizer

    [垃圾回收]     1- Go的开发者也不用写代码来释放程序中不再使用的变量和结构占用内存,Go中有独立的进程,垃圾回收器(GC),处理这些事情.它会搜索不再使用的变量然后释放它们.     2- ...

  6. CDlinux制作U盘启动盘,打造自己的口袋系统

    工具: 1.8G或以上U盘一枚: 2.CDlinux0.9.7.1镜像文件,注意其他版本不一定能成功(传送门http://pan.baidu.com/s/1o7P6Gu2): 3.UltraISO或U ...

  7. C++/C高质量编程指南-笔记

    复习: C/C++高质量编程指南: [规则1-2-1]为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块. [规则1-2-2]用 #include <file ...

  8. fatal error C1083:无法打开包括文件:“stdint.h”: No such file or directory解决方案

    stdint.h文件是C99的标准头文件,默认情况下VC是不支持的,所以在使用过程中肯定会碰到 "No such file or directory"的问题. 解决办法 1.从网盘 ...

  9. 分布式服务dubbo使用

    SOA 服务框架dubbo 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: ...

  10. Ubuntu16.04解决无法切换root权限的问题

    在su root时发现无法切换到root权限.显示: /usr/local/bin/zsh 没有文件或目录 想了想问题所在,突然想起来前段时间想要更换shell主题,于是装了zsh和oh-my-zsh ...