[79a0317] | 1 | [![npm][npm]][npm-url]
|
---|
| 2 | [![node][node]][node-url]
|
---|
| 3 | ![npm](https://img.shields.io/npm/dw/html-webpack-plugin.svg)
|
---|
| 4 | [![tests][tests]][tests-url]
|
---|
| 5 | [![Backers on Open Collective](https://opencollective.com/html-webpack-plugin/backers/badge.svg)](#backers)
|
---|
| 6 | [![Sponsors on Open Collective](https://opencollective.com/html-webpack-plugin/sponsors/badge.svg)](#sponsors)
|
---|
| 7 |
|
---|
| 8 | <div align="center">
|
---|
| 9 | <img width="200" height="200" src="https://www.w3.org/html/logo/downloads/HTML5_Badge.svg">
|
---|
| 10 | <a href="https://github.com/webpack/webpack">
|
---|
| 11 | <img width="200" height="200"
|
---|
| 12 | src="https://webpack.js.org/assets/icon-square-big.svg">
|
---|
| 13 | </a>
|
---|
| 14 | <div>
|
---|
| 15 | <img width="100" height="100" title="Webpack Plugin" src="http://michael-ciniawsky.github.io/postcss-load-plugins/logo.svg">
|
---|
| 16 | </div>
|
---|
| 17 | <h1>HTML Webpack Plugin</h1>
|
---|
| 18 | <p>Plugin that simplifies creation of HTML files to serve your bundles</p>
|
---|
| 19 | </div>
|
---|
| 20 |
|
---|
| 21 | <h2 align="center">Install</h2>
|
---|
| 22 |
|
---|
| 23 | <h3>Webpack 5</h3>
|
---|
| 24 |
|
---|
| 25 | ```bash
|
---|
| 26 | npm i --save-dev html-webpack-plugin
|
---|
| 27 | ```
|
---|
| 28 |
|
---|
| 29 | ```bash
|
---|
| 30 | yarn add --dev html-webpack-plugin
|
---|
| 31 | ```
|
---|
| 32 |
|
---|
| 33 | <h3>Webpack 4</h3>
|
---|
| 34 |
|
---|
| 35 | ```bash
|
---|
| 36 | npm i --save-dev html-webpack-plugin@4
|
---|
| 37 | ```
|
---|
| 38 |
|
---|
| 39 | ```bash
|
---|
| 40 | yarn add --dev html-webpack-plugin@4
|
---|
| 41 | ```
|
---|
| 42 |
|
---|
| 43 | This is a [webpack](http://webpack.js.org/) plugin that simplifies creation of HTML files to serve your `webpack` bundles. This is especially useful for `webpack` bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply
|
---|
| 44 | your own template using `lodash` templates or use your own loader.
|
---|
| 45 |
|
---|
| 46 | <h2 align="center">Sponsors</h2>
|
---|
| 47 |
|
---|
| 48 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/0/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/0/avatar.svg"></a>
|
---|
| 49 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/1/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/1/avatar.svg"></a>
|
---|
| 50 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/2/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/2/avatar.svg"></a>
|
---|
| 51 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/3/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/3/avatar.svg"></a>
|
---|
| 52 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/4/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/4/avatar.svg"></a>
|
---|
| 53 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/5/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/5/avatar.svg"></a>
|
---|
| 54 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/6/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/6/avatar.svg"></a>
|
---|
| 55 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/7/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/7/avatar.svg"></a>
|
---|
| 56 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/8/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/8/avatar.svg"></a>
|
---|
| 57 | <a href="https://opencollective.com/html-webpack-plugin/sponsor/9/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/9/avatar.svg"></a>
|
---|
| 58 |
|
---|
| 59 | Thanks for supporting the ongoing improvements to the html-webpack-plugin!
|
---|
| 60 |
|
---|
| 61 | <h2 align="center">Zero Config</h2>
|
---|
| 62 |
|
---|
| 63 | The `html-webpack-plugin` works without configuration.
|
---|
| 64 | It's a great addition to the [⚙️ webpack-config-plugins](https://github.com/namics/webpack-config-plugins/blob/master/README.md#zero-config-webpack-dev-server-example).
|
---|
| 65 |
|
---|
| 66 | <h2 align="center">Plugins</h2>
|
---|
| 67 |
|
---|
| 68 | The `html-webpack-plugin` provides [hooks](https://github.com/jantimon/html-webpack-plugin#events) to extend it to your needs. There are already some really powerful plugins which can be integrated with zero configuration
|
---|
| 69 |
|
---|
| 70 | - [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity) for enhanced asset security
|
---|
| 71 | - [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) for iOS and Android offline usage
|
---|
| 72 | - [favicons-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) which generates favicons and icons for iOS, Android and desktop browsers
|
---|
| 73 | - [html-webpack-harddisk-plugin](https://github.com/jantimon/html-webpack-harddisk-plugin) can be used to always write to disk the html file, useful when webpack-dev-server / HMR are being used
|
---|
| 74 | - [html-webpack-inline-svg-plugin](https://github.com/thegc/html-webpack-inline-svg-plugin) to inline SVGs in the resulting HTML file.
|
---|
| 75 | - [html-webpack-exclude-assets-plugin](https://github.com/jamesjieye/html-webpack-exclude-assets-plugin) for excluding assets using regular expressions
|
---|
| 76 | - [html-webpack-include-assets-plugin](https://github.com/jharris4/html-webpack-include-assets-plugin) for including lists of js or css file paths (such as those copied by the copy-webpack-plugin).
|
---|
| 77 | - [html-webpack-injector](https://github.com/thearchitgarg/html-webpack-injector) to inject chunks in `head` or `body` (different locations ) of same html document.
|
---|
| 78 | - [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin) to add resource hints for faster initial page loads using `<link rel='preload'>` and `<link rel='prefetch'>`
|
---|
| 79 | - [link-media-html-webpack-plugin](https://github.com/yaycmyk/link-media-html-webpack-plugin) allows for injected stylesheet `<link />` tags to have their media attribute set automatically; useful for providing specific desktop/mobile/print etc. stylesheets that the browser will conditionally download
|
---|
| 80 | - [html-webpack-inline-style-plugin](https://github.com/djaax/html-webpack-inline-style-plugin) for inlining styles to HTML elements using [juice](https://github.com/Automattic/juice). Useful for email generation automatisation.
|
---|
| 81 | - [html-webpack-exclude-empty-assets-plugin](https://github.com/KnisterPeter/html-webpack-exclude-empty-assets-plugin) removes empty assets from being added to the html. This fixes some problems with extract-text-plugin with webpack 4.
|
---|
| 82 | - [webpack-concat-plugin](https://github.com/hxlniada/webpack-concat-plugin) for concat and uglify files that needn't to be webpack bundles(for legacy files) and inject to html-webpack-plugin.
|
---|
| 83 | - [html-webpack-link-type-plugin](https://github.com/steadyapp/html-webpack-link-type-plugin) adds a configurable mimetype to resources injected as links (such as adding type="text/css" to external stylesheets) for compatibility with "strict mode".
|
---|
| 84 | - [csp-html-webpack-plugin](https://github.com/slackhq/csp-html-webpack-plugin) to add [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) meta tags to the HTML output
|
---|
| 85 | - [strict-csp-html-webpack-plugin](https://github.com/google/strict-csp/tree/main/strict-csp-html-webpack-plugin) to add a [**strict** Content-Security-Policy (CSP)](https://web.dev) as a `meta` tag to the HTML output. A strict CSP is specifically efficient against XSS attacks.
|
---|
| 86 | - [webpack-nomodule-plugin](https://github.com/swimmadude66/webpack-nomodule-plugin) allows you to add a `nomodule` attribute to specific injected scripts, which prevents the scripts from being loaded by newer browsers. Good for limiting loads of polyfills.
|
---|
| 87 | - [html-webpack-skip-assets-plugin](https://github.com/swimmadude66/html-webpack-skip-assets-plugin) Skip adding certain output files to the html file. Built as a drop-in replacement for [html-webpack-exclude-assets-plugin](https://www.npmjs.com/package/html-webpack-exclude-assets-plugin) and works with newer [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) versions
|
---|
| 88 | - [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) allows to add preload links <link rel='preload'> anywhere you want.
|
---|
| 89 | - [inject-body-webpack-plugin](https://github.com/Jaid/inject-body-webpack-plugin) is a simple method of injecting a custom HTML string into the body.
|
---|
| 90 | - [html-webpack-plugin-django](https://github.com/TommasoAmici/html-webpack-plugin-django) a Webpack plugin to inject Django static tags.
|
---|
| 91 | - [html-webpack-inject-attributes-plugin](https://github.com/dyw934854565/html-webpack-inject-attributes-plugin) add extra attributes to inject assetTags.
|
---|
| 92 | - [js-entry-webpack-plugin](https://github.com/liam61/html-webpack-plugin) creates webpack bundles into your js entry
|
---|
| 93 |
|
---|
| 94 | <h2 align="center">Usage</h2>
|
---|
| 95 |
|
---|
| 96 | The plugin will generate an HTML5 file for you that includes all your `webpack`
|
---|
| 97 | bundles in the head using `script` tags. Just add the plugin to your `webpack`
|
---|
| 98 | config as follows:
|
---|
| 99 |
|
---|
| 100 | **webpack.config.js**
|
---|
| 101 |
|
---|
| 102 | ```js
|
---|
| 103 | const HtmlWebpackPlugin = require("html-webpack-plugin");
|
---|
| 104 |
|
---|
| 105 | module.exports = {
|
---|
| 106 | entry: "index.js",
|
---|
| 107 | output: {
|
---|
| 108 | path: __dirname + "/dist",
|
---|
| 109 | filename: "index_bundle.js",
|
---|
| 110 | },
|
---|
| 111 | plugins: [new HtmlWebpackPlugin()],
|
---|
| 112 | };
|
---|
| 113 | ```
|
---|
| 114 |
|
---|
| 115 | This will generate a file `dist/index.html` containing the following
|
---|
| 116 |
|
---|
| 117 | ```html
|
---|
| 118 | <!doctype html>
|
---|
| 119 | <html>
|
---|
| 120 | <head>
|
---|
| 121 | <meta charset="utf-8" />
|
---|
| 122 | <title>Webpack App</title>
|
---|
| 123 | <script defer src="index_bundle.js"></script>
|
---|
| 124 | </head>
|
---|
| 125 | <body></body>
|
---|
| 126 | </html>
|
---|
| 127 | ```
|
---|
| 128 |
|
---|
| 129 | If you have multiple `webpack` entry points, they will all be included with `script` tags in the generated HTML.
|
---|
| 130 |
|
---|
| 131 | If you have any CSS assets in webpack's output (for example, CSS extracted with the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin))
|
---|
| 132 | then these will be included with `<link>` tags in the HTML head.
|
---|
| 133 |
|
---|
| 134 | If you have plugins that make use of it, `html-webpack-plugin` should be ordered first before any of the integrated Plugins.
|
---|
| 135 |
|
---|
| 136 | <h2 align="center">Options</h2>
|
---|
| 137 |
|
---|
| 138 | You can pass a hash of configuration options to `html-webpack-plugin`.
|
---|
| 139 | Allowed values are as follows:
|
---|
| 140 |
|
---|
| 141 | | Name | Type | Default | Description |
|
---|
| 142 | | :----------------------: | :--------------------------------------------------: | :---------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
---|
| 143 | | **`title`** | `{String}` | `Webpack App` | The title to use for the generated HTML document |
|
---|
| 144 | | **`filename`** | `{String\|Function}` | `'index.html'` | The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`). The `[name]` placeholder will be replaced with the entry name. Can also be a function e.g. `(entryName) => entryName + '.html'`. |
|
---|
| 145 | | **`template`** | `{String}` | `` | `webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details |
|
---|
| 146 | | **`templateContent`** | `{string\|Function\|false}` | false | Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section |
|
---|
| 147 | | **`templateParameters`** | `{Boolean\|Object\|Function}` | `false` | Allows to overwrite the parameters used in the template - see [example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters) |
|
---|
| 148 | | **`inject`** | `{Boolean\|String}` | `true` | `true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element. Passing `true` will add it to the head/body depending on the `scriptLoading` option. Passing `false` will disable automatic injections. - see the [inject:false example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position) |
|
---|
| 149 | | **`publicPath`** | `{String\|'auto'}` | `'auto'` | The publicPath used for script and link tags |
|
---|
| 150 | | **`scriptLoading`** | `{'blocking'\|'defer'\|'module'\|'systemjs-module'}` | `'defer'` | Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. Setting to `'module'` adds attribute [`type="module"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html). This also implies "defer", since modules are automatically deferred. |
|
---|
| 151 | | **`favicon`** | `{String}` | `` | Adds the given favicon path to the output HTML |
|
---|
| 152 | | **`meta`** | `{Object}` | `{}` | Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}` |
|
---|
| 153 | | **`base`** | `{Object\|String\|false}` | `false` | Inject a [`base`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag. E.g. `base: "https://example.com/path/page.html` |
|
---|
| 154 | | **`minify`** | `{Boolean\|Object}` | `true` if `mode` is `'production'`, otherwise `false` | Controls if and in what ways the output should be minified. See [minification](#minification) below for more details. |
|
---|
| 155 | | **`hash`** | `{Boolean}` | `false` | If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files (i.e. `main.js?hash=compilation_hash`). This is useful for cache busting |
|
---|
| 156 | | **`cache`** | `{Boolean}` | `true` | Emit the file only if it was changed |
|
---|
| 157 | | **`showErrors`** | `{Boolean}` | `true` | Errors details will be written into the HTML page |
|
---|
| 158 | | **`chunks`** | `{?}` | `?` | Allows you to add only some chunks (e.g only the unit-test chunk) |
|
---|
| 159 | | **`chunksSortMode`** | `{String\|Function}` | `auto` | Allows to control how chunks should be sorted before they are included to the HTML. Allowed values are `'none' \| 'auto' \| 'manual' \| {Function}` |
|
---|
| 160 | | **`excludeChunks`** | `{Array.<string>}` | `` | Allows you to skip some chunks (e.g don't add the unit-test chunk) |
|
---|
| 161 | | **`xhtml`** | `{Boolean}` | `false` | If `true` render the `link` tags as self-closing (XHTML compliant) |
|
---|
| 162 |
|
---|
| 163 | Here's an example webpack config illustrating how to use these options
|
---|
| 164 |
|
---|
| 165 | **webpack.config.js**
|
---|
| 166 |
|
---|
| 167 | ```js
|
---|
| 168 | {
|
---|
| 169 | entry: 'index.js',
|
---|
| 170 | output: {
|
---|
| 171 | path: __dirname + '/dist',
|
---|
| 172 | filename: 'index_bundle.js'
|
---|
| 173 | },
|
---|
| 174 | plugins: [
|
---|
| 175 | new HtmlWebpackPlugin({
|
---|
| 176 | title: 'My App',
|
---|
| 177 | filename: 'assets/admin.html'
|
---|
| 178 | })
|
---|
| 179 | ]
|
---|
| 180 | }
|
---|
| 181 | ```
|
---|
| 182 |
|
---|
| 183 | ### Generating Multiple HTML Files
|
---|
| 184 |
|
---|
| 185 | To generate more than one HTML file, declare the plugin more than
|
---|
| 186 | once in your plugins array
|
---|
| 187 |
|
---|
| 188 | **webpack.config.js**
|
---|
| 189 |
|
---|
| 190 | ```js
|
---|
| 191 | {
|
---|
| 192 | entry: 'index.js',
|
---|
| 193 | output: {
|
---|
| 194 | path: __dirname + '/dist',
|
---|
| 195 | filename: 'index_bundle.js'
|
---|
| 196 | },
|
---|
| 197 | plugins: [
|
---|
| 198 | new HtmlWebpackPlugin(), // Generates default index.html
|
---|
| 199 | new HtmlWebpackPlugin({ // Also generate a test.html
|
---|
| 200 | filename: 'test.html',
|
---|
| 201 | template: 'src/assets/test.html'
|
---|
| 202 | })
|
---|
| 203 | ]
|
---|
| 204 | }
|
---|
| 205 | ```
|
---|
| 206 |
|
---|
| 207 | ### Writing Your Own Templates
|
---|
| 208 |
|
---|
| 209 | If the default generated HTML doesn't meet your needs you can supply
|
---|
| 210 | your own template. The easiest way is to use the `template` option and pass a custom HTML file.
|
---|
| 211 | The html-webpack-plugin will automatically inject all necessary CSS, JS, manifest
|
---|
| 212 | and favicon files into the markup.
|
---|
| 213 |
|
---|
| 214 | Details of other template loaders are [documented here](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md).
|
---|
| 215 |
|
---|
| 216 | ```js
|
---|
| 217 | plugins: [
|
---|
| 218 | new HtmlWebpackPlugin({
|
---|
| 219 | title: "Custom template",
|
---|
| 220 | // Load a custom template (lodash by default)
|
---|
| 221 | template: "index.html",
|
---|
| 222 | }),
|
---|
| 223 | ];
|
---|
| 224 | ```
|
---|
| 225 |
|
---|
| 226 | **index.html**
|
---|
| 227 |
|
---|
| 228 | ```html
|
---|
| 229 | <!doctype html>
|
---|
| 230 | <html>
|
---|
| 231 | <head>
|
---|
| 232 | <meta charset="utf-8" />
|
---|
| 233 | <title><%= htmlWebpackPlugin.options.title %></title>
|
---|
| 234 | </head>
|
---|
| 235 | <body></body>
|
---|
| 236 | </html>
|
---|
| 237 | ```
|
---|
| 238 |
|
---|
| 239 | If you already have a template loader, you can use it to parse the template.
|
---|
| 240 | Please note that this will also happen if you specify the html-loader and use `.html` file as template.
|
---|
| 241 |
|
---|
| 242 | **webpack.config.js**
|
---|
| 243 |
|
---|
| 244 | ```js
|
---|
| 245 | module: {
|
---|
| 246 | loaders: [
|
---|
| 247 | { test: /\.hbs$/, loader: "handlebars-loader" }
|
---|
| 248 | ]
|
---|
| 249 | },
|
---|
| 250 | plugins: [
|
---|
| 251 | new HtmlWebpackPlugin({
|
---|
| 252 | title: 'Custom template using Handlebars',
|
---|
| 253 | template: 'index.hbs'
|
---|
| 254 | })
|
---|
| 255 | ]
|
---|
| 256 | ```
|
---|
| 257 |
|
---|
| 258 | You can use the `lodash` syntax out of the box. If the `inject` feature doesn't fit your needs and you want full control over the asset placement use the [default template](https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html) of the [html-webpack-template project](https://github.com/jaketrent/html-webpack-template) as a starting point for writing your own.
|
---|
| 259 |
|
---|
| 260 | The following variables are available in the template by default (you can extend them using the `templateParameters` option):
|
---|
| 261 |
|
---|
| 262 | - `htmlWebpackPlugin`: data specific to this plugin
|
---|
| 263 |
|
---|
| 264 | - `htmlWebpackPlugin.options`: the options hash that was passed to
|
---|
| 265 | the plugin. In addition to the options actually used by this plugin,
|
---|
| 266 | you can use this hash to pass arbitrary data through to your template.
|
---|
| 267 |
|
---|
| 268 | - `htmlWebpackPlugin.tags`: the prepared `headTags` and `bodyTags` Array to render the `<base>`, `<meta>`, `<script>` and `<link>` tags.
|
---|
| 269 | Can be used directly in templates and literals. For example:
|
---|
| 270 | ```html
|
---|
| 271 | <html>
|
---|
| 272 | <head>
|
---|
| 273 | <%= htmlWebpackPlugin.tags.headTags %>
|
---|
| 274 | </head>
|
---|
| 275 | <body>
|
---|
| 276 | <%= htmlWebpackPlugin.tags.bodyTags %>
|
---|
| 277 | </body>
|
---|
| 278 | </html>
|
---|
| 279 | ```
|
---|
| 280 | - `htmlWebpackPlugin.files`: direct access to the files used during the compilation.
|
---|
| 281 |
|
---|
| 282 | ```typescript
|
---|
| 283 | publicPath: string;
|
---|
| 284 | js: string[];
|
---|
| 285 | css: string[];
|
---|
| 286 | manifest?: string;
|
---|
| 287 | favicon?: string;
|
---|
| 288 | ```
|
---|
| 289 |
|
---|
| 290 | - `webpackConfig`: the webpack configuration that was used for this compilation. This
|
---|
| 291 | can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`).
|
---|
| 292 |
|
---|
| 293 | - `compilation`: the webpack [compilation object](https://webpack.js.org/api/compilation-object/).
|
---|
| 294 | This can be used, for example, to get the contents of processed assets and inline them
|
---|
| 295 | directly in the page, through `compilation.assets[...].source()`
|
---|
| 296 | (see [the inline template example](examples/inline/template.pug)).
|
---|
| 297 |
|
---|
| 298 | The template can also be directly inlined directly into the options object.
|
---|
| 299 | ⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
|
---|
| 300 |
|
---|
| 301 | **webpack.config.js**
|
---|
| 302 |
|
---|
| 303 | ```js
|
---|
| 304 | new HtmlWebpackPlugin({
|
---|
| 305 | templateContent: `
|
---|
| 306 | <html>
|
---|
| 307 | <body>
|
---|
| 308 | <h1>Hello World</h1>
|
---|
| 309 | </body>
|
---|
| 310 | </html>
|
---|
| 311 | `,
|
---|
| 312 | });
|
---|
| 313 | ```
|
---|
| 314 |
|
---|
| 315 | The `templateContent` can also access all `templateParameters` values.
|
---|
| 316 | ⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
|
---|
| 317 |
|
---|
| 318 | **webpack.config.js**
|
---|
| 319 |
|
---|
| 320 | ```js
|
---|
| 321 | new HtmlWebpackPlugin({
|
---|
| 322 | inject: false,
|
---|
| 323 | templateContent: ({ htmlWebpackPlugin }) => `
|
---|
| 324 | <html>
|
---|
| 325 | <head>
|
---|
| 326 | ${htmlWebpackPlugin.tags.headTags}
|
---|
| 327 | </head>
|
---|
| 328 | <body>
|
---|
| 329 | <h1>Hello World</h1>
|
---|
| 330 | ${htmlWebpackPlugin.tags.bodyTags}
|
---|
| 331 | </body>
|
---|
| 332 | </html>
|
---|
| 333 | `,
|
---|
| 334 | });
|
---|
| 335 | ```
|
---|
| 336 |
|
---|
| 337 | ### Filtering Chunks
|
---|
| 338 |
|
---|
| 339 | To include only certain chunks you can limit the chunks being used
|
---|
| 340 |
|
---|
| 341 | **webpack.config.js**
|
---|
| 342 |
|
---|
| 343 | ```js
|
---|
| 344 | plugins: [
|
---|
| 345 | new HtmlWebpackPlugin({
|
---|
| 346 | chunks: ["app"],
|
---|
| 347 | }),
|
---|
| 348 | ];
|
---|
| 349 | ```
|
---|
| 350 |
|
---|
| 351 | It is also possible to exclude certain chunks by setting the `excludeChunks` option
|
---|
| 352 |
|
---|
| 353 | **webpack.config.js**
|
---|
| 354 |
|
---|
| 355 | ```js
|
---|
| 356 | plugins: [
|
---|
| 357 | new HtmlWebpackPlugin({
|
---|
| 358 | excludeChunks: ["dev-helper"],
|
---|
| 359 | }),
|
---|
| 360 | ];
|
---|
| 361 | ```
|
---|
| 362 |
|
---|
| 363 | ### Minification
|
---|
| 364 |
|
---|
| 365 | If the `minify` option is set to `true` (the default when webpack's `mode` is `'production'`),
|
---|
| 366 | the generated HTML will be minified using [html-minifier-terser](https://github.com/DanielRuf/html-minifier-terser)
|
---|
| 367 | and the following options:
|
---|
| 368 |
|
---|
| 369 | ```js
|
---|
| 370 | {
|
---|
| 371 | collapseWhitespace: true,
|
---|
| 372 | keepClosingSlash: true,
|
---|
| 373 | removeComments: true,
|
---|
| 374 | removeRedundantAttributes: true,
|
---|
| 375 | removeScriptTypeAttributes: true,
|
---|
| 376 | removeStyleLinkTypeAttributes: true,
|
---|
| 377 | useShortDoctype: true
|
---|
| 378 | }
|
---|
| 379 | ```
|
---|
| 380 |
|
---|
| 381 | To use custom [html-minifier options](https://github.com/DanielRuf/html-minifier-terser#options-quick-reference)
|
---|
| 382 | pass an object to `minify` instead. This object will not be merged with the defaults above.
|
---|
| 383 |
|
---|
| 384 | To disable minification during production mode set the `minify` option to `false`.
|
---|
| 385 |
|
---|
| 386 | ### Meta Tags
|
---|
| 387 |
|
---|
| 388 | If the `meta` option is set the html-webpack-plugin will inject meta tags.
|
---|
| 389 | For the default template the html-webpack-plugin will already provide a default for the `viewport` meta tag.
|
---|
| 390 |
|
---|
| 391 | Please take a look at this well maintained list of almost all [possible meta tags](https://github.com/joshbuchea/HEAD#meta).
|
---|
| 392 |
|
---|
| 393 | #### name/content meta tags
|
---|
| 394 |
|
---|
| 395 | Most meta tags are configured by setting a `name` and a `content` attribute.
|
---|
| 396 | To add those use a key/value pair:
|
---|
| 397 |
|
---|
| 398 | **webpack.config.js**
|
---|
| 399 |
|
---|
| 400 | ```js
|
---|
| 401 | plugins: [
|
---|
| 402 | new HtmlWebpackPlugin({
|
---|
| 403 | meta: {
|
---|
| 404 | viewport: "width=device-width, initial-scale=1, shrink-to-fit=no",
|
---|
| 405 | // Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
---|
| 406 | "theme-color": "#4285f4",
|
---|
| 407 | // Will generate: <meta name="theme-color" content="#4285f4">
|
---|
| 408 | },
|
---|
| 409 | }),
|
---|
| 410 | ];
|
---|
| 411 | ```
|
---|
| 412 |
|
---|
| 413 | #### Simulate http response headers
|
---|
| 414 |
|
---|
| 415 | The **http-equiv** attribute is essentially used to simulate a HTTP response header.
|
---|
| 416 | This format is supported using an object notation which allows you to add any attribute:
|
---|
| 417 |
|
---|
| 418 | **webpack.config.js**
|
---|
| 419 |
|
---|
| 420 | ```js
|
---|
| 421 | plugins: [
|
---|
| 422 | new HtmlWebpackPlugin({
|
---|
| 423 | meta: {
|
---|
| 424 | "Content-Security-Policy": {
|
---|
| 425 | "http-equiv": "Content-Security-Policy",
|
---|
| 426 | content: "default-src https:",
|
---|
| 427 | },
|
---|
| 428 | // Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
|
---|
| 429 | // Which equals to the following http header: `Content-Security-Policy: default-src https:`
|
---|
| 430 | "set-cookie": {
|
---|
| 431 | "http-equiv": "set-cookie",
|
---|
| 432 | content: "name=value; expires=date; path=url",
|
---|
| 433 | },
|
---|
| 434 | // Will generate: <meta http-equiv="set-cookie" content="value; expires=date; path=url">
|
---|
| 435 | // Which equals to the following http header: `set-cookie: value; expires=date; path=url`
|
---|
| 436 | },
|
---|
| 437 | }),
|
---|
| 438 | ];
|
---|
| 439 | ```
|
---|
| 440 |
|
---|
| 441 | ### Base Tag
|
---|
| 442 |
|
---|
| 443 | When the `base` option is used,
|
---|
| 444 | html-webpack-plugin will inject a [base tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base).
|
---|
| 445 | By default, a base tag will not be injected.
|
---|
| 446 |
|
---|
| 447 | The following two are identical and will both insert `<base href="http://example.com/some/page.html">`:
|
---|
| 448 |
|
---|
| 449 | ```js
|
---|
| 450 | new HtmlWebpackPlugin({
|
---|
| 451 | base: "http://example.com/some/page.html",
|
---|
| 452 | });
|
---|
| 453 | ```
|
---|
| 454 |
|
---|
| 455 | ```js
|
---|
| 456 | new HtmlWebpackPlugin({
|
---|
| 457 | base: { href: "http://example.com/some/page.html" },
|
---|
| 458 | });
|
---|
| 459 | ```
|
---|
| 460 |
|
---|
| 461 | The `target` can be specified with the corresponding key:
|
---|
| 462 |
|
---|
| 463 | ```js
|
---|
| 464 | new HtmlWebpackPlugin({
|
---|
| 465 | base: {
|
---|
| 466 | href: "http://example.com/some/page.html",
|
---|
| 467 | target: "_blank",
|
---|
| 468 | },
|
---|
| 469 | });
|
---|
| 470 | ```
|
---|
| 471 |
|
---|
| 472 | which will inject the element `<base href="http://example.com/some/page.html" target="_blank">`.
|
---|
| 473 |
|
---|
| 474 | ### Long Term Caching
|
---|
| 475 |
|
---|
| 476 | For long term caching add `contenthash` to the filename.
|
---|
| 477 |
|
---|
| 478 | **Example:**
|
---|
| 479 |
|
---|
| 480 | ```js
|
---|
| 481 | plugins: [
|
---|
| 482 | new HtmlWebpackPlugin({
|
---|
| 483 | filename: "index.[contenthash].html",
|
---|
| 484 | }),
|
---|
| 485 | ];
|
---|
| 486 | ```
|
---|
| 487 |
|
---|
| 488 | `contenthash` is the hash of the content of the output file.
|
---|
| 489 |
|
---|
| 490 | Refer webpack's [Template Strings](https://webpack.js.org/configuration/output/#template-strings) for more details
|
---|
| 491 |
|
---|
| 492 | ### Events
|
---|
| 493 |
|
---|
| 494 | To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the HTML this plugin executes
|
---|
| 495 | [tapable](https://github.com/webpack/tapable/tree/master) hooks.
|
---|
| 496 |
|
---|
| 497 | The [lib/hooks.js](https://github.com/jantimon/html-webpack-plugin/blob/master/lib/hooks.js) contains all information
|
---|
| 498 | about which values are passed.
|
---|
| 499 |
|
---|
| 500 | [![Concept flow uml](https://raw.githubusercontent.com/jantimon/html-webpack-plugin/master/flow.png)](https://github.com/jantimon/html-webpack-plugin/blob/master/flow.puml)
|
---|
| 501 |
|
---|
| 502 | #### `beforeAssetTagGeneration` hook
|
---|
| 503 |
|
---|
| 504 | ```
|
---|
| 505 | AsyncSeriesWaterfallHook<{
|
---|
| 506 | assets: {
|
---|
| 507 | publicPath: string,
|
---|
| 508 | js: Array<{string}>,
|
---|
| 509 | css: Array<{string}>,
|
---|
| 510 | favicon?: string | undefined,
|
---|
| 511 | manifest?: string | undefined
|
---|
| 512 | },
|
---|
| 513 | outputName: string,
|
---|
| 514 | plugin: HtmlWebpackPlugin
|
---|
| 515 | }>
|
---|
| 516 | ```
|
---|
| 517 |
|
---|
| 518 | #### `alterAssetTags` hook
|
---|
| 519 |
|
---|
| 520 | ```
|
---|
| 521 | AsyncSeriesWaterfallHook<{
|
---|
| 522 | assetTags: {
|
---|
| 523 | scripts: Array<HtmlTagObject>,
|
---|
| 524 | styles: Array<HtmlTagObject>,
|
---|
| 525 | meta: Array<HtmlTagObject>,
|
---|
| 526 | },
|
---|
| 527 | publicPath: string,
|
---|
| 528 | outputName: string,
|
---|
| 529 | plugin: HtmlWebpackPlugin
|
---|
| 530 | }>
|
---|
| 531 | ```
|
---|
| 532 |
|
---|
| 533 | #### `alterAssetTagGroups` hook
|
---|
| 534 |
|
---|
| 535 | ```
|
---|
| 536 | AsyncSeriesWaterfallHook<{
|
---|
| 537 | headTags: Array<HtmlTagObject | HtmlTagObject>,
|
---|
| 538 | bodyTags: Array<HtmlTagObject | HtmlTagObject>,
|
---|
| 539 | publicPath: string,
|
---|
| 540 | outputName: string,
|
---|
| 541 | plugin: HtmlWebpackPlugin
|
---|
| 542 | }>
|
---|
| 543 | ```
|
---|
| 544 |
|
---|
| 545 | #### `afterTemplateExecution` hook
|
---|
| 546 |
|
---|
| 547 | ```
|
---|
| 548 | AsyncSeriesWaterfallHook<{
|
---|
| 549 | html: string,
|
---|
| 550 | headTags: Array<HtmlTagObject | HtmlTagObject>,
|
---|
| 551 | bodyTags: Array<HtmlTagObject | HtmlTagObject>,
|
---|
| 552 | outputName: string,
|
---|
| 553 | plugin: HtmlWebpackPlugin,
|
---|
| 554 | }>
|
---|
| 555 | ```
|
---|
| 556 |
|
---|
| 557 | #### `beforeEmit` hook
|
---|
| 558 |
|
---|
| 559 | ```
|
---|
| 560 | AsyncSeriesWaterfallHook<{
|
---|
| 561 | html: string,
|
---|
| 562 | outputName: string,
|
---|
| 563 | plugin: HtmlWebpackPlugin,
|
---|
| 564 | }>
|
---|
| 565 | ```
|
---|
| 566 |
|
---|
| 567 | #### `afterEmit` hook
|
---|
| 568 |
|
---|
| 569 | ```
|
---|
| 570 | AsyncSeriesWaterfallHook<{
|
---|
| 571 | outputName: string,
|
---|
| 572 | plugin: HtmlWebpackPlugin
|
---|
| 573 | }>
|
---|
| 574 | ```
|
---|
| 575 |
|
---|
| 576 | Example implementation: [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity)
|
---|
| 577 |
|
---|
| 578 | **plugin.js**
|
---|
| 579 |
|
---|
| 580 | ```js
|
---|
| 581 | // If your plugin is direct dependent to the html webpack plugin:
|
---|
| 582 | const HtmlWebpackPlugin = require("html-webpack-plugin");
|
---|
| 583 | // If your plugin is using html-webpack-plugin as an optional dependency
|
---|
| 584 | // you can use https://github.com/tallesl/node-safe-require instead:
|
---|
| 585 | const HtmlWebpackPlugin = require("safe-require")("html-webpack-plugin");
|
---|
| 586 |
|
---|
| 587 | class MyPlugin {
|
---|
| 588 | apply(compiler) {
|
---|
| 589 | compiler.hooks.compilation.tap("MyPlugin", (compilation) => {
|
---|
| 590 | console.log("The compiler is starting a new compilation...");
|
---|
| 591 |
|
---|
| 592 | // Static Plugin interface |compilation |HOOK NAME | register listener
|
---|
| 593 | HtmlWebpackPlugin.getCompilationHooks(compilation).beforeEmit.tapAsync(
|
---|
| 594 | "MyPlugin", // <-- Set a meaningful name here for stacktraces
|
---|
| 595 | (data, cb) => {
|
---|
| 596 | // Manipulate the content
|
---|
| 597 | data.html += "The Magic Footer";
|
---|
| 598 | // Tell webpack to move on
|
---|
| 599 | cb(null, data);
|
---|
| 600 | },
|
---|
| 601 | );
|
---|
| 602 | });
|
---|
| 603 | }
|
---|
| 604 | }
|
---|
| 605 |
|
---|
| 606 | module.exports = MyPlugin;
|
---|
| 607 | ```
|
---|
| 608 |
|
---|
| 609 | **webpack.config.js**
|
---|
| 610 |
|
---|
| 611 | ```js
|
---|
| 612 | plugins: [new MyPlugin({ options: "" })];
|
---|
| 613 | ```
|
---|
| 614 |
|
---|
| 615 | Note that the callback must be passed the HtmlWebpackPluginData in order to pass this onto any other plugins listening on the same `beforeEmit` event
|
---|
| 616 |
|
---|
| 617 | <h2 align="center">Maintainers</h2>
|
---|
| 618 |
|
---|
| 619 | <table>
|
---|
| 620 | <tbody>
|
---|
| 621 | <tr>
|
---|
| 622 | <td align="center">
|
---|
| 623 | <img width="150" height="150"
|
---|
| 624 | src="https://avatars3.githubusercontent.com/u/4113649?v=3&s=150">
|
---|
| 625 | </br>
|
---|
| 626 | <a href="https://github.com/jantimon">Jan Nicklas</a>
|
---|
| 627 | </td>
|
---|
| 628 | <td align="center">
|
---|
| 629 | <img width="150" height="150"
|
---|
| 630 | src="https://avatars2.githubusercontent.com/u/4112409?v=3&s=150">
|
---|
| 631 | </br>
|
---|
| 632 | <a href="https://github.com/mastilver">Thomas Sileghem</a>
|
---|
| 633 | </td>
|
---|
| 634 | </tr>
|
---|
| 635 | <tbody>
|
---|
| 636 | </table>
|
---|
| 637 |
|
---|
| 638 | ## Backers
|
---|
| 639 |
|
---|
| 640 | Thank you to all our backers!
|
---|
| 641 | If you want to support the project as well [become a sponsor](https://opencollective.com/html-webpack-plugin#sponsor) or a [a backer](https://opencollective.com/html-webpack-plugin#backer).
|
---|
| 642 |
|
---|
| 643 | <a href="https://opencollective.com/html-webpack-plugin/backer/0/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/0/avatar.svg?requireActive=false"></a>
|
---|
| 644 | <a href="https://opencollective.com/html-webpack-plugin/backer/1/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/1/avatar.svg?requireActive=false"></a>
|
---|
| 645 | <a href="https://opencollective.com/html-webpack-plugin/backer/2/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/2/avatar.svg?requireActive=false"></a>
|
---|
| 646 | <a href="https://opencollective.com/html-webpack-plugin/backer/3/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/3/avatar.svg?requireActive=false"></a>
|
---|
| 647 | <a href="https://opencollective.com/html-webpack-plugin/backer/4/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/4/avatar.svg?requireActive=false"></a>
|
---|
| 648 | <a href="https://opencollective.com/html-webpack-plugin/backer/5/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/5/avatar.svg?requireActive=false"></a>
|
---|
| 649 | <a href="https://opencollective.com/html-webpack-plugin/backer/6/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/6/avatar.svg?requireActive=false"></a>
|
---|
| 650 | <a href="https://opencollective.com/html-webpack-plugin/backer/7/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/7/avatar.svg?requireActive=false"></a>
|
---|
| 651 | <a href="https://opencollective.com/html-webpack-plugin/backer/8/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/8/avatar.svg?requireActive=false"></a>
|
---|
| 652 | <a href="https://opencollective.com/html-webpack-plugin/backer/9/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/9/avatar.svg?requireActive=false"></a>
|
---|
| 653 |
|
---|
| 654 | ## Contributors
|
---|
| 655 |
|
---|
| 656 | This project exists thanks to all the people who contribute.
|
---|
| 657 |
|
---|
| 658 | You're free to contribute to this project by submitting [issues](https://github.com/jantimon/html-webpack-plugin/issues) and/or [pull requests](https://github.com/jantimon/html-webpack-plugin/pulls). This project is test-driven, so keep in mind that every change and new feature should be covered by tests.
|
---|
| 659 |
|
---|
| 660 | <a href="https://github.com/jantimon/html-webpack-plugin/graphs/contributors"><img src="https://opencollective.com/html-webpack-plugin/contributors.svg?width=890&button=false" /></a>
|
---|
| 661 |
|
---|
| 662 | [npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg
|
---|
| 663 | [npm-url]: https://npmjs.com/package/html-webpack-plugin
|
---|
| 664 | [node]: https://img.shields.io/node/v/html-webpack-plugin.svg
|
---|
| 665 | [node-url]: https://nodejs.org
|
---|
| 666 | [tests]: https://github.com/jantimon/html-webpack-plugin/workflows/CI/badge.svg
|
---|
| 667 | [tests-url]: https://github.com/jantimon/html-webpack-plugin/actions?query=workflow%3ACI
|
---|