webpack 模块热替换原理


Posted in Javascript onApril 09, 2018

全称是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;
};

这个webpack.config.js建立了两个配置,一个是commonConfig,一个是developmentConfig 两者通过env参数来区分,但这个env参数是怎么来的呢?我们看看之前的package.json中的一段:

webpack 模块热替换原理

也就是说,如果按照上面的这个配置,我们通过npm start 启动的话,进入的就是开发环境配置,如果是直接build,那么就是生产环境的方式。build方式是第一节里面讲的 直接通过npm启动webpack,这就不带WDS了。另外有了一个Object.assign语法,将配置合并。这个时候通过npm start启动,控制台打印出了两条日志。

webpack 模块热替换原理

看起来HRM已经启动了。但是此时更新一下component.js

webpack 模块热替换原理

日志显示没有东西被热更新。而且这个39,36代表的是模块Id,看起来很不直观,这里可以通过一个插件使其更符合人意

plugins: [
   new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
  ],

这个时候再启动。

webpack 模块热替换原理

这样名称就直观了。但是我们期待的更新还是没有出来。因为需要实现一个接口

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;
}

webpack 模块热替换原理

这个时候页面更新了。每次改动页面上都会增加一个带有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:webpack-ch3_3water.rar

参考:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
Feb 04 Javascript
jQuery表格行换色的三种实现方法
Jun 27 Javascript
推荐25个超炫的jQuery网格插件
Nov 28 Javascript
jQuery中:reset选择器用法实例
Jan 04 Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 Javascript
JS实现超精简响应鼠标显示二级菜单代码
Sep 12 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
Dec 31 Javascript
js实现复选框的全选和取消全选效果
Jan 03 Javascript
React Component存在的几种形式详解
Nov 06 Javascript
最简单的JS实现json转csv的方法
Jan 10 Javascript
vue实现抽屉弹窗效果
Nov 15 Javascript
vue实现防抖的实例代码
Jan 11 Vue.js
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
Apr 09 #Javascript
浅谈webpack 自动刷新与解析
Apr 09 #Javascript
webpack 插件html-webpack-plugin的具体使用
Apr 09 #Javascript
详解webpack 入门与解析
Apr 09 #Javascript
vue技术分享之你可能不知道的7个秘密
Apr 09 #Javascript
一步步教会你微信小程序的登录鉴权
Apr 09 #Javascript
vue组件详解之使用slot分发内容
Apr 09 #Javascript
You might like
咖啡语言
2021/03/03 咖啡文化
PHP和javascript常用正则表达式及用法实例
2014/07/01 PHP
Windows下php+mysql5.7配置教程
2017/05/16 PHP
Three.js源码阅读笔记(物体是如何组织的)
2012/12/27 Javascript
深入理解javaScript中的事件驱动
2013/05/21 Javascript
使用javascript做的一个随机点名程序
2014/02/13 Javascript
jquery果冻抖动效果实现方法
2015/01/15 Javascript
javascript显式类型转换实例分析
2015/04/25 Javascript
jQuery超简单选项卡完整实例
2015/09/26 Javascript
JavaScript 七大技巧(一)
2015/12/13 Javascript
JavaScript实现带播放列表的音乐播放器实例分享
2016/03/07 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
基于jQuery的ajax方法封装
2016/07/14 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
JavaScript实现QQ列表展开收缩扩展功能
2017/10/30 Javascript
webpack搭建vue 项目的步骤
2017/12/27 Javascript
Vue props用法详解(小结)
2018/07/03 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
Python中Django框架下的staticfiles使用简介
2015/05/30 Python
python函数装饰器用法实例详解
2015/06/04 Python
批处理与python代码混合编程的方法
2016/05/19 Python
Python上下文管理器和with块详解
2017/09/09 Python
Python何时应该使用Lambda函数
2019/07/02 Python
python实现的自动发送消息功能详解
2019/08/15 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
tensorflow 查看梯度方式
2020/02/04 Python
事业单位人员的自我评价范文
2014/09/21 职场文书
普通党员个人剖析材料
2014/10/08 职场文书
特此通知格式
2015/04/27 职场文书
2016年11月份红领巾广播稿
2015/12/21 职场文书
《七月的天山》教学反思
2016/02/19 职场文书
java基础——多线程
2021/07/03 Java/Android
win10壁纸在哪个文件夹 win10桌面背景图片文件位置分享
2022/08/05 数码科技