react 热替换 ([HMR])
react 热替换 ([HMR])
热替换好多地方可以用到,目前比较流行的用法是搭配React和webpack实现在不刷新页面的情况下对模块的增删改。在给项目添加热替换功能的时候,可以说是踩了各种坑,webpack官方给的配置也有小问题还不得不翻墙去解决(百度出来的一个能打的也没有)。
官方的方案在这儿:https://webpack.js.org/guides/hmr-react/
我先把自己配置成功的贴出来,再说一下如果完全照搬官方配置,会产生的问题:
(只保留热替换相关配置和最基础配置,且只考虑开发不考虑生产,且假设你已安装必要的包)
module.exports = {
  entry: [
    'react-hot-loader/patch', // 1
    // 开启 React 代码的模块热替换(HMR)
    './src',
  ],
  output: {
    filename: 'js/bundle.js',
    path: path.resolve(__dirname, 'public'),
    publicPath:'http://localhost:7000/', // 2
  },
  module: {
    rules: [
      { test: /\.(js|jsx)$/, use: 'babel-loader', exclude: /node_modules/ },
      { test: /\.css$/,
        use:['style-loader', 'css-loader', 'postcss-loader'], // 3
        exclude: /node_modules/ },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  devServer: {
    port: 7000,
    hot: true, // 4
    // 开启服务器的模块热替换(HMR)
    headers: {
      'Access-Control-Allow-Origin': '*', // 5
    },
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(), // 6
    // 开启全局的模块热替换(HMR)
    new webpack.NamedModulesPlugin(), // +
    // 当模块热替换(HMR)时在浏览器控制台输出对用户更友好的模块名字信息
  ],
}
react 和babel 部分的配置与官方相同即可。
参考官方配置你遇到第一个问题:
[HMR] Update failed: SyntaxError: Unexpected token < in JSON at position 0
    at Object.parse (<anonymous>)
    at XMLHttpRequest.request.onreadystatechange
这个问题很头疼,因为你去搜索完全找不到有用的东西,而且你看不出来错在哪了,当时的心情真是。。。
最后在 react-hot-loader 的 github 库的 Issues 里翻到了有人和我一样的问题,大快人心。
原来是 output 的 publicPath 出了问题用 '/' 是不行滴,要把启动webpack服务的地址填上:'http://localhost:7000/'。其实也不能怪官方文档,人家是假设你应用程序和包都托管给 webpack 服务,但是我的只把包托给了 webpack 服务,应用程序是另外启动的 node 服务。好吧这是个比较小众的问题,你要是正好有这个问题,还搜到了这篇文章,那是好福气了。
另外一个
XMLHttpRequest cannot load http://localhost:7000/4221731a75de7a449377.hot-update.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 404
这个问题只在 webpack 服务发生变动时候有,并不影响HMR使用,所以不管它也可以。
devServer里添加
 headers: {
      'Access-Control-Allow-Origin': '*', // 5
    },
即可,也是因为应用程序没有托管给 webpack 导致。
如果你的应用程序和包都是托管给 webpack 服务,那就没有这两个问题了。
(话说应用程序一般都是另启服务的吧。。。)
再说一个问题,除了上面两个,是不是这么多配置都是必须的。不配置会导致什么错误。
首先,
entry里的
'react-hot-loader/patch', // 1
devServer里的
hot: true, // 4
plugins里的
new webpack.HotModuleReplacementPlugin(), // 6
从字面上看就是必须的,不用想,否则不会热。
    new webpack.NamedModulesPlugin(), // +只是让控制台输出的更友好,推荐但非必需
这个比较容易忽略:
      { test: /\.css$/,
        use:['style-loader', 'css-loader', 'postcss-loader'], // 3
        exclude: /node_modules/ },
style-loader 是必须的,否则样式的刷新就不热了。
很多人用 ExtractTextWebpackPlugin 把 css 文件单独弄出来就不用 style-loader了,不过推荐部署应用之前弄一份就行,开发用不着 ExtractTextWebpackPlugin 。
不用 style-loader 修改样式表就不会无刷新更新页面了。不过这一点容易想到。
还有一点就是 babel 配置文件里禁用 modules 很重要,否则导致各种问题,根本别想愉快的开发。这个对应用程序本身使用 import 没有影响,毕竟 webpack2 啥标准都支持,其他地方就用 require 吧。
react 热替换 ([HMR])的更多相关文章
- 模块热替换   HMR
		
devserver:{hot:true},既及时更新代码,样式(需配合loader)变化,自动重编译,只适用于开发环境. 入口文件中,添加监视: + if (module.hot) {+ module ...
 - webpack学习之—— 模块热替换(Hot Module Replacement)
		
模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面.主要是通过以下几种方式,来显著加快开发速度: 保留在完全重 ...
 - 【webpack】-- 模块热替换
		
全称是Hot Module ReplaceMent(HMR),理解成热模块替换或者模块热替换都可以吧,和.net中的热插拔一个意思,就是在运行中对程序的模块进行更新.这个功能主要是用于开发过程中,对生 ...
 - 【webpack学习笔记】a05-模块热替换
		
什么是模块热替换? 这个功能会在程序运行过程中替换.添加或删除模块,而无需重新加载整个页面 有什么用呢? 保留在完全重新加载页面时丢失的应用程序状态. 只更新变更内容,以节省宝贵的开发时间. 调整样式 ...
 - 启用 webpack 的模块热替换特性
		
启用 webpack 的模块热替换特性: module.exports = { //... devServer: { hot: true } } 注意,必须有 webpack.HotModuleRep ...
 - webpack学习_模块热替换(Hot Module Peaplacement)
		
模块热替换(Hot Module Replacement 或 HMR) 是webpack提供的最有用的功能之一.允许在u女性是更新各种模块,而无需进行完全刷新. 启用HMR 承接之前的代码 webpa ...
 - webpack 模块热替换的理解和使用
		
模块热替换(webpack文档上也叫 Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一.它允许在运行时更新各种模块,而无需进行完全刷新. 这句话其实 ...
 - Java_类的热替换
		
转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...
 - 使用自己的ClassLoader实现热替换
		
首先实现一个自己的ClassLoader,该ClassLoader重写findClass方法. 从classpath中加载类资源. 注意,不要重写loadClass方法. 因为在使用自定义的MyCl ...
 
随机推荐
- CSS3-渐变背景色
			
线性渐变背景色: <style> .linear { width:130px; height:130px; border:2px solid black; padding: 10px; b ...
 - JDK8-十大新特性-附demo
			
JDK原计划17年上半年就发版,但未成功发版.才发现JDK8的特性还没总结过,特此总结. 一.十大特性. 1.Lambda表达式 2.Stream函数式操作流元素集合 3.接口新增:默认方法与静态方法 ...
 - 新手介绍简单一下iOS开发中几种界面传值
			
首先在处理iOS-UI中,也许在很多地方需要用到两种甚至多种不同界面之间的传值,相比这也是很多iOS入门成员头疼问题,同样作为新手的我在接触这类传值时候也一脸懵然,经过一段时间的研究,对于简单的传值有 ...
 - 微信开发(2)---微信小程序开发实战part1
			
微信开发现在来说,简单可以概括为两部分,微信公众号和微信小程序. 微信公众号的技术已经非常成熟.分为服务号和订阅号.简单的.可以弄一个个人订阅号,在编辑模式下就可以实现推送图文.自动回复.自定义菜单的 ...
 - Mac 下载安装MySQL
			
step 1. 从官网上下载MySQL Community Server step 2. 安装MySQL step 3. 配置mysql和mysqladmin的alias $ vim ~/.bashr ...
 - JS 部分常见循环、分支、嵌套练习
			
图形题思路:1.确定图形一共几行,即为外层的循环次数2.确定每行有几种元素,代表有几个内层循环3.确定每种元素的个数,即为每个内层循环的次数 通常,找出每种元素个数,与行号的关系式,即为当前内层循 ...
 - Linux基础(7)
			
Linux 基础(7) 一.内存的监控(free) free -m 以单位为MB的方式查看内存的使用情况(free命令读取的文件是/proc/meminfo) total:是指计算机安装的内存总量 u ...
 - sass学习入门篇(三)
			
这章我们讲“嵌套”,嵌套包括两种:一,选择器嵌套.二是属性的嵌套.一般用选择器嵌套居多 一,选择器嵌套:指的是在一个选择器中嵌套另一个选择器来实现继承.使用&表示父元素选择器 li{ floa ...
 - 原生js实现数据双向绑定
			
最近接触了vue,在谈到vue等等的mvvm框架之前,先了解什么是数据双向绑定以及如何利用原生JS实现数据双向绑定 单向数据绑定 指先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HT ...
 - iOS开发tips-UINavigationBar的切换
			
概述 在iOS系统中,如果控制器是以push方式进行管理的话,那么事实上多个控制器是共享的同一个导航栏.当然iOS系统的设计无可厚非,但是国内的应用经常会遇到很多个性的设计,就比如说A push到 B ...