如果启用了热模块替换,为什么 LiveReload 在更改 HTML 时无法在 Webpack 中工作?
Why doesn't LiveReload work in Webpack when changing HTML if Hot Module Replacement is enabled?
如果你在Webpack的devServer
设置里设置了hot: true
,那么Hot Module Replacement CSS 有效并且无需重新加载完整页面即可应用更改。但是当更改 HTML 文件时,LiveReload 出于某种原因不起作用,您需要手动刷新页面以便应用更改。
如果 hot: true
在 devServer
配置文件中被禁用,那么当更改 HTML 文件时 LiveReload 工作正常,页面会自行重新加载,但是 CSS 的 热模块替换 不起作用,当更改 CSS 时,页面会完全重新加载。
这是应该的方式吗?为什么会发生这种情况,如何为 CSS 启用 Hot Module Replacement,但同时使 LiveReload 在更改 HTML 个文件?
要创建多个 HTML 文件,我使用 HtmlWebpackPlugin
插件。
配置文件如下:
webpack.common.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
module.exports = mode => {
const PRODUCTION = mode === 'production';
return {
entry: {
app: './src/index.js',
},
output: {
filename: 'js/[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[path][name].[ext]',
outputPath: 'img',
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
hash: false,
template: 'src/index.html',
filename: 'index.html',
}),
new webpack.DefinePlugin({
PRODUCTION: PRODUCTION,
}),
new CopyPlugin([
{ from: 'src/img', to: 'img' },
{ from: 'src/fonts', to: 'fonts' },
]),
],
}
};
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
module.exports = (env, argv) => {
return merge(common(argv.mode), {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
overlay: {
warnings: true,
errors: true
},
port: 8081,
hot: true,
},
watchOptions: {
aggregateTimeout: 100,
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
],
}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
});
};
如果您的问题仍然存在,请在启用 hmr 的情况下尝试以下操作:
npm i chokidar --save-dev
添加到 webpack 配置文件:const chokidar = require('chokidar')
添加到 webpack-dev-server 选项:
before(app, server) {
chokidar.watch([
'./build/**/*.html' //make sure to edit this path to your html files
]).on('all', function () {
server.sockWrite(server.sockets, 'content-changed');
});
},
如果你在Webpack的devServer
设置里设置了hot: true
,那么Hot Module Replacement CSS 有效并且无需重新加载完整页面即可应用更改。但是当更改 HTML 文件时,LiveReload 出于某种原因不起作用,您需要手动刷新页面以便应用更改。
如果 hot: true
在 devServer
配置文件中被禁用,那么当更改 HTML 文件时 LiveReload 工作正常,页面会自行重新加载,但是 CSS 的 热模块替换 不起作用,当更改 CSS 时,页面会完全重新加载。
这是应该的方式吗?为什么会发生这种情况,如何为 CSS 启用 Hot Module Replacement,但同时使 LiveReload 在更改 HTML 个文件?
要创建多个 HTML 文件,我使用 HtmlWebpackPlugin
插件。
配置文件如下:
webpack.common.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
module.exports = mode => {
const PRODUCTION = mode === 'production';
return {
entry: {
app: './src/index.js',
},
output: {
filename: 'js/[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[path][name].[ext]',
outputPath: 'img',
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
hash: false,
template: 'src/index.html',
filename: 'index.html',
}),
new webpack.DefinePlugin({
PRODUCTION: PRODUCTION,
}),
new CopyPlugin([
{ from: 'src/img', to: 'img' },
{ from: 'src/fonts', to: 'fonts' },
]),
],
}
};
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
module.exports = (env, argv) => {
return merge(common(argv.mode), {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
overlay: {
warnings: true,
errors: true
},
port: 8081,
hot: true,
},
watchOptions: {
aggregateTimeout: 100,
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
],
}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
});
};
如果您的问题仍然存在,请在启用 hmr 的情况下尝试以下操作:
npm i chokidar --save-dev
添加到 webpack 配置文件:
const chokidar = require('chokidar')
添加到 webpack-dev-server 选项:
before(app, server) { chokidar.watch([ './build/**/*.html' //make sure to edit this path to your html files ]).on('all', function () { server.sockWrite(server.sockets, 'content-changed'); }); },