html-webpack-plugin 5.3.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [5.5.0](https://github.com/jantimon/html-webpack-plugin/compare/v5.4.0...v5.5.0) (2021-10-25)
6
+
7
+
8
+ ### Features
9
+
10
+ * Support type=module via scriptLoading option ([1e42625](https://github.com/jantimon/html-webpack-plugin/commit/1e4262528ff02a83e1fc7739b42472680fd205c2)), closes [#1663](https://github.com/jantimon/html-webpack-plugin/issues/1663)
11
+
12
+ ### [5.4.0](https://github.com/jantimon/html-webpack-plugin/compare/v5.3.2...v5.3.3) (2021-10-15)
13
+
14
+ ### Features
15
+
16
+ * update terser ([9c7fba0](https://github.com/jantimon/html-webpack-plugin/pull/1688)
17
+
18
+ ### [5.3.2](https://github.com/jantimon/html-webpack-plugin/compare/v5.3.1...v5.3.2) (2021-06-22)
19
+
20
+ ### Bug Fixes
21
+
22
+ * update lodash and pretty error ([9c7fba0](https://github.com/jantimon/html-webpack-plugin/commit/9c7fba02d0aa7d9e804863a66eb896db3046f645)
23
+
24
+ ### [5.3.1](https://github.com/jantimon/html-webpack-plugin/compare/v5.3.0...v5.3.1) (2021-03-09)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * remove loader-utils from plugin core ([82d0ee8](https://github.com/jantimon/html-webpack-plugin/commit/82d0ee8ddf146f17d71e98c1b44b2f2ec7420051))
30
+
5
31
  ## [5.3.0](https://github.com/jantimon/html-webpack-plugin/compare/v5.2.0...v5.3.0) (2021-03-07)
6
32
 
7
33
 
package/README.md CHANGED
@@ -79,7 +79,6 @@ The `html-webpack-plugin` provides [hooks](https://github.com/jantimon/html-webp
79
79
  * [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).
80
80
  * [html-webpack-injector](https://github.com/thearchitgarg/html-webpack-injector) to inject chunks in `head` or `body` (different locations ) of same html document.
81
81
  * [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'>`
82
- * [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
83
82
  * [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
84
83
  * [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.
85
84
  * [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.
@@ -89,13 +88,13 @@ The `html-webpack-plugin` provides [hooks](https://github.com/jantimon/html-webp
89
88
  * [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.
90
89
  * [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
91
90
  * [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) allows to add preload links &lt;link rel='preload'> anywhere you want.
92
-
91
+ * [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.
93
92
 
94
93
 
95
94
  <h2 align="center">Usage</h2>
96
95
 
97
96
  The plugin will generate an HTML5 file for you that includes all your `webpack`
98
- bundles in the body using `script` tags. Just add the plugin to your `webpack`
97
+ bundles in the head using `script` tags. Just add the plugin to your `webpack`
99
98
  config as follows:
100
99
 
101
100
  **webpack.config.js**
@@ -122,9 +121,9 @@ This will generate a file `dist/index.html` containing the following
122
121
  <head>
123
122
  <meta charset="utf-8">
124
123
  <title>Webpack App</title>
124
+ <script defer src="index_bundle.js"></script>
125
125
  </head>
126
126
  <body>
127
- <script src="index_bundle.js"></script>
128
127
  </body>
129
128
  </html>
130
129
  ```
@@ -150,7 +149,7 @@ Allowed values are as follows:
150
149
  |**`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) |
151
150
  |**`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)|
152
151
  |**`publicPath`**|`{String\|'auto'}`|`'auto'`|The publicPath used for script and link tags|
153
- |**`scriptLoading`**|`{'blocking'\|'defer'}`|`'defer'`| Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. |
152
+ |**`scriptLoading`**|`{'blocking'\|'defer'\|'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. |
154
153
  |**`favicon`**|`{String}`|``|Adds the given favicon path to the output HTML|
155
154
  |**`meta`**|`{Object}`|`{}`|Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`|
156
155
  |**`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`|
@@ -464,7 +463,7 @@ which will inject the element `<base href="http://example.com/some/page.html" ta
464
463
 
465
464
  ### Long Term Caching
466
465
 
467
- For long term caching add `contenthash/templatehash` to the filename.
466
+ For long term caching add `contenthash` to the filename.
468
467
 
469
468
  **Example:**
470
469
 
@@ -476,15 +475,9 @@ plugins: [
476
475
  ]
477
476
  ```
478
477
 
479
- `contenthash/templatehash` is the hash of the content of the output file.
480
-
481
- Optionally, You can configure like `[<hashType>:contenthash:<digestType>:<length>]`
482
-
483
- * `hashType` - one of `sha1`, `md5`, `sha256`, `sha512` or any other node.js supported hash type
484
- * `digestType` - one of `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
485
- * `maxlength` - maximum length of the generated hash in chars
478
+ `contenthash` is the hash of the content of the output file.
486
479
 
487
- **Defaults:** `[md5:contenthash:hex:9999]`
480
+ Refer webpack's [Template Strings](https://webpack.js.org/configuration/output/#template-strings) for more details
488
481
 
489
482
  ### Events
490
483
 
package/index.js CHANGED
@@ -14,7 +14,6 @@ const vm = require('vm');
14
14
  const fs = require('fs');
15
15
  const _ = require('lodash');
16
16
  const path = require('path');
17
- const loaderUtils = require('loader-utils');
18
17
  const { CachedChildCompilation } = require('./lib/cached-child-compiler');
19
18
 
20
19
  const { createHtmlTagObject, htmlTagObjectToString, HtmlTagArray } = require('./lib/html-tags');
@@ -71,7 +70,7 @@ class HtmlWebpackPlugin {
71
70
  this.options = options;
72
71
 
73
72
  // Assert correct option spelling
74
- assert(options.scriptLoading === 'defer' || options.scriptLoading === 'blocking', 'scriptLoading needs to be set to "defer" or "blocking');
73
+ assert(options.scriptLoading === 'defer' || options.scriptLoading === 'blocking' || options.scriptLoading === 'module', 'scriptLoading needs to be set to "defer", "blocking" or "module"');
75
74
  assert(options.inject === true || options.inject === false || options.inject === 'head' || options.inject === 'body', 'inject needs to be set to true, false, "head" or "body');
76
75
 
77
76
  // Default metaOptions if no template is provided
@@ -132,8 +131,7 @@ class HtmlWebpackPlugin {
132
131
  ...global,
133
132
  HTML_WEBPACK_PLUGIN: true,
134
133
  require: require,
135
- htmlWebpackPluginPublicPath:
136
- publicPath,
134
+ htmlWebpackPluginPublicPath: publicPath,
137
135
  URL: require('url').URL,
138
136
  __filename: templateWithoutLoaders
139
137
  });
@@ -189,13 +187,6 @@ function hookIntoCompiler (compiler, options, plugin) {
189
187
  options.filename = path.relative(outputPath, filename);
190
188
  }
191
189
 
192
- // `contenthash` is introduced in webpack v4.3
193
- // which conflicts with the plugin's existing `contenthash` method,
194
- // hence it is renamed to `templatehash` to avoid conflicts
195
- options.filename = options.filename.replace(/\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, (match) => {
196
- return match.replace('contenthash', 'templatehash');
197
- });
198
-
199
190
  // Check if webpack is running in production mode
200
191
  // @see https://github.com/webpack/webpack/blob/3366421f1784c449f415cda5930a8e445086f688/lib/WebpackOptionsDefaulter.js#L12-L14
201
192
  const isProductionLikeMode = compiler.options.mode === 'production' || !compiler.options.mode;
@@ -249,21 +240,12 @@ function hookIntoCompiler (compiler, options, plugin) {
249
240
  compilation.errors.push(prettyError(templateResult.error, compiler.context).toString());
250
241
  }
251
242
 
252
- const compiledEntries = 'compiledEntry' in templateResult ? {
253
- hash: templateResult.compiledEntry.hash,
254
- chunk: templateResult.compiledEntry.entry
255
- } : {
256
- hash: templateResult.mainCompilationHash
257
- };
258
-
259
- const childCompilationOutputName = compilation.getAssetPath(options.filename, compiledEntries);
260
-
261
243
  // If the child compilation was not executed during a previous main compile run
262
244
  // it is a cached result
263
245
  const isCompilationCached = templateResult.mainCompilationHash !== compilation.hash;
264
246
 
265
247
  /** The public path used inside the html file */
266
- const htmlPublicPath = getPublicPath(compilation, childCompilationOutputName, options.publicPath);
248
+ const htmlPublicPath = getPublicPath(compilation, options.filename, options.publicPath);
267
249
 
268
250
  /** Generated file paths from the entry point names */
269
251
  const assets = htmlWebpackPluginAssets(compilation, sortedEntryNames, htmlPublicPath);
@@ -288,7 +270,7 @@ function hookIntoCompiler (compiler, options, plugin) {
288
270
  assets.favicon = faviconPath;
289
271
  return getHtmlWebpackPluginHooks(compilation).beforeAssetTagGeneration.promise({
290
272
  assets: assets,
291
- outputName: childCompilationOutputName,
273
+ outputName: options.filename,
292
274
  plugin: plugin
293
275
  });
294
276
  });
@@ -306,7 +288,7 @@ function hookIntoCompiler (compiler, options, plugin) {
306
288
  ...generateFaviconTags(assets.favicon)
307
289
  ]
308
290
  },
309
- outputName: childCompilationOutputName,
291
+ outputName: options.filename,
310
292
  publicPath: htmlPublicPath,
311
293
  plugin: plugin
312
294
  }))
@@ -320,7 +302,7 @@ function hookIntoCompiler (compiler, options, plugin) {
320
302
  return getHtmlWebpackPluginHooks(compilation).alterAssetTagGroups.promise({
321
303
  headTags: assetGroups.headTags,
322
304
  bodyTags: assetGroups.bodyTags,
323
- outputName: childCompilationOutputName,
305
+ outputName: options.filename,
324
306
  publicPath: htmlPublicPath,
325
307
  plugin: plugin
326
308
  });
@@ -351,7 +333,7 @@ function hookIntoCompiler (compiler, options, plugin) {
351
333
  const injectedHtmlPromise = Promise.all([assetTagGroupsPromise, templateExectutionPromise])
352
334
  // Allow plugins to change the html before assets are injected
353
335
  .then(([assetTags, html]) => {
354
- const pluginArgs = { html, headTags: assetTags.headTags, bodyTags: assetTags.bodyTags, plugin: plugin, outputName: childCompilationOutputName };
336
+ const pluginArgs = { html, headTags: assetTags.headTags, bodyTags: assetTags.bodyTags, plugin: plugin, outputName: options.filename };
355
337
  return getHtmlWebpackPluginHooks(compilation).afterTemplateExecution.promise(pluginArgs);
356
338
  })
357
339
  .then(({ html, headTags, bodyTags }) => {
@@ -361,7 +343,7 @@ function hookIntoCompiler (compiler, options, plugin) {
361
343
  const emitHtmlPromise = injectedHtmlPromise
362
344
  // Allow plugins to change the html after assets are injected
363
345
  .then((html) => {
364
- const pluginArgs = { html, plugin: plugin, outputName: childCompilationOutputName };
346
+ const pluginArgs = { html, plugin: plugin, outputName: options.filename };
365
347
  return getHtmlWebpackPluginHooks(compilation).beforeEmit.promise(pluginArgs)
366
348
  .then(result => result.html);
367
349
  })
@@ -372,16 +354,15 @@ function hookIntoCompiler (compiler, options, plugin) {
372
354
  return options.showErrors ? prettyError(err, compiler.context).toHtml() : 'ERROR';
373
355
  })
374
356
  .then(html => {
375
- // Allow to use [templatehash] as placeholder for the html-webpack-plugin name
376
- // See also https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/
377
- // From https://github.com/webpack-contrib/extract-text-webpack-plugin/blob/8de6558e33487e7606e7cd7cb2adc2cccafef272/src/index.js#L212-L214
378
- const finalOutputName = childCompilationOutputName.replace(/\[(?:(\w+):)?templatehash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, (_, hashType, digestType, maxLength) => {
379
- return loaderUtils.getHashDigest(Buffer.from(html, 'utf8'), hashType, digestType, parseInt(maxLength, 10));
380
- });
357
+ const filename = options.filename.replace(/\[templatehash([^\]]*)\]/g, require('util').deprecate(
358
+ (match, options) => `[contenthash${options}]`,
359
+ '[templatehash] is now [contenthash]')
360
+ );
361
+ const replacedFilename = replacePlaceholdersInFilename(filename, html, compilation);
381
362
  // Add the evaluated html code to the webpack assets
382
- compilation.emitAsset(finalOutputName, new webpack.sources.RawSource(html, false));
383
- previousEmittedAssets.push({ name: finalOutputName, html });
384
- return finalOutputName;
363
+ compilation.emitAsset(replacedFilename.path, new webpack.sources.RawSource(html, false), replacedFilename.info);
364
+ previousEmittedAssets.push({ name: replacedFilename.path, html });
365
+ return replacedFilename.path;
385
366
  })
386
367
  .then((finalOutputName) => getHtmlWebpackPluginHooks(compilation).afterEmit.promise({
387
368
  outputName: finalOutputName,
@@ -519,6 +500,38 @@ function hookIntoCompiler (compiler, options, plugin) {
519
500
  });
520
501
  }
521
502
 
503
+ /**
504
+ * Replace [contenthash] in filename
505
+ *
506
+ * @see https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/
507
+ *
508
+ * @param {string} filename
509
+ * @param {string|Buffer} fileContent
510
+ * @param {WebpackCompilation} compilation
511
+ * @returns {{ path: string, info: {} }}
512
+ */
513
+ function replacePlaceholdersInFilename (filename, fileContent, compilation) {
514
+ if (/\[\\*([\w:]+)\\*\]/i.test(filename) === false) {
515
+ return { path: filename, info: {} };
516
+ }
517
+ const hash = compiler.webpack.util.createHash(compilation.outputOptions.hashFunction);
518
+ hash.update(fileContent);
519
+ if (compilation.outputOptions.hashSalt) {
520
+ hash.update(compilation.outputOptions.hashSalt);
521
+ }
522
+ const contentHash = hash.digest(compilation.outputOptions.hashDigest).slice(0, compilation.outputOptions.hashDigestLength);
523
+ return compilation.getPathWithInfo(
524
+ filename,
525
+ {
526
+ contentHash,
527
+ chunk: {
528
+ hash: contentHash,
529
+ contentHash
530
+ }
531
+ }
532
+ );
533
+ }
534
+
522
535
  /**
523
536
  * Helper to sort chunks
524
537
  * @param {string[]} entryNames
@@ -728,7 +741,8 @@ function hookIntoCompiler (compiler, options, plugin) {
728
741
  voidTag: false,
729
742
  meta: { plugin: 'html-webpack-plugin' },
730
743
  attributes: {
731
- defer: options.scriptLoading !== 'blocking',
744
+ defer: options.scriptLoading === 'defer',
745
+ type: options.scriptLoading === 'module' ? 'module' : undefined,
732
746
  src: scriptAsset
733
747
  }
734
748
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-webpack-plugin",
3
- "version": "5.3.0",
3
+ "version": "5.5.0",
4
4
  "license": "MIT",
5
5
  "description": "Simplifies creation of HTML files to serve your webpack bundles",
6
6
  "author": "Jan Nicklas <j.nicklas@me.com> (https://github.com/jantimon)",
@@ -28,32 +28,31 @@
28
28
  ]
29
29
  },
30
30
  "devDependencies": {
31
- "@types/loader-utils": "2.0.1",
32
31
  "@types/node": "11.13.9",
33
- "commitizen": "4.2.1",
32
+ "commitizen": "^4.2.4",
34
33
  "css-loader": "5.0.1",
35
34
  "cz-conventional-changelog": "2.1.0",
36
- "dir-compare": "1.7.2",
35
+ "dir-compare": "^3.3.0",
37
36
  "html-loader": "2.1.1",
38
- "jest": "26.5.3",
39
- "mini-css-extract-plugin": "1.0.0",
37
+ "jest": "^27.2.5",
38
+ "mini-css-extract-plugin": "^1.6.0",
40
39
  "pug": "3.0.2",
41
40
  "pug-loader": "2.4.0",
42
41
  "raw-loader": "4.0.2",
43
42
  "rimraf": "2.6.3",
44
43
  "semistandard": "^13.0.1",
45
- "standard-version": "9.1.0",
44
+ "standard-version": "^9.3.0",
46
45
  "style-loader": "2.0.0",
47
46
  "typescript": "4.1.3",
48
- "webpack": "5.23.0",
49
- "webpack-recompilation-simulator": "3.2.0",
50
- "webpack-cli": "4.2.0"
47
+ "webpack": "5.24.3",
48
+ "webpack-cli": "4.5.0",
49
+ "webpack-recompilation-simulator": "3.2.0"
51
50
  },
52
51
  "dependencies": {
53
- "@types/html-minifier-terser": "^5.0.0",
54
- "html-minifier-terser": "^5.0.1",
55
- "lodash": "^4.17.20",
56
- "pretty-error": "^2.1.1",
52
+ "@types/html-minifier-terser": "^6.0.0",
53
+ "html-minifier-terser": "^6.0.2",
54
+ "lodash": "^4.17.21",
55
+ "pretty-error": "^4.0.0",
57
56
  "tapable": "^2.0.0"
58
57
  },
59
58
  "peerDependencies": {
package/typings.d.ts CHANGED
@@ -96,7 +96,7 @@ declare namespace HtmlWebpackPlugin {
96
96
  *
97
97
  * @default 'defer'
98
98
  */
99
- scriptLoading?: "blocking" | "defer";
99
+ scriptLoading?: "blocking" | "defer" | "module";
100
100
  /**
101
101
  * Inject meta tags
102
102
  */