1.定义
HMR即HotModuleReplacement
开发时,当我们修改了其中一个模块的代码webpack默认会将所有模块重新打包编译,速度很慢所以我们需要做到修改摸个模块代码,只对这个模块的代码重新打包编译,其他模块不变,这样打包的速度就能变快
HotModuleReplacement(HMR/热模块替换):在程序运行中,替换、添加或者删除模块,而无需重新加载整个页面
2.配置
在webpack.dev.js中添加配置
/**开发服务器 */devServer: {host: 'localhost',//启动服务器域名port: "3000",//启动服务器端口号open: true,//是否自动打开浏览器hot: true,//开启HMR功能(只能用于开发环境,生产环境不需要)},
然后执行命令
npx webpack serve --config ./config/webpack.dev.js
进行开发模式的运行
此时css文件已经可以实现HMR了,修改css文件保存,整个页面不会刷新,只会更新修改的模块。
此时控制台会打印出哪个模块进行了HMR
3.实现JS文件的HMR
对于JS文件webpack不会在配置后自动进行HMR,需要手动进行配置
在打包的入口文件中即main.js文件中对需要HMR的模块进行逐个的引入
添加如下代码
//添加JS热更新
if (module.hot) {console.log('支持热更新');//判断是否支持热更新module.hot.accept('./js/sum.js')module.hot.accept('./js/count.js')
}
然后重新运行
修改count.js模块,在查看控制台,发现count.js已经可以进行HMR了。
4.完整代码
webpack.dev.js
const path = require('path');//nodejs用来处理路径问题的模块
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackDevServer = require('webpack-dev-server');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const loader = require('sass-loader');
function getCssLoader(pre) {return [MiniCssExtractPlugin.loader, 'css-loader',{loader: 'postcss-loader',options: {postcssOptions: {plugins: ['postcss-preset-env']}}}, pre].filter(Boolean)
}
module.exports = {/**入口 */entry: './src/main.js',/**输出 相对路径*/output: {/**文件输出路径 绝对路径*///__dirname 表示当前文件的文件夹目录path: undefined,//所有文件的输出目录/**文件名 */filename: 'static/js/dist.js',//入口文件输出文件名clean: true,//在打包前将path整个目录内容情况},/**加载器 */module: {rules: [//loader的配置{/**test 代表要检测的文件 */test: /\.css$/, //只检测.css文件use: getCssLoader() //对检测到文件使用哪些loader},{test: /\.less$/,//只检测.less文件//loader:'xxx',loader只能使用一个loader,use可以使用多个loaderuse: getCssLoader('less-loader'),//对检测到文件使用哪些loader},{test: /\.s[ac]ss$/,//只检测.sass文件use: getCssLoader('sass-loader'),},{test: /\.styl$/,//只检测.stylus文件use: getCssLoader('stylus-loader')},{test: /\.(png|jpe?g|gif|webp)$/,type: 'asset/resource',parser: {dataUrlCondition: {//小于10kb的图标转base64,减少请求数量maxSize: 10 * 1024 // 10kb}},generator: {//输出图片名称//[hash:10]hash值取前10位filename: 'static/imgs/[hash:10][ext][query]'}},/**图标字体相关配置 */{test: /\.(ttf|woff2?|mp3|mp4|avi)$/,//只对ttf、woff2资源起作用type: 'asset/resource',//加上/resource表示将资源原封不动的打包出来generator: {filename: "static/media/[hash][ext][query]"}},{test: /\.js$/,/**排除哪些文件 */exclude: /(node_modules)/,loader: 'babel-loader',// options: {// presets: ['@babel/preset-env'],// },},]},/**插件 */plugins: [//plugin配置new ESLintPlugin({/** 检测哪些文件 */context: path.resolve(__dirname, '../src')}),new HtmlWebpackPlugin({/**模板 */template: path.resolve(__dirname, '../src/public/index.html')}),new MiniCssExtractPlugin()],/**开发服务器 */devServer: {host: 'localhost',//启动服务器域名port: "3000",//启动服务器端口号open: true,//是否自动打开浏览器hot: true,//开启HMR功能(只能用于开发环境,生产环境不需要)},/**模式 */mode: 'development',devtool: 'cheap-module-source-map'
}
main.js
import sum from "./js/sum";
import count from "./js/count";
//要想webpack打包资源,必须引入该资源
import "./css/file.css"
import "./css/box.less"
import "./css/box2.scss"
import "./css/box3.styl"
import "../src/css/iconfont.css"
console.log(count(1, 2));
console.log(sum(1, 2, 3, 4, 5))
//添加JS热更新
if (module.hot) {console.log('支持热更新');//判断是否支持热更新module.hot.accept('./js/sum.js')module.hot.accept('./js/count.js')
}