New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

html-bundler-webpack-plugin

Package Overview
Dependencies
Maintainers
1
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

html-bundler-webpack-plugin

HTML bundler plugin for webpack handels HTML files as entrypoint and extracts CSS, JS, images from their sources loaded in HTML.

  • 0.6.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3.2K
decreased by-15.4%
Maintainers
1
Weekly downloads
 
Created
Source


HTML Bundler Plugin for Webpack

HTML Bundler Plugin is the right way to bundle all resources with your HTML files

npm node node codecov node

This is a new powerful plugin that does exactly what you want, automatically extracts JS, CSS, images, fonts from their sources loaded directly in HTML. The generated HTML contains output hashed filenames of processed source files. The plugin allow to use an HTML file or a template as an entry point in Webpack.

The purpose of this plugin is to make the developer's life much easier than it was using html-webpack-plugin mini-css-extract-plugin and other plugins.

💡 Highlights:

  • Define your HTML templates in Webpack entry.
  • The HTML template is the entry point for all source scripts and styles.
  • Source scripts and styles can be loaded directly in HTML using <script> and <link> tags.
  • All JS and CSS files will be extracted from their sources loaded in HTML tags.
  • You can easily inline JS, CSS, SVG, images without additional plugins and loaders.
  • You can easily use a template engine, e.g. Nunjucks, Handlebars and others without template loaders

This plugin works like the pug-plugin but the entry point is a HTML template.

How to easily build a multipage website with this plugin, see the Webpack boilerplate used the html-bundler-webpack-plugin;

Simple usage example

Add source scripts, styles, images directly to HTML using a relative path or a Webpack alias:

<html>
  <head>
    <!-- load source style -->
    <link href="./style.scss" rel="stylesheet">
    <!-- load source script -->
    <script src="./main.js" defer="defer"></script>
  </head>
  <body>
    <h1>Hello World!</h1>
    <!-- @images is the Webpack alias for the source images directory -->
    <img src="@images/logo.png">
  </body>
</html>

The generated HTML contains hashed output filenames of processed source files:

<html>
  <head>
    <link href="/assets/css/style.05e4dd86.css" rel="stylesheet">
    <script src="/assets/js/main.f4b855d8.js" defer="defer"></script>
  </head>
  <body>
    <h1>Hello World!</h1>
    <img src="/assets/img/logo.58b43bd8.png">
  </body>
</html>

Add the HTML templates in the Webpack entry:

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  entry: {
    // define HTML templates here
    index: './src/views/home/index.html', // output dist/index.html
  },
  resolve: {
    alias: {
      '@images': path.join(__dirname, './src/images'),
    },
  },
  plugins: [
    // enable processing of HTML templates defined in Webpack entry
    new HtmlBundlerPlugin(),
  ],
  module: {
    rules: [
      {
        test: /.html/,
        loader: HtmlBundlerPlugin.loader, // HTML template loader
      },
      // ... other rules, e.g. for styles, images, fonts, etc.
    ],
  },
};

Contents


  1. Install and Quick start
  2. Features
  3. Plugin options
  4. Loader options
  5. Recipes

Features

  • HTML file is the entry point for all resources (styles, scripts)
  • handels HTML files defined in Webpack entry
  • extracts CSS from source style loaded in HTML via a <link> tag
  • extracts JS from source script loaded in HTML via a <script> tag
  • resolves source files in the CSS url() and in HTML attributes
  • extracts resolved resources to output directory
  • generated HTML contains hashed CSS, JS, images, fonts output filenames
  • support the module types asset/resource asset/inline asset
  • inline CSS in HTML
  • inline JavaScript in HTML
  • inline image as base64 encoded data-URL for PNG, JPG, etc. in HTML and CSS
  • inline SVG as SVG tag in HTML
  • inline SVG as utf-8 data-URL in CSS
  • support the auto publicPath

Just one HTML bundler plugin replaces the most used functionality of the plugins and loaders:

PackageFeatures
html-webpack-pluginextract HTML and save in a file
mini-css-extract-pluginextract CSS and save in a file
webpack-remove-empty-scriptsremove empty JS files generated by the mini-css-extract-plugin
html-loaderexports HTML as string
style-loaderinject CSS into the DOM
resolve-url-loaderresolve relative url in CSS
svg-url-loaderencode SVG data-URL as utf8
posthtml-inline-svginline SVG icons in HTML

Install and Quick start

Install the html-bundler-webpack-plugin:

npm install html-bundler-webpack-plugin --save-dev

Install additional packages for styles:

npm install css-loader sass sass-loader --save-dev

Change your webpack.config.js according to the following minimal configuration:

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
    publicPath: '/',
  },

  entry: {
    // define HTML files here
    index: './src/views/home/index.html',  // output dist/index.html
    'pages/about': './src/views/about/index.html', // output dist/pages/about.html
    // ...
  },

  plugins: [
    new HtmlBundlerPlugin({
      js: {
        // output filename of extracted JS from source script loaded in HTML via `<script>` tag
        filename: 'assets/js/[name].[contenthash:8].js',
      },
      css: {
        // output filename of extracted CSS from source style loaded in HTML via `<link>` tag
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],

  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader, //  HTML template loader
      },
      {
        test: /\.(css|sass|scss)$/,
        use: ['css-loader', 'sass-loader'],
      },
    ],
  },
};

Plugin options

verbose

Type: boolean Default: false
Display information about extracted files.

test

Type: RegExp Default: /\.html$/
The test option allows то handel only those entry points that match their source filename.

For example, if you has *.html and *.hbs entry points, then you can set the option to match all needed files: test: /\.(html|hbs)$/.

outputPath

Type: string Default: webpack.options.output.path
The output directory for processed file. This directory can be relative by webpack.options.output.path or absolute.

filename

Type: string | Function Default: [name].html
The name of output file.

  • If type is string then following substitutions (see output.filename for chunk-level) are available in template string:
    • [id] The ID of the chunk.
    • [name] Only filename without extension or path.
    • [contenthash] The hash of the content.
    • [contenthash:nn] The nn is the length of hashes (defaults to 20).
  • If type is Function then following arguments are available in the function:
    • @param {PathData} pathData has the useful properties (see the type PathData):
      • pathData.filename the full path to source file
      • pathData.chunk.name the name of entry key
    • @param {AssetInfo} assetInfo Mostly this object is empty.
    • @return {string} The name or template string of output file.

css

Type: Object
Default properties:

{
  test: /\.(css|scss|sass|less|styl)$/,
  verbose: false,
  filename: '[name].css',
  outputPath: null,
}

The filename property see by filename option. The outputPath property see by outputPath option.

The option to extract CSS from a style source file loaded in the HTML tag:

<link href="./style.scss" rel="stylesheet">

Warning

Don't import source styles in JavaScript! Styles must be loaded directly in HTML.

The default CSS output filename is [name].css. You can specify your own filename using webpack filename substitutions:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      css: {
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],
};

The [name] is the base filename of a loaded style. For example, if source file is style.scss, then output filename will be assets/css/style.1234abcd.css.
If you want to have a different output filename, you can use the filename options as the function.

Warning

Don't use mini-css-extract-plugin or style-loader, they are not required more.
The html-bundler-webpack-plugin extracts CSS much faster than other plugins and resolves all asset URLs in CSS, therefore the resolve-url-loader is redundant too.

js

Type: Object
Default properties:

{
  verbose: false,
  filename: '[name].js', 
  outputPath: null,
}

The filename property see by filename option. The outputPath property see by outputPath option. The test property not exist because all JS files loaded in <script> tag are automatically detected.

The option to extract JS from a script source file loaded in the HTML tag:

<script src="./main.js"></script>

The default JS output filename is [name].js. You can specify your own filename using webpack filename substitutions:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      js: {
        filename: 'assets/js/[name].[contenthash:8].js',
      },
    }),
  ],
};

The [name] is the base filename script. For example, if source file is main.js, then output filename will be assets/js/main.1234abcd.js.
If you want to have a different output filename, you can use the filename options as the function.

extractComments

Type: boolean Default: false
Enable / disable extraction of comments to *.LICENSE.txt file.

When using splitChunks optimization for node modules containing comments, Webpack extracts those comments into a separate text file. By default, the plugin don't create such unwanted text files. But if you want to extract files like *.LICENSE.txt, set this option to true:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      extractComments: true,
    }),
  ],
};

Loader options

sources

Type:

type sources =
  | boolean
  | Array<{
      tag?: string;
      attributes?: Array<string>;
      filter?: ({
        tag: string,
        attribute: string,
        value: string,
        attributes: string,
        resourcePath: string
      }) => boolean|undefined;
    }>;

Default: true

By default, resolves source files in the following attributes:

TagAttributes
linkhref (for type="text/css" or rel="stylesheet") imagesrcset (for as="image")
scriptsrc
imgsrc srcset
inputsrc (for type="image")
sourcesrc srcset
audiosrc
tracksrc
videosrc poster
objectdata

To disable the processing of all attributes, set the source option as false.

Note

Automatically are processed only attributes containing a relative path or Webpack alias, e.g.:

  • src="./image.png" - relative path to local directory
  • src="../../assets/image.png" - relative path to parent directory
  • src="@images/image.png" - image directory as Webpack alias

Url values like following are not processed, e.g.:

  • src="https://example.com/img/image.png"
  • src="//example.com/img/image.png"
  • src="/img/image.png"

Other not file values are ignored, e.g.:

  • src="data:image/png; ..."
  • src="javascript: ..."

The default tags can be extended with new attributes or add new tags and attributes.

For example, add the processing of the data-src and data-srcset attributes to the img tag:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader,
        options: {
          sources: [
            {
              tag: 'img',
              attributes: ['data-src', 'data-srcset'],
            }
          ],
        },
      },
    ],
  },
};

You can use the filter function to allow processing for specific attributes.

For example, use filter to allow processing for images in meta tag by content attribute:

<html>
  <head>
    <!-- ignore the attribute via filter -->
    <meta name="theme-color" content="#ffffff">
    <!-- resolve the 'content' attribute if 'name' containing special values  -->
    <meta name="twitter:image" content="./image.png">
    <meta name="logo" content="./logo.png">
  </head>
  <body>
    <!-- resolve 'src' attribute containing relative path -->
    <img src="./image.png">
  </body>
</html>

webpack.config.js

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader,
        options: {
          sources: [
            {
              tag: 'meta',
              attributes: ['content'],
              // note: use the destruction of used variables from the object argument
              filter: ({ tag, attribute, value, attributes, resourcePath }) => {
                const allowedNames = ['twitter:image', 'logo'];
                if ('name' in attributes && allowedNames.indexOf(attributes.name) < 0) {
                  return false;
                }
              },
            }
          ],
        },
      },
    ],
  },
};

The filter parameter is an object containing the properties:

  • tag the name of the HTML tag
  • attribute the name of the HTML attribute
  • value the value of the HTML attribute
  • attributes all attributes of the tag
  • resourcePath the path of the HTML file

The attribute can be ignored by returning false, otherwise the function should return nothing.

Filter can disable an attribute of a tag.

For example, disable the processing of default attribute srcset of the img tag:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader,
        options: {
          sources: [
            {
              tag: 'img',
              filter: ({ attribute }) => attribute !== 'srcset',
            }
          ],
        },
      },
    ],
  },
};

preprocessor

Type:

type preprocessor = (
  content: string,
  loaderContext: LoaderContext
) => HTMLElement;

Default: undefined

The content argument is raw content of a file.
The loaderContext argument is an object contained useful properties, e.g.:

  • mode - the Webpack mode: production, development, none
  • rootContext - the path to Webpack context
  • resource - the template file

Complete API see by the Loader Context.

The preprocessor is called before handling of the content. This function can be used to replace a placeholder with a variable or compile the content with a template engine, e.g. Handlebars.

For example, set variable in the template index.html

<html>
<head>
  <title>{{title}}</title>
</head>
<body>
  <h1>Hello World!</h1>
</body>
</html>

Webpack config

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
  },

  entry: {
    index: './src/index.html',
  },

  plugins: [new HtmlBundlerPlugin()],

  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader,
        options: {
          preprocessor: (content, loaderContext) => content.replace('{{title}}', 'Homepage'),
        },
      },
    ],
  },
};

Note

Using the preprocessor you can use anyone template engine without its loader.

The preprocessor will be called for each entry file. For multipage configuration, you can use the loaderContext.resource property to differentiate data for diverse pages. See the usage example.


How to use source images in HTML

Add to Webpack config the rule:

module: {
  rules: [
    {
      test: /\.(png|jpe?g|ico)/,
      type: 'asset/resource',
      generator: {
        filename: 'assets/img/[name].[hash:8][ext]',
      },
    },
  ],
}

Add a source file using a relative path or Webpack alias in HTML:

<html>
  <head>
    <link href="./favicon.ico" rel="icon" />
  </head>
  <body>
    <img src="./apple.png" srcset="./apple1.png 320w, ./apple2.png 640w" alt="apple">
    <picture>
      <source srcset="./fig1.jpg, ./fig2.jpg 320w, ./fig3.jpg 640w">
    </picture>
  </body>
</html>

The generated HTML contains hashed output images filenames:

<html>
  <head>
    <link href="/assets/img/favicon.05e4dd86.ico" rel="icon" />
  </head>
  <body>
    <img src="/assets/img/apple.f4b855d8.png" srcset="/assets/img/apple1.855f4bd8.png 320w, /assets/img/apple2.d8f4b855.png 640w" alt="apple">
    <picture>
      <source srcset="/assets/img/fig1.605e4dd8.jpg, /assets/img/fig2.8605e4dd.jpg 320w, /assets/img/fig3.e4605dd8.jpg 640w">
    </picture>
  </body>
</html>

How to preload source fonts in HTML

Add to Webpack config the rule:

module: {
  rules: [
    {
      test: /\.(eot|ttf|woff|woff2)/,
      type: 'asset/resource',
      generator: {
        filename: 'assets/fonts/[name][ext]',
      },
    },
  ],
}

Add a source file using a relative path or Webpack alias in HTML:

<html>
  <head>
    <link href="./font1.woff2" rel="preload" as="font" type="font/woff2" />
    <link href="./font2.woff2" rel="preload" as="font" type="font/woff2" />
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

The generated HTML contains output fonts filenames:

<html>
  <head>
    <link href="/assets/fonts/font1.woff2" rel="preload" as="font" type="font/woff2" />
    <link href="/assets/fonts/font2.woff2" rel="preload" as="font" type="font/woff2" />
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

Note

You don't need a plugin to copy files from source directory to public.

How to inline CSS in HTML

For example, the style.scss:

$color: red;
h1 {
  color: $color;
}

Add the ?inline query to the source filename which you want to inline:

<html>
  <head>
    <!-- load style as file -->
    <link href="./main.scss" rel="stylesheet" />
    <!-- inline style -->
    <link href="./style.scss?inline" rel="stylesheet" />
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

The generated HTML contains inline CSS already processed via Webpack:

<html>
  <head>
    <!-- load style as file -->
    <link href="/assets/css/main.05e4dd86.css" rel="stylesheet">
    <!-- inline style -->
    <style>
      h1{color: red;}
    </style>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

Note

To enable source map in inline CSS set the Webpack option devtool.

How to inline JS in HTML

For example, the script.js:

console.log('Hello JS!');

Add the ?inline query to the source filename which you want to inline:

<html>
  <head>
    <!-- load script as file -->
    <script src="./main.js" defer="defer"></script>
    <!-- inline script -->
    <script src="./script.js?inline"></script>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

The generated HTML contains inline JS already compiled via Webpack:

<html>
  <head>
    <!-- load style as file -->
    <script src="assets/js/main.992ba657.js" defer="defer"></script>
    <!-- inline script -->
    <script>
      (()=>{"use strict";console.log("Hello JS!")})();
    </script>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>

Note

If Webpack is started as serve or watch, the inlined JS code will contain additional HMR code. Don't worry it is ok, so works Webpack live reload.

To enable source map in inline JS set the Webpack option devtool.

How to inline SVG, PNG images in HTML

You can inline images in two ways:

  • force inline image using ?inline query
  • auto inline by image size

Add to Webpack config the rule:

module: {
  rules: [
    {
      test: /\.(png|jpe?g|svg|webp|ico)$/i,
      oneOf: [
        // inline image using `?inline` query
        {
          resourceQuery: /inline/,
          type: 'asset/inline',
        },
        // auto inline by image size
        {
          type: 'asset',
          parser: {
            dataUrlCondition: {
              maxSize: 1024,
            },
          },
          generator: {
            filename: 'assets/img/[name].[hash:8][ext]',
          },
        },
      ],
    },
  ],
}

How to use a template engine

For example, using the Handlebars templating engine, there is an index.hbs

<html>
<head>
  <title>{{title}}</title>
</head>
<body>
  <h1>{{headline}}</h1>
  <div>
    <p>{{firstname}} {{lastname}}</p>
  </div>
</body>
</html>

Add the preprocessor option to compile the content with Handlebars.

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
const Handlebars = require('handlebars');

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
  },

  entry: {
    index: './src/views/home/index.hbs',
  },

  plugins: [
    new HtmlBundlerPlugin({
      test: /\.(html|hbs)$/, // add the option to match *.hbs files in entry, default is /\.html$/
    }),
  ],

  module: {
    rules: [
      {
        test: /\.(html|hbs)$/, // must match the files specified in the entry
        loader: HtmlBundlerPlugin.loader,
        options: {
          // add the preprocessor function to compile *.hbs files to HTML
          // you can pass data here to all templates
          preprocessor: (content, loaderContext) =>
            Handlebars.compile(content)({
              title: 'My Title',
              headline: 'Breaking Bad',
              firstname: 'Walter',
              lastname: 'Heisenberg',
            }),
        },
      },
    ],
  },
};

How to pass data into template

You can pass variables into template using a lightweight template engine, e.g. Handlebars. See the usage example by How to use a template engine or How to pass different data by multipage configuration.

How to pass different data by multipage configuration

For multipage configuration, better to use the Nunjucks templating engine maintained by Mozilla.

For example, you have several pages with variables.
Both pages have the same layout src/views/layouts/default.html

<!DOCTYPE html>
<html>
<head>
  <title>{{title}}</title>
  <!-- block for specific page styles -->
  {% block styles %}{% endblock %}
  <!-- block for specific page scripts -->
  {% block scripts %}{% endblock %}
</head>
<body>
  <main class="main-content">
    <!-- block for specific page content -->
    {% block content %}{% endblock %}
  </main>
</body>
</html>

src/views/pages/home/index.html

{% extends "src/views/layouts/default.html" %}

{% block styles %}
  <link href="./home.scss" rel="stylesheet">
{% endblock %}

{% block scripts %}
  <script src="./home.js" defer="defer"></script>
{% endblock %}

{% block content %}
  <h1>{{ filmTitle }}</h1>
  <p>Location: {{ location }}</p>
  <!-- @images is the Webpack alias for the source images directory -->
  <img src="@images/{{ imageFile }}">
{% endblock %}

src/views/pages/about/index.html

{% extends "src/views/layouts/default.html" %}

{% block styles %}
  <link href="./about.scss" rel="stylesheet">
{% endblock %}

{% block scripts %}
  <script src="./about.js" defer="defer"></script>
{% endblock %}

{% block content %}
  <h1>Main characters</h1>
  <ul>
  {% for item in actors %}
    <li class="name">{{ item.firstname }} {{ item.lastname }}</li>
  {% endfor %}
  </ul>
{% endblock %}

Webpack config

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
const Nunjucks = require('nunjucks');

/**
 * Find template data by template file.
 *
 * @param {string} sourceFile
 * @param {Object} data
 * @return {Object}
 */
const findData = (sourceFile, data) => {
  for (const [key, value] of Object.entries(data)) {
    if (sourceFile.endsWith(key)) return value;
  }
  return {};
};

// note: data keys are different endings of source template files defined in entry
const entryData = {
  'home/index.html': {
    title: 'Home',
    filmTitle: 'Breaking Bad',
    location: 'Albuquerque, New Mexico',
    imageFile: 'map.png',
  },
  'about/index.html': {
    title: 'About',
    actors: [
      {
        firstname: 'Walter',
        lastname: 'White, "Heisenberg"',
      },
      {
        firstname: 'Jesse',
        lastname: 'Pinkman',
      },
    ],
  },
};

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
  },
  entry: {
    // define your templates here
    index: 'src/views/pages/home/index.html', // => dist/index.html
    about: 'src/views/pages/about/index.html', // => dist/about.html
  },
  resolve: {
    alias: {
      '@images': path.join(__dirname, 'src/assets/images'),
    },
  },
  plugins: [
    new HtmlBundlerPlugin({
      js: {
        filename: 'assets/js/[name].[contenthash:8].js',
      },
      css: {
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],
  module: {
    rules: [
      // templates
      {
        test: /\.html/,
        loader: HtmlBundlerPlugin.loader, //  HTML template loader
        options: {
          // the deconstucted 'resource' argument is the template file
          preprocessor: (content, { resource }) => {
            // get template variables by template filename
            const data = findData(resource, entryData);
            // render template with specific variables
            return Nunjucks.renderString(content, data);
          },
        },
      },
      // styles
      {
        test: /\.(css|sass|scss)$/,
        use: ['css-loader', 'sass-loader'],
      },
      // images
      {
        test: /\.(png|svg|jpe?g|webp)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'assets/img/[name].[hash:8][ext]',
        },
      },
    ],
  },
};

The generated dist/index.html

<!DOCTYPE html>
<html>
<head>
  <title>Home</title>
  <link href="assets/css/home.2180238c.css" rel="stylesheet">
  <script src="assets/js/home.790d746b.js" defer="defer"></script>
</head>
<body>
  <main class="main-content">
    <h1>Breaking Bad</h1>
    <p>Breaking Bad is an American crime drama</p>
    <p>Location: Albuquerque, New Mexico</p>
    <img src="assets/img/map.697ef306.png" alt="location" />
  </main>
</body>
</html>

The generated dist/about.html

<!DOCTYPE html>
<html>
<head>
  <title>About</title>
  <link href="assets/css/about.2777c101.css" rel="stylesheet">
  <script src="assets/js/about.1.c5e03c0e.js" defer="defer"></script>
</head>
<body>
  <main class="main-content">
    <h1>Main characters</h1>
    <ul>
      <li class="name">Walter White, &quot;Heisenberg&quot;</li>
      <li class="name">Jesse Pinkman</li>
    </ul>
  </main>
</body>
</html>

HMR live reload

To enable live reload by changes any file add in the Webpack config the devServer option:

module.exports = {
  // enable HMR with live reload
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    watchFiles: {
      paths: ['src/**/*.*'],
      options: {
        usePolling: true,
      },
    },
  },
};

Note

Live reload works only if in HTML used a JS file. This is specific of Webpack. If your HTML has not a JS, then create one empty JS file, e.g. hmr.js and add it in the HTML:

<script src="./hmr.js"></script>

Also See

  • ansis - The Node.js lib for ANSI color styling of text in terminal
  • pug-loader The Pug loader for Webpack
  • pug-plugin The Pug plugin for Webpack

License

ISC

Keywords

FAQs

Package last updated on 28 Jan 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc