1 | [![npm][npm]][npm-url]
|
2 | [![node][node]][node-url]
|
3 | [![deps][deps]][deps-url]
|
4 | [![tests][tests]][tests-url]
|
5 | [![coverage][cover]][cover-url]
|
6 | [![chat][chat]][chat-url]
|
7 |
|
8 | <div align="center">
|
9 | <img width="200" height="200" src="https://worldvectorlogo.com/logos/html5.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 |
|
24 | ```bash
|
25 | npm i --save-dev html-webpack-plugin
|
26 | ```
|
27 |
|
28 | ```bash
|
29 | yarn add --dev html-webpack-plugin
|
30 | ```
|
31 |
|
32 |
|
33 |
|
34 | 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
|
35 | your own template using `lodash` templates or use your own loader.
|
36 |
|
37 | ### `Plugins`
|
38 |
|
39 | 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
|
40 |
|
41 | * [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity) for enhanced asset security
|
42 | * [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) for iOS and Android offline usage
|
43 | * [favicons-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) which generates favicons and icons for iOS, Android and desktop browsers
|
44 | * [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
|
45 | * [html-webpack-inline-source-plugin](https://github.com/DustinJackson/html-webpack-inline-source-plugin) to inline your assets in the resulting HTML file
|
46 | * [html-webpack-inline-svg-plugin](https://github.com/thegc/html-webpack-inline-svg-plugin) to inline SVGs in the resulting HTML file.
|
47 | * [html-webpack-exclude-assets-plugin](https://github.com/jamesjieye/html-webpack-exclude-assets-plugin) for excluding assets using regular expressions
|
48 | * [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).
|
49 | * [script-ext-html-webpack-plugin](https://github.com/numical/script-ext-html-webpack-plugin) to add `async`, `defer` or `module` attributes to your `<script>` elements, or even inline them
|
50 | * [style-ext-html-webpack-plugin](https://github.com/numical/style-ext-html-webpack-plugin) to convert your `<link>`s to external stylesheets into `<style>` elements containing internal CSS
|
51 | * [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'>`
|
52 | * [preload-webpack-plugin](https://github.com/GoogleChrome/preload-webpack-plugin) for automatically wiring up asynchronous (and other types) of JavaScript chunks using `<link rel='preload'>` helping with lazy-loading
|
53 | * [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
|
54 | * [inline-chunk-manifest-html-webpack-plugin](https://github.com/jouni-kantola/inline-chunk-manifest-html-webpack-plugin) for inlining webpack's chunk manifest. Default extracts manifest and inlines in `<head>`
|
55 | * [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.
|
56 |
|
57 | <h2 align="center">Usage</h2>
|
58 |
|
59 | The plugin will generate an HTML5 file for you that includes all your `webpack`
|
60 | bundles in the body using `script` tags. Just add the plugin to your `webpack`
|
61 | config as follows:
|
62 |
|
63 | **webpack.config.js**
|
64 | ```js
|
65 | const HtmlWebpackPlugin = require('html-webpack-plugin')
|
66 |
|
67 | module.exports = {
|
68 | entry: 'index.js',
|
69 | output: {
|
70 | path: __dirname + '/dist',
|
71 | filename: 'index_bundle.js'
|
72 | },
|
73 | plugins: [
|
74 | new HtmlWebpackPlugin()
|
75 | ]
|
76 | }
|
77 | ```
|
78 |
|
79 | This will generate a file `dist/index.html` containing the following
|
80 |
|
81 | ```html
|
82 | <!DOCTYPE html>
|
83 | <html>
|
84 | <head>
|
85 | <meta charset="UTF-8">
|
86 | <title>Webpack App</title>
|
87 | </head>
|
88 | <body>
|
89 | <script src="index_bundle.js"></script>
|
90 | </body>
|
91 | </html>
|
92 | ```
|
93 |
|
94 | If you have multiple `webpack` entry points, they will all be included with `script` tags in the generated HTML.
|
95 |
|
96 | If you have any CSS assets in webpack's output (for example, CSS extracted with the [ExtractTextPlugin](https://github.com/webpack/extract-text-webpack-plugin))
|
97 | then these will be included with `<link>` tags in the HTML head.
|
98 |
|
99 | If you have plugins that make use of it, `html-webpack-plugin` should be ordered first before any of the integrated plugins.
|
100 |
|
101 | <h2 align="center">Options</h2>
|
102 |
|
103 | You can pass a hash of configuration options to `html-webpack-plugin`.
|
104 | Allowed values are as follows
|
105 |
|
106 | |Name|Type|Default|Description|
|
107 | |:--:|:--:|:-----:|:----------|
|
108 | |**[`title`](#)**|`{String}`|``|The title to use for the generated HTML document|
|
109 | |**[`filename`](#)**|`{String}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`)|
|
110 | |**[`template`](#)**|`{String}`|``|`webpack` require path to the template. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details|
|
111 | |**[`inject`](#)**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element|
|
112 | |**[`favicon`](#)**|`{String}`|``|Adds the given favicon path to the output HTML|
|
113 | |**[`minify`](#)**|`{Boolean\|Object}`|`true`|Pass [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference)'s options as object to minify the output|
|
114 | |**[`hash`](#)**|`{Boolean}`|`false`|If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files. This is useful for cache busting|
|
115 | |**[`cache`](#)**|`{Boolean}`|`true`|Emit the file only if it was changed|
|
116 | |**[`showErrors`](#)**|`{Boolean}`|`true`|Errors details will be written into the HTML page|
|
117 | |**[`chunks`](#)**|`{?}`|`?`|Allows you to add only some chunks (e.g only the unit-test chunk)|
|
118 | |**[`chunksSortMode`](#plugins)**|`{String/|Function}`|`auto`|Allows to control how chunks should be sorted before they are included to the HTML. Allowed values are `'none' | 'auto' | 'dependency' | 'manual' | {Function}`|
|
119 | |**[`excludeChunks`](#)**|`{String}`|``|Allows you to skip some chunks (e.g don't add the unit-test chunk)|
|
120 | |**[`xhtml`](#)**|`{Boolean}`|`false`|If `true` render the `link` tags as self-closing (XHTML compliant)|
|
121 |
|
122 | Here's an example webpack config illustrating how to use these options
|
123 |
|
124 | **webpack.config.js**
|
125 | ```js
|
126 | {
|
127 | entry: 'index.js',
|
128 | output: {
|
129 | path: __dirname + '/dist',
|
130 | filename: 'index_bundle.js'
|
131 | },
|
132 | plugins: [
|
133 | new HtmlWebpackPlugin({
|
134 | title: 'My App',
|
135 | filename: 'assets/admin.html'
|
136 | })
|
137 | ]
|
138 | }
|
139 | ```
|
140 |
|
141 | ### `Generating Multiple HTML Files`
|
142 |
|
143 | To generate more than one HTML file, declare the plugin more than
|
144 | once in your plugins array
|
145 |
|
146 | **webpack.confg.js**
|
147 | ```js
|
148 | {
|
149 | entry: 'index.js',
|
150 | output: {
|
151 | path: __dirname + '/dist',
|
152 | filename: 'index_bundle.js'
|
153 | },
|
154 | plugins: [
|
155 | new HtmlWebpackPlugin(), // Generates default index.html
|
156 | new HtmlWebpackPlugin({ // Also generate a test.html
|
157 | filename: 'test.html',
|
158 | template: 'src/assets/test.html'
|
159 | })
|
160 | ]
|
161 | }
|
162 | ```
|
163 |
|
164 | ### `Writing Your Own Templates`
|
165 |
|
166 | If the default generated HTML doesn't meet your needs you can supply
|
167 | your own template. The easiest way is to use the `template` option and pass a custom HTML file.
|
168 | The html-webpack-plugin will automatically inject all necessary CSS, JS, manifest
|
169 | and favicon files into the markup.
|
170 |
|
171 | ```js
|
172 | plugins: [
|
173 | new HtmlWebpackPlugin({
|
174 | title: 'Custom template',
|
175 | // Load a custom template (lodash by default see the FAQ for details)
|
176 | template: 'index.html'
|
177 | })
|
178 | ]
|
179 | ```
|
180 |
|
181 | **index.html**
|
182 | ```html
|
183 | <!DOCTYPE html>
|
184 | <html>
|
185 | <head>
|
186 | <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
|
187 | <title><%= htmlWebpackPlugin.options.title %></title>
|
188 | </head>
|
189 | <body>
|
190 | </body>
|
191 | </html>
|
192 | ```
|
193 |
|
194 | If you already have a template loader, you can use it to parse the template.
|
195 | Please note that this will also happen if you specifiy the html-loader and use `.html` file as template.
|
196 |
|
197 | **webpack.config.js**
|
198 | ```js
|
199 | module: {
|
200 | loaders: [
|
201 | { test: /\.hbs$/, loader: "handlebars" }
|
202 | ]
|
203 | },
|
204 | plugins: [
|
205 | new HtmlWebpackPlugin({
|
206 | title: 'Custom template using Handlebars',
|
207 | template: 'index.hbs'
|
208 | })
|
209 | ]
|
210 | ```
|
211 |
|
212 | 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.
|
213 |
|
214 | The following variables are available in the template:
|
215 | - `htmlWebpackPlugin`: data specific to this plugin
|
216 | - `htmlWebpackPlugin.files`: a massaged representation of the
|
217 | `assetsByChunkName` attribute of webpack's [stats](https://github.com/webpack/docs/wiki/node.js-api#stats)
|
218 | object. It contains a mapping from entry point name to the bundle filename, eg:
|
219 | ```json
|
220 | "htmlWebpackPlugin": {
|
221 | "files": {
|
222 | "css": [ "main.css" ],
|
223 | "js": [ "assets/head_bundle.js", "assets/main_bundle.js"],
|
224 | "chunks": {
|
225 | "head": {
|
226 | "entry": "assets/head_bundle.js",
|
227 | "css": [ "main.css" ]
|
228 | },
|
229 | "main": {
|
230 | "entry": "assets/main_bundle.js",
|
231 | "css": []
|
232 | },
|
233 | }
|
234 | }
|
235 | }
|
236 | ```
|
237 | If you've set a publicPath in your webpack config this will be reflected
|
238 | correctly in this assets hash.
|
239 |
|
240 | - `htmlWebpackPlugin.options`: the options hash that was passed to
|
241 | the plugin. In addition to the options actually used by this plugin,
|
242 | you can use this hash to pass arbitrary data through to your template.
|
243 |
|
244 | - `webpack`: the webpack [stats](https://github.com/webpack/docs/wiki/node.js-api#stats)
|
245 | object. Note that this is the stats object as it was at the time the HTML template
|
246 | was emitted and as such may not have the full set of stats that are available
|
247 | after the webpack run is complete.
|
248 |
|
249 | - `webpackConfig`: the webpack configuration that was used for this compilation. This
|
250 | can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`).
|
251 |
|
252 | - `compilation`: the webpack [compilation](https://webpack.js.org/api/compilation/) object.
|
253 | This can be used, for example, to get the contents of processed assets and inline them
|
254 | directly in the page, through `compilation.assets[...].source()`
|
255 | (see [the inline template example](examples/inline/template.jade)).
|
256 |
|
257 |
|
258 | ### `Filtering Chunks`
|
259 |
|
260 | To include only certain chunks you can limit the chunks being used
|
261 |
|
262 | **webpack.config.js**
|
263 | ```js
|
264 | plugins: [
|
265 | new HtmlWebpackPlugin({
|
266 | chunks: ['app']
|
267 | })
|
268 | ]
|
269 | ```
|
270 |
|
271 | It is also possible to exclude certain chunks by setting the `excludeChunks` option
|
272 |
|
273 | **webpack.config.js**
|
274 | ```js
|
275 | plugins: [
|
276 | new HtmlWebpackPlugin({
|
277 | excludeChunks: [ 'dev-helper' ]
|
278 | })
|
279 | ]
|
280 | ```
|
281 |
|
282 | ### `Events`
|
283 |
|
284 | To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the HTML this plugin executes the following events:
|
285 |
|
286 | #### `Sync`
|
287 |
|
288 | * `html-webpack-plugin-alter-chunks`
|
289 |
|
290 | #### `Async`
|
291 |
|
292 | * `html-webpack-plugin-before-html-generation`
|
293 | * `html-webpack-plugin-before-html-processing`
|
294 | * `html-webpack-plugin-alter-asset-tags`
|
295 | * `html-webpack-plugin-after-html-processing`
|
296 | * `html-webpack-plugin-after-emit`
|
297 |
|
298 | Example implementation: [html-webpack-harddisk-plugin](https://github.com/jantimon/html-webpack-harddisk-plugin)
|
299 |
|
300 | **plugin.js**
|
301 | ```js
|
302 | function MyPlugin(options) {
|
303 | // Configure your plugin with options...
|
304 | }
|
305 |
|
306 | MyPlugin.prototype.apply = function (compiler) {
|
307 | compiler.plugin('compilation', (compilation) => {
|
308 | console.log('The compiler is starting a new compilation...');
|
309 |
|
310 | compilation.plugin(
|
311 | 'html-webpack-plugin-before-html-processing',
|
312 | (data, cb) => {
|
313 | data.html += 'The Magic Footer'
|
314 |
|
315 | cb(null, data)
|
316 | }
|
317 | )
|
318 | })
|
319 | }
|
320 |
|
321 | module.exports = MyPlugin
|
322 | ```
|
323 |
|
324 | **webpack.config.js**
|
325 | ```js
|
326 | plugins: [
|
327 | new MyPlugin({ options: '' })
|
328 | ]
|
329 | ```
|
330 |
|
331 | Note that the callback must be passed the HtmlWebpackPluginData in order to pass this onto any other plugins listening on the same `html-webpack-plugin-before-html-processing` event
|
332 |
|
333 | <h2 align="center">Contribution</h2>
|
334 |
|
335 | 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.
|
336 |
|
337 | This project uses the [semistandard code style](https://github.com/Flet/semistandard).
|
338 |
|
339 | Before running the tests, make sure to execute `yarn link` and `yarn link html-webpack-plugin` (or the `npm` variant of this).
|
340 |
|
341 |
|
342 | <h2 align="center">Maintainers</h2>
|
343 |
|
344 | <table>
|
345 | <tbody>
|
346 | <tr>
|
347 | <td align="center">
|
348 | <img width="150" height="150"
|
349 | src="https://avatars3.githubusercontent.com/u/4113649?v=3&s=150">
|
350 | </br>
|
351 | <a href="https://github.com/jantimon">Jan Nicklas</a>
|
352 | </td>
|
353 | <td align="center">
|
354 | <img width="150" height="150"
|
355 | src="https://avatars2.githubusercontent.com/u/4112409?v=3&s=150">
|
356 | </br>
|
357 | <a href="https://github.com/mastilver">Thomas Sileghem</a>
|
358 | </td>
|
359 | </tr>
|
360 | <tbody>
|
361 | </table>
|
362 |
|
363 |
|
364 | [npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg
|
365 | [npm-url]: https://npmjs.com/package/html-webpack-plugin
|
366 |
|
367 | [node]: https://img.shields.io/node/v/html-webpack-plugin.svg
|
368 | [node-url]: https://nodejs.org
|
369 |
|
370 | [deps]: https://david-dm.org/jantimon/html-webpack-plugin.svg
|
371 | [deps-url]: https://david-dm.org/jantimon/html-webpack-plugin
|
372 |
|
373 | [tests]: http://img.shields.io/travis/jantimon/html-webpack-plugin.svg
|
374 | [tests-url]: https://travis-ci.org/jantimon/html-webpack-plugin
|
375 |
|
376 | [cover]: https://img.shields.io/codecov/c/github/jantimon/html-webpack-plugin.svg
|
377 | [cover-url]: https://codecov.io/gh/jantimon/html-webpack-plugin
|
378 |
|
379 | [chat]: https://badges.gitter.im/webpack/webpack.svg
|
380 | [chat-url]: https://gitter.im/webpack/webpack
|