在傳統html開發流程中,webapp開發模式中,前端代碼改動不少,按照以前的流程跑的話,每次都須要npm run build以及run start,開發流程就會很繁瑣javascript
webpack官方插件,經過webpack配置去啓動一個微型服務器,便於開發者在開發過程當中避免沒必要要的build以及start,而且該服務器編譯出來的內容保存於內存中,一旦內容有更新,都會自動執行build,而不用手動build
html
編輯工程時,幫助咱們在修改代碼後,頁面實時更新
[區別於會從新請求頁面的「刷新」
]前端
webpack.config.client.js
中添加如下代碼//添加執行環境判斷變量【NODE_ENV】 const isDev=process.env.NODE_ENV==='development'; //修改 module.exports={...} -> const config={...} //在最後加入 if(isDev){ config.devServer={ //devServer而不是server host:'0.0.0.0',//兼容localhost,0.0.0.0,以及IP三種方式訪問 port:'3000', //webpack微服務端口(之後都稱爲devServer) contentBase:path.join(__dirname,'../dist'),//靜態文件路徑 hot:true, //是否開啓Hot module replacement overlay:{ //網頁何時出現遮罩警告層,這裏配置爲error時 errors:true //還有多種,好比warning,可是通常會過濾掉其餘類型 } } } module.exports=config; //不是modules也不是export也不是(config)...
$npm i webpack-dev-server -D
package.json
中添加啓動微服務的scriptscripts-> "dev:client":"cross-env NODE_ENV=development && webpack-dev-server --config build/webpack.config.client.js" //手誤寫成server.js //上面判斷執行環境時,使用的【NODE_ENV】就是這裏定義的變量【NODE_ENV】 //cross-env是一個咱們須要安裝的包,用於兼容windows,linux以及mac的命令行
$npm i cross-env -D
$npm run dev:client
解決方法:在devServer中添加配置:java
publicPath:'/public', //訪問靜態資源時都須要添加public historyApiFallback:{ //爲咱們自動配置了不少映射關係,單頁應用的全部url都會返回404,而該配置將全部前端返回的404請求都返回成historyApiFallback的index index:'/public/index.html' //指定index,由於publicPath添加了前綴,因此此處也須要添加前綴 }
$npm run dev:client
$npm run dev:client
,此時報錯:Uncaught Error: [HMR] Hot Module Replacement is disabled.
devServer
中開啓了hot:true
,可是並無安裝相關依賴模塊致使引用相關js文件shi出錯 $npm run dev:client
hot-module-replacement
)* `.babelrc`添加`presets`同級KV "plugins":["react-hot-loader/babel"] * `$npm i react-hot-loader@next -D` @next是由於當前爲測試版,還沒有正式發佈到npm中 * `app.js`加入如下內容,[個人第2篇文章](https://segmentfault.com/a/1190000012945475) ``` if(module.hot){ //當咱們須要熱更新的代碼有更新時,從新加載App module.hot('./App.jsx',()=>{ const NextApp=require('./App.jsx').default;//加default的緣由在上面連接中有提到 ReactDOM.hydrate(<NextApp />,document.getElementById('root')); }) } * `$npm run dev:client` ``` 發現頁面仍然會自動刷新,沒有實現 * `client配置中` ``` hot:true解註釋 const webpack=require('webpack') //頂部引入webpack config.plugins.push(new Webpack.HotModuleReplacementPlugins()); //與config.devServer同級添加webpack的HotModuleReplacementPlugins插件 //因爲在.babelrc中添加了hotmodule配置,須要在開發時修改entry,因爲只是在開發是進行修改,因此config.devServer中進行修改便可: config.entry={ app:[ 'react-hot-loader/patch', //客戶端熱更新代碼時須要用到的補丁包 path.join(__dirname,'./client/app.js') //要打包的內容 ]//webpack的entry能夠是個數組,表明着該entry中引用的文件,webpack在打包時會將全部的文件打包在一個文件中 } import React from 'react' import ReactDOM from 'react-dom' import { AppContainer } from 'react-hot-loader' //更新1:使用AppContainer去包裹咱們的根節點想要渲染的實際HTML內容 import App from './App.jsx' //ReactDOM.hydrate(<App />,document.getElementById('root')); //更新2:封裝成可傳遞參數的方法,此處註釋掉 //將App掛載在document.body中,由於此時並無模板,只有body可使用,官方推薦在body中建立一個默認節點做爲主dom const root=document.getElementById('root'); //更新3:根節點變量化 const render = Component =>{ const renderMethod=module.hot ? ReactDOM.render :ReactDOM.hydrate; //注意點! //若是不對是否採用react-hot-loader進行判斷,npm run dev:client時,進入瀏覽器會彈出錯誤 //Warning: Expected server HTML to contain a matching <div> in <div>. renderMethod( <AppContainer> <Component /> </AppContainer>, root ) }; //更新4:更新2的封裝 render(App); //更新5:傳參調用更新4 if(module.hot){ module.hot.accept('./App.jsx',()=>{ const NextApp=require('./App.jsx').default; //ReactDOM.hydrate(<App />,document.getElementById('root')); //更新6,採用封裝方法,此處註釋 render(NextApp) //更新7,傳參調用更新4 }) } * `npm run dev:client` 進入瀏覽器,修改內容,發現無需刷新便可更新內容,可是更新時間比較長, 想要更快更新,須要手動保存CTRL+S 另外,【若是】手動重啓devServer後hotmodule失效(頁面Elements刷新), 打開network,勾選Preserve log(用於保留刷新前的請求內容,防止刷新後之前的請求丟失致使很差定位問題), 修改內容後查看請求url,發現404請求,url樣式: http://localhost:3000/public6f45a1f9b1cb390b0ffb.hot-update.json 該文件通知hotmodule有模塊更新以更新內容,發現public後缺失"/",須要在修改成 publicPath:'/public/',推薦後面都加上'/', 多'/'不會出現路徑錯誤,少'/'卻會在某些時候引起不可預期的錯誤