Webpack 是当前前端工程化中最流行的打包工具之一,通过它我们可以将多个文件打包成一个文件,并对这个文件进行代码压缩、合并、优化等操作,以减少网络请求次数,提高网站性能。热更新则是 Webpack 中一项非常重要的功能,它可以在我们修改代码后自动刷新页面,以进行实时预览,提高开发效率。但是,有时候我们会发现热更新失效了,本文将介绍如何解决这个问题。
热更新失效的原因
热更新失效一般是因为 Webpack 自动监控文件变化的方式不太准确,导致无法正确的更新。这个错误通常是由以下原因引起的:
- 在
entry属性中添加了 HTML 文件或者使用了绝对路径 - 在入口文件中写了错误的代码
- 在模块化代码中引入了模块级别的状态变量
- 在模块化代码中使用了
class
解决方案
解决热更新失效的问题一般有以下几种方案:
1. 关闭热更新
如果你真的无法解决热更新失效的问题,你可以尝试关闭热更新,然后每次修改代码后手动刷新页面。关闭热更新的方式如下:
// webpack.config.js
module.exports = {
// ...
devServer: {
hot: false, // 关闭热更新
},
// ...
};2. 修复代码中的错误
在入口文件以及被入口文件引入的模块中,有可能存在错误的语法或者不支持热更新的使用方式,导致热更新失效。解决这个问题的方法是找到并修复代码中的错误。
3. 使用模块热更新
Webpack 中提供了模块热更新(Hot Module Replacement)功能,它是一种更加精确的热更新方式,只会更新被修改到的模块,而不是整个页面。使用模块热更新的方式如下:
// www.javascriptcn.com code example
// webpack.config.js
module.exports = {
// ...
devServer: {
hot: true, // 启用热更新
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 配置模块热更新
],
// ...
};4. 配置文件增加 ignore 参考
通过配置文件增加 ignore 参考,使得 Webpack 自动忽略掉一部分文件更新。例如,你只需要更新代码中的 .js 文件,而不需要更新 HTML 文件,那么在配置文件中增加以下代码:
// webpack.config.js
module.exports = {
// ...
watchOptions: {
ignored: /node_modules|dist|.html$/,
},
// ...
};这里的正则表达式 /node_modules|dist|.html$/ 表示忽略 node_modules、dist 文件夹和以 .html 结尾的文件。
示例代码
为了更好的理解上述方案,下面的示例代码将项热更新被禁用的情况下,手动关闭和启用热更新,并分别讲解相应的代码片段。
// www.javascriptcn.com code example
// webpack.config.js
const webpack = require('webpack');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
path: __dirname + '/dist',
filename: 'index.js',
},
devServer: {
contentBase: './dist', // 将 dist 文件夹设置为本地服务器的根目录
hot: false, // 关闭热更新
},
module: {
rules: [ // babel支持
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 配置模块热更新
],
};这里我们关闭了模块热更新,并启用了 babel 转义支持。在开发过程中,我们找到以下代码并尝试进行调整:
const btn = document.querySelector('#button');
btn.addEventListener('click', () => {
const wrapper = document.createElement('div');
wrapper.innerHTML = 'Hello Webpack';
document.body.appendChild(wrapper);
})当你进行修改并保存时,发现浏览器页面并没有触发自动刷新。
首先,我们尝试手动刷新页面。然后,我们再尝试启用模块热更新:
// www.javascriptcn.com code example
// webpack.config.js
const webpack = require('webpack');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
path: __dirname + '/dist',
filename: 'index.js',
},
devServer: {
contentBase: './dist', // 将 dist 文件夹设置为本地服务器的根目录
hot: true, // 打开热更新
},
module: {
rules: [ // babel支持
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 配置模块热更新
],
};修改代码后,运行 npm run dev,再次在浏览器中访问 http://localhost:8080,修改后的内容应该实现了非常明显的变化。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d685b7a941bf7134c4e983