npmwebpackhtml-webpack-plugin

Hot reloading templateParameters for HtmlWebpackPlugin


I have in my webpack.config.js:

const data = require('./src/data.json');

...

new HtmlWebpackPlugin({
    template: "src/index.hbs",
    filename: "index.html",
    templateParameters: {
        data: data
    },
}),

...

module: {
    rules: [
        {
            test:    /\.hbs$/,
            loader:  "handlebars-loader"
        }
    ],
},

devServer: {
    static:     './dist',
    hot:        true,
    liveReload: true,
    open:       false,
    watchFiles: ['src/**/*.hbs', './src/data.json'],

},

When run with npm start hot reloading works for my JS-Modules, but not if i make changes to the data.json. How can i reload the dev server when i make changes to that JSON-File?


Solution

  • 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

    Just one HtmlBundlerPlugin replaces the functionality of many plugins and loaders such as:

    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.