談到webpack想必大家都不陌生,在前端工程化大行其道的今天,大多數開發者都在用類似webpack, fis3,rollup,gulp,grunt等等的前端項目的打包構建工具。今天的豬腳就是webpack的hot module replacement,說道hmr想必大家會有所熟悉,這不就是更改源碼,頁面在不刷新的情況下某個模塊做出改變嗎?然而,或許大多數開發者看到的往往是頁面的刷新所帶來的源碼更改效果,這個結果就違背了我們踐行hmr技術的初衷了,原因呢,就是我們隊配置不是很熟悉,所以今天我們需要仔細梳理一下hmr技術需要做到哪些准備。
本教程基於nodejs的api去實現,這樣可以做到對流程最大化的控制。
1. 首先確webpack的配置對象的entry入口添加兩個文件。
對於在nodejs的api下,devserver是無法讀取webpack的配置的,所以我們需要手動在入口處添加客戶端文件,並且deverser的hot等配置項是無效的。
1 var config = require('config'); 2 var webpack = require('webpack'); 3 var webpackDevServer = require('webpack-dev-server'); 4 5 var path = require('path'); 6 7 var webpackConfig = require('../build/webpack.dev.config'); // 導入webpack配置對象 8 9 process.env.NODE_ENV = 'development'; 10 11 var name = config.get('name'); 12 13 webpackConfig.entry.unshift('webpack/hot/dev-server'); // 注入hot插件后的客戶端文件,可以監聽到某個模塊去冒泡更新 14 webpackConfig.entry.unshift('webpack-dev-server/client?http://localhost:8080'); // 注入devserver客戶端可以開啟inilne模式監聽源碼變動,使其得到更新 15 var compiler = webpack(webpackConfig);// 編譯配置並生成compiler對象 16 17 var server = new webpackDevServer(compiler, { // 生成devserver對象 18 }); 19 20 server.listen(8080);
2. 確保配置的插件項里添加了webpack.HotModuleReplacement的這個插件
1 var path = require('path'); 2 var webpack = require('webpack'); 3 var htmlWebpackPlugin = require('html-webpack-plugin'); 4 var openBrowserPlugin = require('open-browser-webpack-plugin'); 5 6 module.exports = { 7 entry: [path.join(__dirname, '../src/index.js')], 8 output: { 9 path: path.join(__dirname, '../dist'), 10 filename: '[name].[hash].js', 11 publicPath: '/' 12 }, 13 plugins: [ 14 new htmlWebpackPlugin({ 15 filename: 'index.html', 16 template: path.join(__dirname, '../public/index.html'), 17 inject: 'body' 18 }), 19 new webpack.HotModuleReplacementPlugin() 20 ], 21 module: {}, 22 }
3. 在項目的入口處理module.hot.accept
1 if (module.hot) { 2 module.hot.accept(() => { 3 ReactDom.render( 4 <App />, 5 document.getElementById('root') 6 ) 7 }) 8 } 9 10 ReactDom.render( 11 <App />, 12 document.getElementById('root') 13 )
當然,到這里我們就實現了hmr所需要的所有配置了,但是呢,我們更改的諸如react的state會重置,所以,如果需要保留react的狀態的話,我們還需要react-hot-loader插件。
4. 添加react-host-loader
可以直接參考官網的栗子 https://github.com/gaearon/react-hot-loader