You can try to use modern powerful html-bundler-webpack-plugin instead of html-webpack-plugin.
Use the data plugin option as a JSON or JS filename to recompile and reload pages after changes of variables in the data file without restarting Webpack.
Using the Bundler Plugin
- An entry point is a template (HTML, handlebars, EJS, etc.).
- All your source asset files (scripts, styles, images, etc.) can be specified directly in the HTML template.
- The plugin resolves source files of assets in templates and replaces them with correct output URLs in the generated HTML.
- The resolved assets will be processed via Webpack plugins/loaders and placed into the output directory.
Just one HtmlBundlerPlugin replaces the functionality of many plugins and loaders such as:
- html-webpack-plugin
- handlebars-webpack-plugin
- handlebars-loader
- mini-css-extract-plugin
- style-loader
- and many others
For example there is your page template ./src/index.hbs:
<!DOCTYPE html>
<html>
<head>
<!-- `title` is the vaiable passed from data.json via webpack -->
<title>{{ title }}</title>
<!-- relative path to favicon source file -->
<link href="./favicon.ico" rel="icon" />
<!-- relative path to SCSS source file -->
<link href="./style.scss" rel="stylesheet" />
<!-- relative path to JS source file -->
<script src="./main.js" defer="defer"></script>
</head>
<body>
<h1>Hello World!</h1>
<!-- relative path to image source file -->
<img src="./images/picture.png" />
</body>
</html>
The data file can be a JSON or JS file, e.g. src/data.json
{
"title": "My Title"
}
The Webpack config example:
const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
plugins: [
new HtmlBundlerPlugin({
entry: [
{
import: 'src/index.hbs',
filename: 'index.html',
data: 'src/data.json', // <= relative path to data used in this page
},
// add your pages here
],
data: 'src/data.json', // <= relative path to global data passed into all pages
preprocessor: 'handlebars', // <= enable support *.hbs templates
preprocessorOptions: {
partials: [
'src/partials/', // path to your partials
],
},
}),
],
module: {
rules: [
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader'],
},
{
test: /\.(ico|png|jp?g|webp|svg)$/,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash:8][ext][query]',
},
},
],
},
// enable live reload
devServer: {
static: path.join(__dirname, 'dist'),
watchFiles: {
paths: ['src/**/*.*'],
options: {
usePolling: true,
},
},
},
};
Here is the handlebars example used JSON data files as external data passed into templates.
P.S. You can create a small repository on GitHub and then I can help you do your project working.