全稱是Hot Module ReplaceMent(HMR),理解成熱模塊替換或者模塊熱替換都可以吧,和.net中的熱插拔一個意思,就是在運行中對程序的模塊進行更新。這個功能主要是用於開發過程中,對生產環境沒有任何幫助(這一點區別.net熱插拔)。效果上就是界面的無刷新更新。
HMR基於WDS,style-loader可以通過它來實現無刷新更新樣式。但是對於JavaScript模塊就需要做一點額外的處理,怎么處理繼續往下看。因為HMR是用於開發環境的,所以我們修改下配置,做兩份准備。一個用於生產,一個用於開發。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'build'),
};
const commonConfig={
entry: {
app: PATHS.app,
},
output: {
path: PATHS.build,
filename: '[name].js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo',
}),
],
}
function developmentConfig(){
const config ={
devServer:{
//使能歷史記錄api
historyApiFallback:true,
hotOnly:true,//關閉熱替換 注釋掉這行就行
stats:'errors-only',
host:process.env.Host,
port:process.env.PORT,
overlay:{
errors:true,
warnings:true,
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
};
return Object.assign(
{},
commonConfig,
config,
{
plugins: commonConfig.plugins.concat(config.plugins),
}
);
}
module.exports = function(env){
console.log("env",env);
if(env=='development'){
return developmentConfig();
}
return commonConfig;
};
plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), ],

import component from './component'; let demoComponent=component(); document.body.appendChild(demoComponent); //HMR 接口 if(module.hot){ module.hot.accept('./component',()=>{ const nextComponent=component(); document.body.replaceChild(nextComponent,demoComponent); demoComponent=nextComponent; }) }
並修改component.js:
export default function () { var element = document.createElement('h1'); element.innerHTML = 'Hello webpack'; return element; }

這個時候頁面更新了。每次改動頁面上都會增加一個帶有hot-update.js ,類似於下面這樣:
webpackHotUpdate(0,{ /***/ "./app/component.js": /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony default export */ __webpack_exports__["default"] = function () { var element = document.createElement('h1'); element.innerHTML = 'Hello web '; element.className='box'; return element; }; /***/ }) })
通過webpackHotUpdate對相應模塊進行更新。0表示模塊的id,"./app/component.js"表示模塊對應的name。結構是webpack(id,{key:function(){}})。function外帶了一個括號,不知道有什么作用。webpackHotUpdate的定義是這樣的:
this["webpackHotUpdate"] = function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars
hotAddUpdateChunk(chunkId, moreModules); if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules); } ;
小結:從結構來看,一個是id,一個是對應修改的模塊。但實際執行更新的是hotApply方法。熱更新整個機制還是有點復雜,效果上像MVVM的那種綁定。有興趣的可以深入研究下。不建議在生產使用HMR,會讓整體文件變大,而且對生成沒有什么幫助,在下一節會講樣式的加載,style-loader就是用到了HMR。但對於js模塊還要寫額外的代碼,這讓人有點不爽。
demo:http://files.cnblogs.com/files/stoneniqiu/webpack-ch3.zip
