html-webpack-plugin 2.19.0 → 2.22.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
@@ -1,6 +1,22 @@
1
1
  Change History
2
2
  ==============
3
3
 
4
+ v2.22.0
5
+ ---
6
+ * Update dependencies
7
+
8
+ v2.21.1
9
+ ---
10
+ * Better error handling (#354)
11
+
12
+ v2.21.0
13
+ ----
14
+ * Add `html-webpack-plugin-alter-asset-tags` event to allow plugins to adjust the script/link tags
15
+
16
+ v2.20.0
17
+ ----
18
+ * Exclude chunks works now even if combined with dependency sort
19
+
4
20
  v2.19.0
5
21
  ----
6
22
  * Add `html-webpack-plugin-alter-chunks` event for custom chunk sorting and interpolation
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  HTML Webpack Plugin
2
2
  ===================
3
- [![npm version](https://badge.fury.io/js/html-webpack-plugin.svg)](http://badge.fury.io/js/html-webpack-plugin) [![Dependency Status](https://david-dm.org/ampedandwired/html-webpack-plugin.svg)](https://david-dm.org/ampedandwired/html-webpack-plugin) [![Build status](https://travis-ci.org/ampedandwired/html-webpack-plugin.svg)](https://travis-ci.org/ampedandwired/html-webpack-plugin) [![Windows build status](https://ci.appveyor.com/api/projects/status/github/ampedandwired/html-webpack-plugin?svg=true&branch=master)](https://ci.appveyor.com/project/jantimon/html-webpack-plugin) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard) [![bitHound Dependencies](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/badges/dependencies.svg)](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/master/dependencies/npm)
3
+ [![npm version](https://badge.fury.io/js/html-webpack-plugin.svg)](http://badge.fury.io/js/html-webpack-plugin) [![Dependency Status](https://david-dm.org/ampedandwired/html-webpack-plugin.svg)](https://david-dm.org/ampedandwired/html-webpack-plugin) [![Build status](https://travis-ci.org/ampedandwired/html-webpack-plugin.svg)](https://travis-ci.org/ampedandwired/html-webpack-plugin) [![Windows build status](https://ci.appveyor.com/api/projects/status/github/ampedandwired/html-webpack-plugin?svg=true&branch=master)](https://ci.appveyor.com/project/jantimon/html-webpack-plugin) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard) [![bitHound Dependencies](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/badges/dependencies.svg)](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/master/dependencies/npm) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)]()
4
4
 
5
5
  [![NPM](https://nodei.co/npm/html-webpack-plugin.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/html-webpack-plugin/)
6
6
 
@@ -24,8 +24,7 @@ Migration guide from 1.x
24
24
  [Changelog](https://github.com/ampedandwired/html-webpack-plugin/blob/master/CHANGELOG.md)
25
25
 
26
26
  If you used the 1.x version please take a look at the [migration guide](https://github.com/ampedandwired/html-webpack-plugin/blob/master/migration.md)
27
- In case I missed something please open a pull request for it.
28
- See also issue [#186](https://github.com/ampedandwired/html-webpack-plugin/issues/186)
27
+
29
28
 
30
29
  Basic Usage
31
30
  -----------
@@ -75,7 +74,7 @@ Allowed values are as follows:
75
74
  - `title`: The title to use for the generated HTML document.
76
75
  - `filename`: The file to write the HTML to. Defaults to `index.html`.
77
76
  You can specify a subdirectory here too (eg: `assets/admin.html`).
78
- - `template`: Path to the template. Supports loaders e.g. `html!./index.html`.
77
+ - `template`: Webpack require path to the template. Please see the [docs](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md) for details.
79
78
  - `inject`: `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.
80
79
  - `favicon`: Adds the given favicon path to the output html.
81
80
  - `minify`: `{...} | false` Pass a [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference) options object to minify the output.
@@ -105,6 +104,13 @@ Here's an example webpack config illustrating how to use these options:
105
104
  }
106
105
  ```
107
106
 
107
+ FAQ
108
+ ----
109
+
110
+ * [Why is my html minified?](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md)
111
+ * [Why is my `<% ... %>` template not working?](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md)
112
+ * [How can I use handlebars/pug/ejs as template engine](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md)
113
+
108
114
  Generating Multiple HTML Files
109
115
  ------------------------------
110
116
  To generate more than one HTML file, declare the plugin more than
@@ -137,8 +143,7 @@ and favicon files into the markup.
137
143
  plugins: [
138
144
  new HtmlWebpackPlugin({
139
145
  title: 'Custom template',
140
- template: 'my-index.ejs', // Load a custom template (ejs by default but can be changed)
141
- inject: 'body' // Inject all scripts into the body (this is the default so you can skip it)
146
+ template: 'my-index.ejs', // Load a custom template (ejs by default see the FAQ for details)
142
147
  })
143
148
  ]
144
149
  ```
@@ -244,14 +249,15 @@ Events
244
249
 
245
250
  To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the html this plugin executes the following events:
246
251
 
247
- Asnyc:
252
+ Async:
248
253
 
249
254
  * `html-webpack-plugin-before-html-generation`
250
255
  * `html-webpack-plugin-before-html-processing`
256
+ * `html-webpack-plugin-alter-asset-tags`
251
257
  * `html-webpack-plugin-after-html-processing`
252
258
  * `html-webpack-plugin-after-emit`
253
259
 
254
- Sync:
260
+ Sync:
255
261
 
256
262
  * `html-webpack-plugin-alter-chunks`
257
263
 
@@ -290,3 +296,13 @@ plugins: [
290
296
  ```
291
297
 
292
298
  Note that the callback must be passed the htmlPluginData in order to pass this onto any other plugins listening on the same 'html-webpack-plugin-before-html-processing' event.
299
+
300
+
301
+ # Contribution
302
+
303
+ You're free to contribute to this project by submitting [issues](https://github.com/ampedandwired/html-webpack-plugin/issues) and/or [pull requests](https://github.com/ampedandwired/html-webpack-plugin/pulls). This project is test-driven, so keep in mind that every change and new feature should be covered by tests.
304
+ This project uses the [semistandard code style](https://github.com/Flet/semistandard).
305
+
306
+ # License
307
+
308
+ This project is licensed under [MIT](https://github.com/ampedandwired/html-webpack-plugin/blob/master/LICENSE).
package/index.js CHANGED
@@ -12,7 +12,7 @@ Promise.promisifyAll(fs);
12
12
  function HtmlWebpackPlugin (options) {
13
13
  // Default options
14
14
  this.options = _.extend({
15
- template: __dirname + '/default_index.ejs',
15
+ template: path.join(__dirname, 'default_index.ejs'),
16
16
  filename: 'index.html',
17
17
  hash: false,
18
18
  inject: true,
@@ -143,8 +143,15 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
143
143
  });
144
144
  })
145
145
  .then(function (html) {
146
- // Add the stylesheets, scripts and so on to the resulting html
147
- return self.postProcessHtml(html, assets);
146
+ // Prepare script and link tags
147
+ var assetTags = self.generateAssetTags(assets);
148
+ var pluginArgs = {head: assetTags.head, body: assetTags.body, plugin: self, chunks: chunks, outputName: self.childCompilationOutputName};
149
+ // Allow plugins to change the assetTag definitions
150
+ return applyPluginsAsyncWaterfall('html-webpack-plugin-alter-asset-tags', pluginArgs)
151
+ .then(function () {
152
+ // Add the stylesheets, scripts and so on to the resulting html
153
+ return self.postProcessHtml(html, assets, { body: pluginArgs.body, head: pluginArgs.head });
154
+ });
148
155
  })
149
156
  // Allow plugins to change the html after assets are injected
150
157
  .then(function (html) {
@@ -259,7 +266,7 @@ HtmlWebpackPlugin.prototype.executeTemplate = function (templateFunction, chunks
259
266
  *
260
267
  * Returns a promise
261
268
  */
262
- HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets) {
269
+ HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets, assetTags) {
263
270
  var self = this;
264
271
  if (typeof html !== 'string') {
265
272
  return Promise.reject('Expected html to be a string but got ' + JSON.stringify(html));
@@ -268,7 +275,7 @@ HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets) {
268
275
  // Inject
269
276
  .then(function () {
270
277
  if (self.options.inject) {
271
- return self.injectAssetsIntoHtml(html, assets);
278
+ return self.injectAssetsIntoHtml(html, assets, assetTags);
272
279
  } else {
273
280
  return html;
274
281
  }
@@ -449,27 +456,45 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function (compilation, chu
449
456
  /**
450
457
  * Injects the assets into the given html string
451
458
  */
452
- HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets) {
459
+ HtmlWebpackPlugin.prototype.generateAssetTags = function (assets) {
453
460
  // Turn script files into script tags
454
461
  var scripts = assets.js.map(function (scriptPath) {
455
- return '<script type="text/javascript" src="' + scriptPath + '"></script>';
462
+ return {
463
+ tagName: 'script',
464
+ closeTag: true,
465
+ attributes: {
466
+ type: 'text/javascript',
467
+ src: scriptPath
468
+ }
469
+ };
456
470
  });
457
471
  // Make tags self-closing in case of xhtml
458
- var xhtml = this.options.xhtml ? '/' : '';
472
+ var selfClosingTag = !!this.options.xhtml;
459
473
  // Turn css files into link tags
460
474
  var styles = assets.css.map(function (stylePath) {
461
- return '<link href="' + stylePath + '" rel="stylesheet"' + xhtml + '>';
475
+ return {
476
+ tagName: 'link',
477
+ selfClosingTag: selfClosingTag,
478
+ attributes: {
479
+ href: stylePath,
480
+ rel: 'stylesheet'
481
+ }
482
+ };
462
483
  });
463
- // Injections
464
- var htmlRegExp = /(<html[^>]*>)/i;
484
+ // Injection targets
465
485
  var head = [];
466
- var headRegExp = /(<\/head>)/i;
467
486
  var body = [];
468
- var bodyRegExp = /(<\/body>)/i;
469
487
 
470
488
  // If there is a favicon present, add it to the head
471
489
  if (assets.favicon) {
472
- head.push('<link rel="shortcut icon" href="' + assets.favicon + '"' + xhtml + '>');
490
+ head.push({
491
+ tagName: 'link',
492
+ selfClosingTag: selfClosingTag,
493
+ attributes: {
494
+ rel: 'shortcut icon',
495
+ href: assets.favicon
496
+ }
497
+ });
473
498
  }
474
499
  // Add styles to the head
475
500
  head = head.concat(styles);
@@ -479,6 +504,18 @@ HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets) {
479
504
  } else {
480
505
  body = body.concat(scripts);
481
506
  }
507
+ return {head: head, body: body};
508
+ };
509
+
510
+ /**
511
+ * Injects the assets into the given html string
512
+ */
513
+ HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets, assetTags) {
514
+ var htmlRegExp = /(<html[^>]*>)/i;
515
+ var headRegExp = /(<\/head>)/i;
516
+ var bodyRegExp = /(<\/body>)/i;
517
+ var body = assetTags.body.map(this.createHtmlTag);
518
+ var head = assetTags.head.map(this.createHtmlTag);
482
519
 
483
520
  if (body.length) {
484
521
  if (bodyRegExp.test(html)) {
@@ -533,6 +570,18 @@ HtmlWebpackPlugin.prototype.appendHash = function (url, hash) {
533
570
  return url + (url.indexOf('?') === -1 ? '?' : '&') + hash;
534
571
  };
535
572
 
573
+ /**
574
+ * Turn a tag definition into a html string
575
+ */
576
+ HtmlWebpackPlugin.prototype.createHtmlTag = function (tagDefinition) {
577
+ var attributes = Object.keys(tagDefinition.attributes || {}).map(function (attributeName) {
578
+ return attributeName + '="' + tagDefinition.attributes[attributeName] + '"';
579
+ });
580
+ return '<' + [tagDefinition.tagName].concat(attributes).join(' ') + (tagDefinition.selfClosingTag ? '/' : '') + '>' +
581
+ (tagDefinition.innerHTML || '') +
582
+ (tagDefinition.closeTag ? '</' + tagDefinition.tagName + '>' : '');
583
+ };
584
+
536
585
  /**
537
586
  * Helper to return the absolute template path with a fallback loader
538
587
  */
@@ -543,7 +592,7 @@ HtmlWebpackPlugin.prototype.getFullTemplatePath = function (template, context) {
543
592
  }
544
593
  // Resolve template path
545
594
  return template.replace(
546
- /(\!)([^\/\\][^\!\?]+|[^\/\\!?])($|\?.+$)/,
595
+ /([!])([^\/\\][^!\?]+|[^\/\\!?])($|\?.+$)/,
547
596
  function (match, prefix, filepath, postfix) {
548
597
  return prefix + path.resolve(filepath) + postfix;
549
598
  });
@@ -41,10 +41,11 @@ module.exports.dependency = function (chunks) {
41
41
  // Add an edge for each parent (parent -> child)
42
42
  chunk.parents.forEach(function (parentId) {
43
43
  var parentChunk = nodeMap[parentId];
44
- if (!parentChunk) {
45
- throw new Error('Can not find chunk parent during dependency sort');
44
+ // If the parent chunk does not exist (e.g. because of an excluded chunk)
45
+ // we ignore that parent
46
+ if (parentChunk) {
47
+ edges.push([parentChunk, chunk]);
46
48
  }
47
- edges.push([parentChunk, chunk]);
48
49
  });
49
50
  }
50
51
  });
package/lib/compiler.js CHANGED
@@ -68,18 +68,6 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
68
68
  // Compile and return a promise
69
69
  return new Promise(function (resolve, reject) {
70
70
  childCompiler.runAsChild(function (err, entries, childCompilation) {
71
- // Replace [hash] placeholders in filename
72
- var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
73
- hash: childCompilation.hash,
74
- chunk: entries[0]
75
- });
76
- // Restore the parent compilation to the state like it
77
- // was before the child compilation
78
- compilation.assets[outputName] = assetsBeforeCompilation[outputName];
79
- if (assetsBeforeCompilation[outputName] === undefined) {
80
- // If it wasn't there - delete it
81
- delete compilation.assets[outputName];
82
- }
83
71
  // Resolve / reject the promise
84
72
  if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
85
73
  var errorDetails = childCompilation.errors.map(function (error) {
@@ -89,6 +77,18 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
89
77
  } else if (err) {
90
78
  reject(err);
91
79
  } else {
80
+ // Replace [hash] placeholders in filename
81
+ var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
82
+ hash: childCompilation.hash,
83
+ chunk: entries[0]
84
+ });
85
+ // Restore the parent compilation to the state like it
86
+ // was before the child compilation
87
+ compilation.assets[outputName] = assetsBeforeCompilation[outputName];
88
+ if (assetsBeforeCompilation[outputName] === undefined) {
89
+ // If it wasn't there - delete it
90
+ delete compilation.assets[outputName];
91
+ }
92
92
  resolve({
93
93
  // Hash of the template entry point
94
94
  hash: entries[0].hash,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-webpack-plugin",
3
- "version": "2.19.0",
3
+ "version": "2.22.0",
4
4
  "description": "Simplifies creation of HTML files to serve your webpack bundles",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -30,31 +30,39 @@
30
30
  "url": "https://github.com/ampedandwired/html-webpack-plugin/issues"
31
31
  },
32
32
  "homepage": "https://github.com/ampedandwired/html-webpack-plugin",
33
+ "semistandard": {
34
+ "ignore": [
35
+ "examples/*/dist/**/*.*"
36
+ ]
37
+ },
33
38
  "devDependencies": {
34
39
  "appcache-webpack-plugin": "^1.2.1",
35
40
  "css-loader": "^0.23.1",
36
41
  "dir-compare": "1.0.1",
37
42
  "es6-promise": "^3.2.1",
38
43
  "extract-text-webpack-plugin": "^1.0.1",
39
- "file-loader": "^0.8.5",
44
+ "file-loader": "^0.9.0",
40
45
  "html-loader": "^0.4.3",
41
46
  "jade": "^1.11.0",
42
47
  "jade-loader": "^0.8.0",
43
48
  "jasmine": "^2.4.1",
44
49
  "rimraf": "^2.5.2",
45
- "semistandard": "^7.0.5",
50
+ "semistandard": "^8.0.0",
46
51
  "style-loader": "^0.13.1",
47
52
  "underscore-template-loader": "^0.7.3",
48
53
  "url-loader": "^0.5.7",
49
- "webpack": "^1.13.0",
54
+ "webpack": "^1.13.1",
50
55
  "webpack-recompilation-simulator": "^1.3.0"
51
56
  },
52
57
  "dependencies": {
53
- "bluebird": "^3.3.5",
54
- "html-minifier": "^2.1.3",
58
+ "bluebird": "^3.4.1",
59
+ "html-minifier": "^2.1.6",
55
60
  "loader-utils": "^0.2.15",
56
- "lodash": "^4.12.0",
61
+ "lodash": "^4.13.1",
57
62
  "pretty-error": "^2.0.0",
58
63
  "toposort": "^1.0.0"
64
+ },
65
+ "peerDependencies": {
66
+ "webpack": "*"
59
67
  }
60
68
  }