
This is a modern plugin that does exactly what you want, automatically extracts JS, CSS, images, fonts
from their sources loaded directly in HTML using tags
and replaces the source filenames with output hashed version of the files.
The plugin enable to use an HTML file as entry-point in Webpack.
How to easily build a multipage website with this plugin, see the Webpack boilerplate used the html-bundler-webpack-plugin
;
Note
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.
This plugin works like the pug-plugin but the entry point is a HTML
file.
š” Highlights:
- Define your HTML pages in Webpack entry.
- The HTML file is the entry-point for all source scripts and styles.
- Source scripts and styles should be loaded directly in HTML using tags.
- All JS and CSS files will be extracted from their sources specified in HTML tags.
Simple usage example
Add the HTML files in the Webpack entry:
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
entry: {
index: './src/views/home/index.html',
},
plugins: [
new HtmlBundlerPlugin(),
],
module: {
rules: [
{
test: /.html/,
loader: HtmlBundlerPlugin.loader,
},
],
},
};
Add source scripts and styles directly to HTML using a relative path or Webpack alias:
<html>
<head>
<link href="./style.scss" rel="stylesheet">
<script src="./main.js" defer="defer"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
The generated HTML contains hashed output CSS and JS filenames:
<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>
</body>
</html>
Contents
- Install and Quick start
- Features
- Plugin options
- Recipes
Features
Just one HTML bundler plugin replaces the functionality of the plugins and loaders:
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: {
index: './src/views/home/index.html',
'pages/about': './src/views/about/index.html',
},
plugins: [
new HtmlBundlerPlugin({
js: {
filename: 'assets/js/[name].[contenthash:8].js',
},
css: {
filename: 'assets/css/[name].[contenthash:8].css',
},
}),
],
module: {
rules: [
{
test: /\.html$/,
loader: HtmlBundlerPlugin.loader,
},
{
test: /\.(css|sass|scss)$/,
use: ['css-loader', 'sass-loader'],
},
],
},
};
Plugin options
verbose
Type: boolean
Default: false
Display the file information at processing.
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 filepathData.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)$/,
enabled: true,
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.
Note
- the extract
js
module is always enabled - the
test
property not exist because all loaded scripts 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.
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>
<link href="./main.scss" rel="stylesheet" />
<link href="./main.scss?inline" rel="stylesheet" />
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
The generated HTML contains inline CSS already processed via Webpack:
<html>
<head>
<link href="/assets/css/style.05e4dd86.css" rel="stylesheet">
<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: 'source-map'
.
How to inline JS in HTML
For example, the main.js:
console.log('Hello JS!');
Add the ?inline
query to the source filename which you want to inline:
<html>
<head>
<script src="./main.js" defer="defer"></script>
<script src="./main.js?inline"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
The generated HTML contains inline JS already compiled via Webpack:
<html>
<head>
<script src="assets/js/main.992ba657.js" defer="defer"></script>
<script>
(()=>{"use strict";console.log("Hello JS!")})();
</script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
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: [
{
resourceQuery: /inline/,
type: 'asset/inline',
},
{
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1024,
},
},
generator: {
filename: 'assets/img/[name].[hash:8][ext]',
},
},
],
},
],
}
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
Now you don't need a plugin to copy files from source directory to public.
HMR live reload
To enable live reload by changes any file add in the Webpack config the devServer
option:
module.exports = {
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