htmlnano 0.1.10 → 0.2.3

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/README.md CHANGED
@@ -4,30 +4,31 @@
4
4
 
5
5
  Modular HTML minifier, built on top of the [PostHTML](https://github.com/posthtml/posthtml). Inspired by [cssnano](http://cssnano.co/).
6
6
 
7
+
8
+
7
9
  ## [Benchmark](https://github.com/maltsev/html-minifiers-benchmark/blob/master/README.md)
8
- [html-minifier]: https://www.npmjs.com/package/html-minifier
9
- [htmlnano]: https://www.npmjs.com/package/htmlnano
10
+ [html-minifier@3.5.20]: https://www.npmjs.com/package/html-minifier
11
+ [htmlnano@0.2.0]: https://www.npmjs.com/package/htmlnano
10
12
 
11
- | Website | Source (KB) | [html-minifier] | [htmlnano] |
13
+ | Website | Source (KB) | [html-minifier@3.5.20] | [htmlnano@0.2.0] |
12
14
  |---------|------------:|----------------:|-----------:|
13
- | [stackoverflow.com](http://stackoverflow.com/) | 250 | 199 | 208 |
14
- | [github.com](http://github.com/) | 51 | 43 | 45 |
15
- | [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 71 | 64 | 68 |
16
- | [npmjs.com](https://www.npmjs.com/features) | 26 | 20 | 21 |
17
- | **Avg. minify rate** | 0% | **18%** | **14%** |
15
+ | [stackoverflow.com](http://stackoverflow.com/) | 258 | 205 | 218 |
16
+ | [github.com](http://github.com/) | 63 | 51 | 56 |
17
+ | [en.wikipedia.org](https://en.wikipedia.org/wiki/Main_Page) | 77 | 69 | 74 |
18
+ | [npmjs.com](https://www.npmjs.com/features) | 32 | 29 | 30 |
19
+ | **Avg. minify rate** | 0% | **15%** | **9%** |
18
20
 
19
- ## Usage
20
21
 
22
+ ## Usage
21
23
  ### Gulp
22
-
23
24
  ```bash
24
25
  npm install --save-dev gulp-htmlnano
25
26
  ```
26
27
 
27
28
  ```js
28
- var gulp = require('gulp');
29
- var htmlnano = require('gulp-htmlnano');
30
- var options = {
29
+ const gulp = require('gulp');
30
+ const htmlnano = require('gulp-htmlnano');
31
+ const options = {
31
32
  removeComments: false
32
33
  };
33
34
 
@@ -39,17 +40,18 @@ gulp.task('default', function() {
39
40
  });
40
41
  ```
41
42
 
42
- ### Javascript
43
43
 
44
+ ### Javascript
44
45
  ```js
45
- var htmlnano = require('htmlnano');
46
- var options = {
46
+ const htmlnano = require('htmlnano');
47
+ const options = {
47
48
  removeEmptyAttributes: false, // Disable the module "removeEmptyAttributes"
48
49
  collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
49
50
  };
50
51
 
51
52
  htmlnano
52
- .process(html, options)
53
+ // "preset" arg might be skipped (see "Presets" section below for more info)
54
+ .process(html, options, preset)
53
55
  .then(function (result) {
54
56
  // result.html is minified
55
57
  })
@@ -58,23 +60,23 @@ htmlnano
58
60
  });
59
61
  ```
60
62
 
61
- ### PostHTML
62
-
63
- Just add `htmlnano` as the last plugin:
64
63
 
64
+ ### PostHTML
65
+ Just add `htmlnano` as a final plugin:
65
66
  ```js
66
- var posthtml = require('posthtml');
67
- var options = {
67
+ const posthtml = require('posthtml');
68
+ const options = {
68
69
  removeComments: false, // Disable the module "removeComments"
69
70
  collapseWhitespace: 'conservative' // Pass options to the module "collapseWhitespace"
70
71
  };
71
- var posthtmlPlugins = [
72
+ const posthtmlPlugins = [
72
73
  /* other PostHTML plugins */
73
74
 
74
75
  require('htmlnano')(options)
75
76
  ];
76
77
 
77
- posthtml(posthtmlPlugins)
78
+ // "preset" arg might be skipped (see "Presets" section below for more info)
79
+ posthtml(posthtmlPlugins, preset)
78
80
  .process(html)
79
81
  .then(function (result) {
80
82
  // result.html is minified
@@ -82,36 +84,121 @@ posthtml(posthtmlPlugins)
82
84
  .catch(function (err) {
83
85
  console.error(err);
84
86
  });
87
+ ```
88
+
89
+
90
+
91
+ ## Presets
92
+ A preset is just an object with modules config.
93
+
94
+ Currently the following presets are available:
95
+ - [safe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.es6) — a default preset for minifying a regular HTML in a safe way (without breaking anything)
96
+ - [ampSafe](https://github.com/posthtml/htmlnano/blob/master/lib/presets/ampSafe.es6) - same as `safe` preset but for [AMP pages](https://www.ampproject.org/)
97
+ - [max](https://github.com/posthtml/htmlnano/blob/master/lib/presets/max.es6) - maximal minification (might break some pages)
98
+
99
+
100
+ You can use them the following way:
101
+ ```js
102
+ const htmlnano = require('htmlnano');
103
+ const ampSafePreset = require('htmlnano').presets.ampSafe;
104
+ const options = {
105
+ // Your options
106
+ };
107
+
108
+ htmlnano
109
+ .process(html, options, ampSafePreset)
110
+ .then(function (result) {
111
+ // result.html is minified
112
+ })
113
+ .catch(function (err) {
114
+ console.error(err);
115
+ });
116
+ ```
117
+
118
+ If you skip `preset` argument [`safe`](https://github.com/posthtml/htmlnano/blob/master/lib/presets/safe.es6) preset would be used by default.
119
+
120
+
121
+ If you'd like to define your very own config without any presets pass an empty object as a preset:
122
+ ```js
123
+ const htmlnano = require('htmlnano');
124
+ const options = {
125
+ // Your options
126
+ };
85
127
 
86
- // You can also use htmlnano modules separately:
87
- posthtml([
88
- require('htmlnano/lib/modules/mergeStyles').default
89
- ]).process(html);
128
+ htmlnano
129
+ .process(html, options, {})
130
+ .then(function (result) {
131
+ // result.html is minified
132
+ })
133
+ .catch(function (err) {
134
+ console.error(err);
135
+ });
90
136
  ```
91
137
 
92
- ## Modules
93
138
 
139
+ You might create also your own presets:
140
+ ```js
141
+ const htmlnano = require('htmlnano');
142
+ // Preset for minifying email templates
143
+ const emailPreset = {
144
+ mergeStyles: true,
145
+ minifyCss: {
146
+ safe: true
147
+ },
148
+ };
149
+
150
+ const options = {
151
+ // Some specific options
152
+ };
153
+
154
+ htmlnano
155
+ .process(html, options, emailPreset)
156
+ .then(function (result) {
157
+ // result.html is minified
158
+ })
159
+ .catch(function (err) {
160
+ console.error(err);
161
+ });
162
+ ```
163
+
164
+ Feel free [to submit a PR](https://github.com/posthtml/htmlnano/issues/new) with your preset if it might be useful for other developers as well.
165
+
166
+
167
+
168
+ ## Modules
94
169
  By default the modules should only perform safe transforms, see the module documentation below for details.
95
170
  You can disable modules by passing `false` as option, and enable them by passing `true`.
96
171
 
97
- ### collapseWhitespace
98
172
 
173
+ ### collapseAttributeWhitespace
174
+ Collapse redundant white spaces in list-like attributes (`class`, `rel`, `ping`).
175
+
176
+ ##### Example
177
+ Source:
178
+ ```html
179
+ <div class=" content page "></div>
180
+ ```
181
+
182
+ Minified:
183
+ ```html
184
+ <div class="content page"></div>
185
+ ```
186
+
187
+
188
+
189
+ ### collapseWhitespace
99
190
  Collapses redundant white spaces (including new lines). It doesn’t affect white spaces in the elements `<style>`, `<textarea>`, `<script>` and `<pre>`.
100
191
 
101
192
  ##### Options
102
-
103
193
  - `conservative` — collapses all redundant white spaces to 1 space (default)
104
194
  - `all` — collapses all redundant white spaces
105
195
 
106
196
  ##### Side effects
107
-
108
197
  `<i>hello</i> <i>world</i>` after minification will be rendered as `helloworld`.
109
198
  To prevent that use `conservative` option (this is the default option).
110
199
 
111
200
  ##### Example
112
-
113
201
  Source:
114
-
115
202
  ```html
116
203
  <div>
117
204
  hello world!
@@ -120,46 +207,53 @@ Source:
120
207
  ```
121
208
 
122
209
  Minified (with `all`):
123
-
124
210
  ```html
125
211
  <div>hello world!<style>div { color: red; } </style></div>
126
212
  ```
127
213
 
128
214
  Minified (with `conservative`):
129
-
130
215
  ```html
131
216
  <div> hello world! <style>div { color: red; } </style> </div>
132
217
  ```
133
218
 
134
- ### removeComments
135
219
 
136
- ##### Options
220
+ ### deduplicateAttributeValues
221
+ Remove duplicate values from list-like attributes (`class`, `rel`, `ping`).
222
+
223
+ ##### Example
224
+ Source:
225
+ ```html
226
+ <div class="sidebar left sidebar"></div>
227
+ ```
228
+
229
+ Minified:
230
+ ```html
231
+ <div class="sidebar left"></div>
232
+ ```
137
233
 
234
+
235
+ ### removeComments
236
+ ##### Options
138
237
  - `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
139
238
  - `all` — removes all HTML comments
140
239
 
141
240
  ##### Example
142
-
143
241
  Source:
144
-
145
242
  ```html
146
243
  <div><!-- test --></div>
147
244
  ```
148
245
 
149
246
  Minified:
150
-
151
247
  ```html
152
248
  <div></div>
153
249
  ```
154
250
 
155
- ### removeEmptyAttributes
156
251
 
252
+ ### removeEmptyAttributes
157
253
  Removes empty [safe-to-remove](https://github.com/posthtml/htmlnano/blob/master/lib/modules/removeEmptyAttributes.es6) attributes.
158
254
 
159
255
  ##### Side effects
160
-
161
256
  This module could break your styles or JS if you use selectors with attributes:
162
-
163
257
  ```CSS
164
258
  img[style=""] {
165
259
  margin: 10px;
@@ -167,48 +261,86 @@ img[style=""] {
167
261
  ```
168
262
 
169
263
  ##### Example
170
-
171
264
  Source:
172
-
173
265
  ```html
174
266
  <img src="foo.jpg" alt="" style="">
175
267
  ```
176
268
 
177
269
  Minified:
178
-
179
270
  ```html
180
271
  <img src="foo.jpg" alt="">
181
272
  ```
182
273
 
183
- ### minifyCss
184
-
185
- Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
274
+ ### removeUnusedCss
275
+ Removes unused CSS with [uncss](https://github.com/uncss/uncss) inside `<style>` tags.
186
276
 
187
277
  ##### Options
278
+ See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
188
279
 
189
- Css transforms are set to the `safe` option as a default (this should have very little side-effects):
280
+ uncss options can be passed directly to the `removeUnusedCss` module:
281
+ ```js
282
+ htmlnano.process(html, {
283
+ removeUnusedCss: {
284
+ ignore: ['.do-not-remove']
285
+ }
286
+ });
287
+ ```
190
288
 
191
- ```Json
192
- "minifyCss": {
193
- "safe": true
194
- }
289
+ The following uncss options are ignored if passed to the module:
290
+
291
+ - `stylesheets`
292
+ - `ignoreSheets`
293
+ - `raw`
294
+
295
+ ##### Example
296
+ Source:
297
+ ```html
298
+ <div class="b">
299
+ <style>
300
+ .a {
301
+ margin: 10px 10px 10px 10px;
302
+ }
303
+ .b {
304
+ color: #ff0000;
305
+ }
306
+ </style>
307
+ </div>
308
+ ```
309
+
310
+ Optimized:
311
+ ```html
312
+ <div class="b">
313
+ <style>
314
+ .b {
315
+ color: #ff0000;
316
+ }
317
+ </style>
318
+ </div>
195
319
  ```
196
320
 
197
- See [the documentation of cssnano](http://cssnano.co/optimisations/).
198
- For example you can [keep outdated vendor prefixes](http://cssnano.co/optimisations/#discard-outdated-vendor-prefixes):
199
321
 
322
+ ### minifyCss
323
+ Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
324
+
325
+ ##### Options
326
+ See [the documentation of cssnano](http://cssnano.co/optimisations/) for all supported optimizations.
327
+ By default CSS is minified with preset `default`, which shouldn't have any side-effects.
328
+
329
+ To use another preset or disabled some optimizations pass options to `minifyCss` module:
200
330
  ```js
201
331
  htmlnano.process(html, {
202
332
  minifyCss: {
203
- autoprefixer: false
333
+ preset: ['default', {
334
+ discardComments: {
335
+ removeAll: true,
336
+ },
337
+ }]
204
338
  }
205
339
  });
206
340
  ```
207
341
 
208
342
  ##### Example
209
-
210
343
  Source:
211
-
212
344
  ```html
213
345
  <div>
214
346
  <style>
@@ -221,30 +353,36 @@ Source:
221
353
  ```
222
354
 
223
355
  Minified:
224
-
225
356
  ```html
226
357
  <div>
227
358
  <style>h1{margin:10px;color:red}</style>
228
359
  </div>
229
360
  ```
230
361
 
231
- ### minifyJs
232
362
 
233
- Minifies JS with [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
363
+ ### minifyJs
364
+ Minifies JS using [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
234
365
 
235
366
  ##### Options
367
+ See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
368
+ Terser options can be passed directly to the `minifyJs` module:
369
+ ```js
370
+ htmlnano.process(html, {
371
+ minifyJs: {
372
+ output: { quote_style: 1 },
373
+ },
374
+ });
375
+ ```
236
376
 
237
- See [the API documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference)
238
377
 
239
- ##### Example
240
378
 
379
+ ##### Example
241
380
  Source:
242
-
243
381
  ```html
244
382
  <div>
245
383
  <script>
246
384
  /* comment */
247
- var foo = function () {
385
+ const foo = function () {
248
386
 
249
387
  };
250
388
  </script>
@@ -252,21 +390,18 @@ Source:
252
390
  ```
253
391
 
254
392
  Minified:
255
-
256
393
  ```html
257
394
  <div>
258
- <script>var foo=function(){};</script>
395
+ <script>const foo=function(){};</script>
259
396
  </div>
260
397
  ```
261
398
 
262
- ### minifyJson
263
399
 
400
+ ### minifyJson
264
401
  Minifies JSON inside `<script type="application/json"></script>`.
265
402
 
266
403
  ##### Example
267
-
268
404
  Source:
269
-
270
405
  ```html
271
406
  <script type="application/json">
272
407
  {
@@ -276,23 +411,29 @@ Source:
276
411
  ```
277
412
 
278
413
  Minified:
279
-
280
414
  ```html
281
415
  <script type="application/json">{"user":"me"}</script>
282
416
  ```
283
417
 
284
- ### minifySvg
285
418
 
286
- Minifies SVG inside `<svg>` tags with [SVGO](https://github.com/svg/svgo/).
419
+ ### minifySvg
420
+ Minifies SVG inside `<svg>` tags using [SVGO](https://github.com/svg/svgo/).
287
421
 
288
422
  ##### Options
289
-
290
- See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md)
423
+ See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
424
+ SVGO options can be passed directly to the `minifySvg` module:
425
+ ```js
426
+ htmlnano.process(html, {
427
+ minifySvg: {
428
+ plugins: [
429
+ { collapseGroups: false },
430
+ ],
431
+ },
432
+ });
433
+ ```
291
434
 
292
435
  ##### Example
293
-
294
436
  Source:
295
-
296
437
  ```html
297
438
  <svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
298
439
  <rect width="100%" height="100%" fill="red" />
@@ -304,15 +445,13 @@ Source:
304
445
  ```
305
446
 
306
447
  Minified:
307
-
308
448
  ```html
309
449
  <svg baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="red"/><circle cx="150" cy="100" r="80" fill="green"/><text x="150" y="125" font-size="60" text-anchor="middle" fill="#fff">SVG</text></svg>
310
450
  ```
311
451
 
312
- ### removeRedundantAttributes
313
452
 
453
+ ### removeRedundantAttributes
314
454
  Removes redundant attributes from tags if they contain default values:
315
-
316
455
  - `method="get"` from `<form>`
317
456
  - `type="text"` from `<input>`
318
457
  - `type="submit"` from `<button>`
@@ -321,13 +460,10 @@ Removes redundant attributes from tags if they contain default values:
321
460
  - `media="all"` from `<style>` and `<link>`
322
461
 
323
462
  ##### Options
324
-
325
463
  This module is disabled by default, change option to true to enable this module.
326
464
 
327
465
  ##### Side effects
328
-
329
466
  This module could break your styles or JS if you use selectors with attributes:
330
-
331
467
  ```CSS
332
468
  form[method="get"] {
333
469
  color: red;
@@ -335,9 +471,7 @@ form[method="get"] {
335
471
  ```
336
472
 
337
473
  ##### Example
338
-
339
474
  Source:
340
-
341
475
  ```html
342
476
  <form method="get">
343
477
  <input type="text">
@@ -345,21 +479,27 @@ Source:
345
479
  ```
346
480
 
347
481
  Minified:
348
-
349
482
  ```html
350
483
  <form>
351
484
  <input>
352
485
  </form>
353
486
  ```
354
487
 
355
- ### collapseBooleanAttributes
356
488
 
489
+ ### collapseBooleanAttributes
357
490
  Collapses boolean attributes (like `disabled`) to the minimized form.
358
491
 
359
- ##### Side effects
492
+ ##### Options
493
+ If your document uses [AMP](https://www.ampproject.org/), set the `amphtml` flag
494
+ to collapse additonal, AMP-specific boolean attributes:
495
+ ```Json
496
+ "collapseBooleanAttributes": {
497
+ "amphtml": true
498
+ }
499
+ ```
360
500
 
501
+ ##### Side effects
361
502
  This module could break your styles or JS if you use selectors with attributes:
362
-
363
503
  ```CSS
364
504
  button[disabled="disabled"] {
365
505
  color: red;
@@ -367,30 +507,25 @@ button[disabled="disabled"] {
367
507
  ```
368
508
 
369
509
  ##### Example
370
-
371
510
  Source:
372
-
373
511
  ```html
374
512
  <button disabled="disabled">click</button>
375
513
  <script defer=""></script>
376
514
  ```
377
515
 
378
516
  Minified:
379
-
380
517
  ```html
381
518
  <button disabled>click</button>
382
519
  <script defer></script>
383
520
  ```
384
521
 
385
- ### mergeStyles
386
522
 
523
+ ### mergeStyles
387
524
  Merges multiple `<style>` with the same `media` and `type` into one tag.
388
525
  `<style scoped>...</style>` are skipped.
389
526
 
390
527
  ##### Example
391
-
392
528
  Source:
393
-
394
529
  ```html
395
530
  <style>h1 { color: red }</style>
396
531
  <style media="print">div { color: blue }</style>
@@ -400,27 +535,23 @@ Source:
400
535
  ```
401
536
 
402
537
  Minified:
403
-
404
538
  ```html
405
539
  <style>h1 { color: red } div { font-size: 20px }</style>
406
540
  <style media="print">div { color: blue } a {}</style>
407
541
  ```
408
542
 
409
- ### mergeScripts
410
543
 
544
+ ### mergeScripts
411
545
  Merge multiple `<script>` with the same attributes (`id, class, type, async, defer`) into one (last) tag.
412
546
 
413
547
  ##### Side effects
414
-
415
548
  It could break your code if the tags with different attributes share the same variable scope.
416
549
  See the example below.
417
550
 
418
551
  ##### Example
419
-
420
552
  Source:
421
-
422
553
  ```html
423
- <script>var foo = 'A:1';</script>
554
+ <script>const foo = 'A:1';</script>
424
555
  <script class="test">foo = 'B:1';</script>
425
556
  <script type="text/javascript">foo = 'A:2';</script>
426
557
  <script defer>foo = 'C:1';</script>
@@ -430,21 +561,18 @@ Source:
430
561
  ```
431
562
 
432
563
  Minified:
433
-
434
564
  ```html
435
- <script>var foo = 'A:1'; foo = 'A:2'; foo = 'A:3';</script>
565
+ <script>const foo = 'A:1'; foo = 'A:2'; foo = 'A:3';</script>
436
566
  <script defer="defer">foo = 'C:1'; foo = 'C:2';</script>
437
567
  <script class="test" type="text/javascript">foo = 'B:1'; foo = 'B:2';</script>
438
568
  ```
439
569
 
440
- ### custom
441
570
 
571
+ ### custom
442
572
  It's also possible to pass custom modules in the minifier.
443
-
444
573
  As a function:
445
-
446
574
  ```js
447
- var options = {
575
+ const options = {
448
576
  custom: function (tree, options) {
449
577
  // Some minification
450
578
  return tree;
@@ -453,9 +581,8 @@ var options = {
453
581
  ```
454
582
 
455
583
  Or as a list of functions:
456
-
457
584
  ```js
458
- var options = {
585
+ const options = {
459
586
  custom: [
460
587
  function (tree, options) {
461
588
  // Some minification
@@ -472,8 +599,8 @@ var options = {
472
599
 
473
600
  `options` is an object with all options that were passed to the plugin.
474
601
 
475
- ## Contribute
476
602
 
603
+ ## Contribute
477
604
  Since the minifier is modular, it's very easy to add new modules:
478
605
 
479
606
  1. Create a ES6-file inside `lib/modules/` with a function that does some minification. For example you can check [`lib/modules/example.es6`](https://github.com/posthtml/htmlnano/blob/master/lib/modules/example.es6).