問題:
升級(jí) Webpack1 到 Webpack2 之后, 開發(fā)模式下實(shí)時(shí)重載(Live Reloading)不起作用琉雳∮杞瑁控制臺(tái)一直顯示“App hot update...”有决。頁面不自動(dòng)刷新秧秉,沒有變化。
解決辦法:
去掉针肥。WebpackDevServer
配置中的hot:true
new WebpackDevServer(webpack(config), {
......
// hot: true, //去掉
inline: true,
......
})
不過不知道為什么得去掉...
以下內(nèi)容更新于2018/05/15
以上的方法其實(shí)沒有解決根本問題饼记。當(dāng)時(shí)只知道去掉
hot:true
配置后,修改文件時(shí)頁面能夠自動(dòng)刷新了慰枕,但不知道為什么這么做具则,問題到底在哪里。近期看到留言才重新研究了這個(gè)問題具帮∠缤荩花費(fèi)了好幾個(gè)小時(shí)踩坑,算是對(duì)這個(gè)問題有了新的認(rèn)識(shí)匕坯。
項(xiàng)目結(jié)構(gòu)是,django + react + webpack拔稳。
版本:
-
react
:0.14.7
-
webpack
:2.7.0
-
react-hot-loader
:1.3.0
-
webpack-dev-server
:1.14.1
-
django-webpack-loader
:0.5.0
值得參考的樣板項(xiàng)目:
-
django-webpack-loader example(
webpack v1
+webpack-dev-server v1
+react-hot-loader v1
)
升級(jí)webpack 之前葛峻,我項(xiàng)目的配置跟這個(gè)例子差不多。 -
react-hot-loader-minimal-boilerplate (
webpack v2
+webpack-dev-server v2
+react-hot-loader v3
)
問題
升級(jí) webpack
v1到v2之后巴比,模塊熱替換(Hot Module Replacement术奖,HMR)失效了礁遵,而 webpack 配置的entry
中'webpack/hot/only-dev-server'
指明了HMR失效時(shí),頁面也不會(huì)重新加載(參考What's the difference between 'webpack/hot/dev-server' and 'webpack/hot/only-dev-server'?)采记,所以開發(fā)模式下修改文件佣耐,頁面不會(huì)自動(dòng)刷新。
模塊熱替換(HMR - Hot Module Replacement)功能會(huì)在應(yīng)用程序運(yùn)行過程中替換唧龄、添加或刪除模塊兼砖,而無需重新加載整個(gè)頁面。主要是通過以下幾種方式既棺,來顯著加快開發(fā)速度:
- 保留在完全重新加載頁面時(shí)丟失的應(yīng)用程序狀態(tài)讽挟。
- 只更新變更內(nèi)容,以節(jié)省寶貴的開發(fā)時(shí)間丸冕。
- 調(diào)整樣式更加快速 - 幾乎相當(dāng)于在瀏覽器調(diào)試器中更改樣式耽梅。
解決辦法
如果不需要HMR,只需要頁面可以自動(dòng)刷新胖烛,那可以去掉WebpackDevServer
配置中的hot:true
或者把 webpack 配置的entry
中'webpack/hot/only-dev-server'
改成'webpack/hot/dev-server'
眼姐。這樣就算HMR 不生效,也不影響開發(fā)過程中實(shí)時(shí)看到頁面的變化佩番。
但升級(jí)webpack
v1到v2之后众旗,還是想使用HMR呢?
Webpack
升級(jí)到2.7.0
之后答捕,react-hot-loader
還是v1逝钥,根據(jù) react-hot-loader v1.3.0 stopped working after upgrade to webpack 2.2.1 #474 中的討論,說明需要升級(jí)react-hot-loader
拱镐,v1應(yīng)該是不適用 webpack v2
艘款。
提問者還總結(jié)了解決方法,其中第一點(diǎn)沃琅,升級(jí)
webpack
時(shí)也要升級(jí)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",
以上說明,重點(diǎn)是要升級(jí)react-hot-loader
和webpack-dev-server
益眉。
注意晌柬,這個(gè)項(xiàng)目升級(jí)前HMR是啟用的,配置參考django-webpack-loader example郭脂,升級(jí)過程中沒有改動(dòng) webpack 的配置年碘,只是根據(jù) v2 的新特性做了相應(yīng)的用法上的改變(詳情參考遷移到新版本)。因此下面的內(nèi)容不是從0到1地配置 HMR展鸡,而是一個(gè)升級(jí)(主要
react-hot-loader
)的過程屿衅。
-
npm
升級(jí)react-hot-loader
到v3或v4,升級(jí)webpack-dev-server
到v2莹弊。"react-hot-loader": "^4.0.0", "webpack-dev-server": "^2.3.0"
- 在.babelrc 文件的
plugins
中添加一項(xiàng):"react-hot-loader/babel"
涤久。 - 修改 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', //添加這一項(xiàng) './html/app', ] //2.去掉react-hot-loader config.module.rules.push( { test: /\.jsx?$/, exclude: /node_modules/, use: ['babel-loader'] //before: ['react-hot-loader','babel-loader'] } );
- 修改
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':'*'}, //添加這一項(xiàng) inline: true, historyApiFallback: true }).listen(3000, 'localhost', function (err, result) { if (err) { console.log(err); } console.log('Listening at localhost:3000'); });
- 使用
react-hot-loader
的AppContainer
封裝應(yīng)用的頂?shù)捉M件≌嵬可參考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
的升級(jí)就完成了幕与。HMR應(yīng)該就生效了挑势。但是我又遇到一個(gè)坑,瀏覽器控制臺(tái)的輸出信息都正常啦鸣,新的打包文件的網(wǎng)絡(luò)請(qǐng)求也正常潮饱,但是頁面上卻依然沒變化。又是坑敖敫香拉!最后在Hot updates not applied #581里面找到相同情況的解決方法。
效果圖:
結(jié)語
這個(gè)問題的解決過程中踩了不少坑中狂,webpack官方文檔只提供了v4版本的凫碌,很多人也都在吐槽看不到歷史版本的文檔。這個(gè)對(duì)開發(fā)者來說確實(shí)很不方便胃榕。非官方的文檔有很多盛险,但卻加大了排錯(cuò)過程花費(fèi)的精力,降低了效率勋又。
畢竟升級(jí)webpack還是挺麻煩的苦掘,v1到v2還好,變化不多楔壤,升級(jí)到v3配置就改變很多了鹤啡。并且一些相關(guān)插件也得升級(jí),比如這次沒有升級(jí)react-hot-loader
就出問題了蹲嚣。至于那些插件該一起升級(jí)也沒個(gè)官方說法递瑰,只能出問題了再瘋狂地Google。
吐槽歸吐槽隙畜,坑再多抖部,還是得踩啊~~~
延伸閱讀:
- 這篇關(guān)于Webpack熱加載的文章講的很清晰透徹!雖然示例用的是Webpack1
Webpack’s HMR & React-Hot-Loader?—?The Missing Manual:
https://medium.com/@rajaraodv/webpacks-hmr-react-hot-loader-the-missing-manual-232336dc0d96 - Difference between
new webpack.HotModuleReplacementPlugin()
and--hot
?:
https://github.com/webpack/webpack-dev-server/issues/97 - Webpack 2 配置 React 熱加載议惰,React Hot Loading with Webpack 2:
http://engineering.monsanto.com/2017/08/15/react-hotloading-with-webpack-2/ - “module not found : Error: Cannot resolve module 'react/lib/ReactMount' ”:
https://stackoverflow.com/questions/40652327/module-not-found-error-cannot-resolve-module-react-lib-reactmount - 升級(jí)React Hot Loader慎颗,可參考 Update TodoMVC example to React Hot Loader 3:
https://github.com/reduxjs/redux-devtools/commit/64f58b7010a1b2a71ad16716eb37ac1031f93915 - 使用React Hot Loader 的問題及解決方法 :
https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md