orangeyyy
1/1/2018 - 6:18 AM

webpack-HMR

概述

模块热替换(Hot Module Replacement 简称HMR)是webpack提供的非常有用的功能,它允许在运行时更新各个模块而无需进行完全刷新。HMR适用于开发环境,在页面开发调试过程中,当代码发生改变,只会影响发生改变的模块,其他模块的状态得以保留,因此不需要从头开始操作。

使用

HMR的使用非常简单,我们只需要进行下面几步操作:

  • 更新webpack-dev-server的配置开启HMR;
{
  devServer: {
    contentBase: './build',
    hot: true
  }
}
  • 引入webpack内置的HMR插件:
{
  plugins: [
    new webpack.NamedModulePlugin(),
    new webpack.HotModuleReplacementPlugin()
  ]
}
// 添加NamedModulePlugin以便更容易查看要修补的依赖
  • 在js入口文件中增加module.hot判断逻辑
if (module.hot) {
  module.hot.accept('./app.js', () => {
    doSomething();
  });
}

为了使HMR正常工作babel-preset-es2015需要禁用module,["es2015", { "modules": false }];

还好style-loader对HMR的支持,使我们在改变样式文件时,不需要做任何样式相关的配置就能支持;

React中的使用

为了在react项目中使用HMR,我们需要用到react-hot-loader,并且我们需要做如下配置:

  • 在babelrc中使用HMR插件:
// .babelrc
{
  "plugins": ["react-hot-loader/babel"]
}
  • 按照上面的方式开启HMR;
  • 在entry文件中打包patch文件;
// webpack.config.js
module.exports = {
  entry: ['babel-polyfill', 'react-hot-loader/patch', './main.js'],
}
  • 用包裹项目的入口组件:
// main.js
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './app'

const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById('root'),
  )
}

render(App)

// Webpack Hot Module Replacement API
if (module.hot) {
  module.hot.accept('./containers/App', () => {
    render(App)
  })
}

为了使HMR在嵌套routes下工作,devserver的publicPath必须设置为'';

参考