【Webpack2】模块热替换失效页面不自动刷新?

问题:

升级 Webpack1 到 Webpack2 之后, 开发模式下实时重载(Live Reloading)不起作用。控制台一直显示“App hot update...”。页面不自动刷新,没有变化。

一直hot update...但不自动刷新

解决办法:

去掉WebpackDevServer配置中的hot:true

new WebpackDevServer(webpack(config), {
  ......
  // hot: true,  //去掉
  inline: true,
  ......
})

不过不知道为什么得去掉...


以下内容更新于2018/05/15

以上的方法其实没有解决根本问题。当时只知道去掉hot:true配置后,修改文件时页面能够自动刷新了,但不知道为什么这么做,问题到底在哪里。近期看到留言才重新研究了这个问题。花费了好几个小时踩坑,算是对这个问题有了新的认识。

项目结构是,django + react + webpack
版本:

  • react: 0.14.7
  • webpack2.7.0
  • react-hot-loader1.3.0
  • webpack-dev-server1.14.1
  • django-webpack-loader0.5.0

值得参考的样板项目

问题

升级 webpack v1到v2之后,模块热替换(Hot Module Replacement,HMR)失效了,而 webpack 配置的entry'webpack/hot/only-dev-server'指明了HMR失效时,页面也不会重新加载(参考What's the difference between 'webpack/hot/dev-server' and 'webpack/hot/only-dev-server'?),所以开发模式下修改文件,页面不会自动刷新。

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

解决办法

如果不需要HMR,只需要页面可以自动刷新,那可以去掉WebpackDevServer配置中的hot:true或者把 webpack 配置的entry'webpack/hot/only-dev-server'改成'webpack/hot/dev-server'。这样就算HMR 不生效,也不影响开发过程中实时看到页面的变化。

但升级webpack v1到v2之后,还是想使用HMR呢?

Webpack升级到2.7.0之后,react-hot-loader还是v1,根据 react-hot-loader v1.3.0 stopped working after upgrade to webpack 2.2.1 #474 中的讨论,说明需要升级react-hot-loader,v1应该是不适用 webpack v2

需要升级react-hot-loader

提问者还总结了解决方法,其中第一点,升级webpack时也要升级webpack-dev-server

Make sure your webpack-dev-server AND webpack are both updated. at time of writing this is what i've got

"react-hot-loader": "^3.0.0-beta.6",
"webpack-dev-server": "^2.3.0",
"webpack": "^2.2.1",

以上说明,重点是要升级react-hot-loaderwebpack-dev-server

注意,这个项目升级前HMR是启用的,配置参考django-webpack-loader example,升级过程中没有改动 webpack 的配置,只是根据 v2 的新特性做了相应的用法上的改变(详情参考迁移到新版本)。因此下面的内容不是从0到1地配置 HMR,而是一个升级(主要react-hot-loader)的过程。

  1. npm升级react-hot-loader到v3或v4,升级webpack-dev-server到v2。
    "react-hot-loader": "^4.0.0",
    "webpack-dev-server": "^2.3.0"
    
  2. 在.babelrc 文件的plugins中添加一项:"react-hot-loader/babel"
  3. 修改 webpack 配置。
    //webpack.config.local.js
    //1.修改入口
    var config = require('./webpack.base.config.js');
    config.entry.app = [
        'webpack-dev-server/client?http://' + ip + ':3000',
        'webpack/hot/only-dev-server',  //dev-server reloads when applying HMR fails, only-dev-server doesn't.
        'react-hot-loader/patch',  //添加这一项
        './html/app',
    ]
    //2.去掉react-hot-loader
    config.module.rules.push(
      { 
        test: /\.jsx?$/, 
        exclude: /node_modules/, 
        use: ['babel-loader']   //before: ['react-hot-loader','babel-loader']
      }
    );
    
  4. 修改 WebpackDevServer的配置。添加headers。详情参考React Hot Loader Troubleshooting
    //server.js
    new WebpackDevServer(webpack(config), {
      publicPath: config.output.publicPath,
      hot: true,  //enable HMR on the server
      headers:{'Access-Control-Allow-Origin':'*'},  //添加这一项
      inline: true,             
      historyApiFallback: true
    }).listen(3000, 'localhost', function (err, result) {
      if (err) {
        console.log(err);
      }
      console.log('Listening at localhost:3000');
    });
    
  5. 使用 react-hot-loaderAppContainer封装应用的顶底组件。可参考react-hot-loader-minimal-boilerplate
    import React from 'react'
    import ReactDOM from 'react-dom'
    import { AppContainer } from 'react-hot-loader'
    import Root from './containers/Root'
    const render = Component => {
      ReactDOM.render(
        <AppContainer>
          <Component />
        </AppContainer>,
        document.getElementById('root')
      )
    }
    render(Root)
    if (module.hot) {
      module.hot.accept('./containers/Root', () => { render(Root)})
    }
    

按道理,到这为止react-hot-loader的升级就完成了。HMR应该就生效了。但是我又遇到一个坑,浏览器控制台的输出信息都正常,新的打包文件的网络请求也正常,但是页面上却依然没变化。又是坑啊!最后在Hot updates not applied #581里面找到相同情况的解决方法。

热更新依然不生效

效果图:


热更新

结语

这个问题的解决过程中踩了不少坑,webpack官方文档只提供了v4版本的,很多人也都在吐槽看不到历史版本的文档。这个对开发者来说确实很不方便。非官方的文档有很多,但却加大了排错过程花费的精力,降低了效率。

毕竟升级webpack还是挺麻烦的,v1到v2还好,变化不多,升级到v3配置就改变很多了。并且一些相关插件也得升级,比如这次没有升级react-hot-loader就出问题了。至于那些插件该一起升级也没个官方说法,只能出问题了再疯狂地Google。

吐槽归吐槽,坑再多,还是得踩啊~~~

延伸阅读:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,140评论 7 35
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,671评论 7 110
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 11,028评论 0 21
  • Hot Reloading in React 本文是Dan Abramov发表于Medium文章的部分译文,只截取...
    RockSAMA阅读 2,715评论 0 2
  • 我的心知道要放下!但我的念却一直都有回想!让我放不下! 修自己的心之前先修一下自己的念!一切都是泡影!没有什么比生...
    会魔法的妮妮阅读 243评论 0 0