深入浅出webpack-热更新

    科技2026-10-03  11

    什么是热更新?

    使用vue或者react框架开发的时,只要项目启动了,无论修改js代码还是css代码,浏览器都会更新,可能有很多童鞋会认为这就是热更新,实际上这个你看到的并不是热更新。

    初始化项目

    npm init touch index.html touch app.js npm i webpack webpack-cli webpack-dev-server --D

    注意:这里使用的是webpack 4.x,如果直接使用全局的webpack来打包,需要安装webpack-cli ,因为需要这样来打包:

    webpack-cli --entry ./app.js --output build.js

    这里没有全局安装webpack, 所以需要配置命令行:

    package.json

    "build": "webpack", "dev": "webpack-dev-server"

    这个时候如果需要启动本地服务,只需要npm run dev就可以了。但是run dev的时候会默认查找根目录下的webpck.config.js文件,下面需要配置一下该文件:

    webpack.config.js

    const path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode:'development', entry: './index.js', output: { path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js' }, module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', "options": { "presets":[ ["@babel/preset-env", { "targets": { "browsers": [">1%"] // 编译成全球占有率大于1%的浏览器都可以识别 node } }] ], } } }, { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] } ] }, plugins: [ // 处理html文件 打包压缩 new HtmlWebpackPlugin({ filename:'index.html', template : './index.html', inject: true, // 是否自动引入 默认true true/false minify:{ // 压缩 removeComments:true, //删除注释 collapseWhitespace: true //删除空格,压缩 }, }) ] }

    上面是一个简单的配置,通常使用的js文件,都会使用es6语法编写,所以需要将es6的语法编译成es5,这个过程需要用babel来处理。

    npm install babel-loader @babel/core --save-dev

    配置编译目标: 

    npm i @babel/preset-env --D

    处理css文件:

    npm i style-loader css-loader --D

    处理 html文件:

    npm i html-webpack-plugin --D

    app.js写入es6内容:

    import './app.css' (function() { let i = 0; setInterval(() => { console.log(`${i++}`) }, 2000) })()

    启动本地服务:cnpm run  dev

    页面刷新

    touch app.css

    app.css

    #app { color: blue; }

    页面字体颜色: 

    修改 app.css :

    #app { color: red; }

    保存后查看页面,字体颜色已经更新为红色:

    修改js文件:

    setInterval(() => { console.log(`${i++}刷新了`) }, 2000)

    保存后看打印结果,数字又从0开始了,说明浏览器刷新了,也就是重新加载了: 

     

    再修改一下html文件,文案也发生了变化,打印再次从0开始,浏览器reload了:

     如果只是简单的小项目开发,简单的配置就可以满足需求;如果你的项目会比较大,或者随着需求的增加,越来越大,这个时候就会发现这种方式的弊端了。

    项目太大,开发环境下体积比较大,每次的页面刷新耗时较长,影响开发速度。只改变一点内容就刷新整个页面,有点资源浪费。

    热更新

    也就是webpack的模块热替换。它允许在运行时替换,添加,删除各种模块,而无需进行完全刷新重新加载整个页面,优点:

    保留在完全重新加载页面时丢失的应用程序的状态只更新改变的内容,以节省开发时间调整样式更加快速,几乎等同于就在浏览器调试器中更改样式

    配置devServer属性:

    devServer: { hot: true } devServer: {   hot: true, hotOnly: true // 禁用页面刷新,只使用热更新 } 

     

    开启热更新后,会发现 修改css文件页面不刷新,只更新。修改js文件页面依然会刷新,如果要让修改js文件变成热更新,需要=结合插件一起:

    new webpack.HotModuleReplacementPlugin()

    入口文件app.js中加入下面代码,开启只更新不刷新模式:

    if (module.hot) { module.hot.accept() }

    看页面打印:

    更新app.js文件,内容更新了,又开启了一个定时器,页面不是刷新,这就是模块热更新:

     

    模块热替换还支持这样的配置:

    if (module.hot) { module.hot.accept( './library.js', // 可以是一个字符串或字符串数组 function() { // 使用更新过的 library 模块执行某些操作... }) }

    注意:热更新和extract-text-webpack-plugin插件不兼容,开发环境,使用热更新,就不使用这个插件,disbale设置为true。

    Processed: 0.009, SQL: 9