Webpack从手把手配置到原理浅析(五):自动刷新与热更新

1,526 阅读3分钟

在开发过程中,我们希望源代码文件后,Webpack就能检测到文件的变化,然后马上更新有改动的文件,不需要重启服务就能看到文件的变化。 那应该如何配置?

自动刷新

自动刷新是指webpack的devServer在监听到文件有变化后,会触发重新构建打包,然后自动刷新页面,源文件的变化就可以实时查看效果。

配置方式

devServer中默认配置了自动刷新的规则,无须手动配置。但仍可以手动修改一些配置的参数。

module.exports = {
  // ...
  devServer: {
      port: 8080,
      // ...
  },
  watch: true, // 开启监听,默认为 false
  watchOptions: {
    ignored: /node_modules/, // 忽略哪些
    // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
    // 默认为 300ms
    aggregateTimeout: 300,
    // 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
    // 默认每隔1000毫秒询问一次
    poll: 1000
  }
}

缺点

自动刷新会使整个页面全部刷新,速度慢,且程序的状态会丢失。

热更新

热更新又叫做模块热替换(hot module replacement 或 HMR),会在应用程序运行过程中,替换、添加或删除 模块,而无需重新加载整个页面。

配置方式

  1. 引入HotModuleReplacementPlugin插件
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');

module.exports = {
  // ...
  plugins: [
     new webpack.DefinePlugin({
         ENV: JSON.stringify('development')
     }),
     new HotModuleReplacementPlugin()
  ],
}
  1. 配置入口 原来的入口路径字符串,改为数组。
module.exports = {
  // ...
  entry: {
     // index: path.join(srcPath, 'index.js'),
     index: [
         'webpack-dev-server/client?http://localhost:8080/',// 端口与devServer里配置一致
         'webpack/hot/dev-server',
         path.join(srcPath, 'index.js')
     ],
 },
}
  1. devServer开启热更新
module.exports = {
  // ...
  devServer: {
     port: 8080,
     open: true,  // 自动打开浏览器
     hot: true,// 开启热更新
     // 设置代理
     proxy: {
         '/api': 'http://localhost:3000',
     }
 },
}
  1. 注册热更新范围 最后一步,要在代码中注册监听范围,使用module.hot.accept()函数指定热更新监听范围。 eg:在index.js中,要监听./sum.js文件,如果有更新就马上执行指定函数:
import { add } from './sum'

if (module.hot) {
  // 监听./sum文件的改变
 module.hot.accept(['./sum'], () => {
     const res = add(10, 30)
     console.log('res in hot', res)
  })
}

优点

主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面期间丢失的应用程序状态
  • 只更新变更内容,以节省宝贵的开发时间
  • 在源代码中 CSS/JS 产生修改时,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式

缺点

要在代码里注册热更新的范围,增加代码量。所以除非代码太庞大,更新速度很慢,一般开启热更新反而会增加开发开销。

注意

自动刷新和热更新只能在开发环境中使用,即只需要在webpack.dev.js中配置,不可用于生产环境。原因是自动刷新和热更新都是为了监听源文件变化而进行更新,生产环境都是打包好的静态文件,不会出现源文件的变化,所以生产环境无须进行自动刷新和热更新的配置