htmlnano 2.0.1 → 2.0.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/CHANGELOG.md +16 -0
- package/README.md +2 -2
- package/docs/docs/010-introduction.md +4 -4
- package/docs/docs/020-usage.md +63 -23
- package/docs/docs/030-config.md +1 -1
- package/docs/docs/050-modules.md +500 -483
- package/docs/package-lock.json +289 -95
- package/docs/versioned_docs/version-1.1.1/010-introduction.md +4 -4
- package/docs/versioned_docs/version-1.1.1/030-config.md +1 -1
- package/docs/versioned_docs/version-2.0.0/010-introduction.md +4 -4
- package/docs/versioned_docs/version-2.0.0/030-config.md +2 -2
- package/index.d.ts +93 -0
- package/lib/helpers.js +4 -11
- package/lib/htmlnano.js +37 -55
- package/lib/modules/collapseAttributeWhitespace.js +11 -12
- package/lib/modules/collapseBooleanAttributes.js +33 -9
- package/lib/modules/collapseWhitespace.js +17 -19
- package/lib/modules/custom.js +0 -3
- package/lib/modules/deduplicateAttributeValues.js +3 -5
- package/lib/modules/mergeScripts.js +0 -11
- package/lib/modules/mergeStyles.js +2 -8
- package/lib/modules/minifyConditionalComments.js +4 -15
- package/lib/modules/minifyCss.js +5 -16
- package/lib/modules/minifyJs.js +8 -28
- package/lib/modules/minifyJson.js +5 -7
- package/lib/modules/minifySvg.js +13 -4
- package/lib/modules/minifyUrls.js +18 -34
- package/lib/modules/normalizeAttributeValues.js +85 -2
- package/lib/modules/removeAttributeQuotes.js +0 -2
- package/lib/modules/removeComments.js +10 -28
- package/lib/modules/removeEmptyAttributes.js +6 -6
- package/lib/modules/removeOptionalTags.js +9 -46
- package/lib/modules/removeRedundantAttributes.js +20 -68
- package/lib/modules/removeUnusedCss.js +7 -18
- package/lib/modules/sortAttributes.js +10 -25
- package/lib/modules/sortAttributesWithLists.js +7 -29
- package/lib/presets/ampSafe.js +2 -5
- package/lib/presets/max.js +2 -5
- package/lib/presets/safe.js +32 -15
- package/package.json +9 -15
- package/test.js +0 -48
package/docs/docs/050-modules.md
CHANGED
|
@@ -3,6 +3,49 @@
|
|
|
3
3
|
By default the modules should only perform safe transforms, see the module documentation below for details.
|
|
4
4
|
You can disable modules by passing `false` as option, and enable them by passing `true`.
|
|
5
5
|
|
|
6
|
+
The order in which the modules are documented is also the order in which they are applied.
|
|
7
|
+
|
|
8
|
+
## Attributes
|
|
9
|
+
|
|
10
|
+
### normalizeAttributeValues
|
|
11
|
+
|
|
12
|
+
- Normalize casing of specific attribute values that are case-insensitive (like `form[method]`, `img[img]` and `input[type]`).
|
|
13
|
+
- Apply [invalid value default](https://html.spec.whatwg.org/#invalid-value-default) attribute to invalid attribute values (like `<input type=foo>` to `<input type=text>`, which can then be minified to `<input>` by `removeRedundantAttributes` module).
|
|
14
|
+
#### Example
|
|
15
|
+
|
|
16
|
+
Source:
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<form method="GET"></form>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Minified:
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<form method="get"></form>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### removeEmptyAttributes
|
|
29
|
+
Removes empty [safe-to-remove](https://github.com/posthtml/htmlnano/blob/master/lib/modules/removeEmptyAttributes.es6) attributes.
|
|
30
|
+
|
|
31
|
+
#### Side effects
|
|
32
|
+
This module could break your styles or JS if you use selectors with attributes:
|
|
33
|
+
```CSS
|
|
34
|
+
img[style=""] {
|
|
35
|
+
margin: 10px;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### Example
|
|
40
|
+
Source:
|
|
41
|
+
```html
|
|
42
|
+
<img src="foo.jpg" alt="" style="">
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Minified:
|
|
46
|
+
```html
|
|
47
|
+
<img src="foo.jpg" alt="">
|
|
48
|
+
```
|
|
6
49
|
|
|
7
50
|
### collapseAttributeWhitespace
|
|
8
51
|
Collapse redundant white spaces in list-like attributes (`class`, `rel`, `ping`).
|
|
@@ -18,48 +61,81 @@ Minified:
|
|
|
18
61
|
<a class="content page" style="display: block;" href="https://example.com"></a>
|
|
19
62
|
```
|
|
20
63
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
64
|
+
### removeRedundantAttributes
|
|
65
|
+
Removes redundant attributes from tags if they contain default values:
|
|
66
|
+
- `method="get"` from `<form>`
|
|
67
|
+
- `type="text"` from `<input>`
|
|
68
|
+
- `type="submit"` from `<button>`
|
|
69
|
+
- `language="javascript"` and `type="text/javascript"` from `<script>`
|
|
70
|
+
- `charset` from `<script>` if it's an external script
|
|
71
|
+
- `media="all"` from `<style>` and `<link>`
|
|
72
|
+
- `type="text/css"` from `<link rel="stylesheet">`
|
|
25
73
|
|
|
26
74
|
#### Options
|
|
27
|
-
|
|
28
|
-
- `aggressive` — collapses all whitespaces that are redundant and safe to remove
|
|
29
|
-
- `all` — collapses all redundant white spaces
|
|
75
|
+
This module is disabled by default, change option to true to enable this module.
|
|
30
76
|
|
|
31
77
|
#### Side effects
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
78
|
+
This module could break your styles or JS if you use selectors with attributes:
|
|
79
|
+
```CSS
|
|
80
|
+
form[method="get"] {
|
|
81
|
+
color: red;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
36
84
|
|
|
37
85
|
#### Example
|
|
38
86
|
Source:
|
|
39
87
|
```html
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<style>div { color: red; } </style>
|
|
44
|
-
<main></main>
|
|
45
|
-
</div>
|
|
88
|
+
<form method="get">
|
|
89
|
+
<input type="text">
|
|
90
|
+
</form>
|
|
46
91
|
```
|
|
47
92
|
|
|
48
|
-
Minified
|
|
93
|
+
Minified:
|
|
49
94
|
```html
|
|
50
|
-
<
|
|
95
|
+
<form>
|
|
96
|
+
<input>
|
|
97
|
+
</form>
|
|
51
98
|
```
|
|
52
99
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
100
|
+
### collapseBooleanAttributes
|
|
101
|
+
|
|
102
|
+
- Collapses boolean attributes (like `disabled`) to the minimized form.
|
|
103
|
+
- Collapses empty string value attributes (like `href=""`) to the minimized form.
|
|
104
|
+
- Collapses [missing value default](https://html.spec.whatwg.org/#missing-value-default) attributes that are empty strings (`audio[preload=auto]` and `video[preload=auto]`) to the minimized form.
|
|
105
|
+
|
|
106
|
+
#### Options
|
|
107
|
+
If your document uses [AMP](https://www.ampproject.org/), set the `amphtml` flag
|
|
108
|
+
to collapse additonal, AMP-specific boolean attributes:
|
|
109
|
+
```Json
|
|
110
|
+
"collapseBooleanAttributes": {
|
|
111
|
+
"amphtml": true
|
|
112
|
+
}
|
|
56
113
|
```
|
|
57
114
|
|
|
58
|
-
|
|
115
|
+
#### Side effects
|
|
116
|
+
This module could break your styles or JS if you use selectors with attributes:
|
|
117
|
+
```CSS
|
|
118
|
+
button[disabled="disabled"] {
|
|
119
|
+
color: red;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Example
|
|
124
|
+
Source:
|
|
59
125
|
```html
|
|
60
|
-
<
|
|
126
|
+
<button disabled="disabled">click</button>
|
|
127
|
+
<script defer=""></script>
|
|
128
|
+
<a href=""></a>
|
|
129
|
+
<video preload="auto"></video>
|
|
61
130
|
```
|
|
62
131
|
|
|
132
|
+
Minified:
|
|
133
|
+
```html
|
|
134
|
+
<button disabled>click</button>
|
|
135
|
+
<script defer></script>
|
|
136
|
+
<a href></a>
|
|
137
|
+
<video preload></video>
|
|
138
|
+
```
|
|
63
139
|
|
|
64
140
|
### deduplicateAttributeValues
|
|
65
141
|
Remove duplicate values from list-like attributes (`class`, `rel`, `ping`).
|
|
@@ -75,480 +151,371 @@ Minified:
|
|
|
75
151
|
<div class="sidebar left"></div>
|
|
76
152
|
```
|
|
77
153
|
|
|
154
|
+
### minifyUrls
|
|
155
|
+
Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
|
|
78
156
|
|
|
79
|
-
|
|
80
|
-
#### Options
|
|
81
|
-
- `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
|
|
82
|
-
- `all` — removes all HTML comments
|
|
83
|
-
- A `RegExp` — only HTML comments matching the given regexp will be removed.
|
|
84
|
-
- A `Function` that returns boolean — removes HTML comments that can make the given callback function returns truthy value.
|
|
157
|
+
You have to install `relateurl`, `terser` and `srcset` in order to use this feature:
|
|
85
158
|
|
|
86
|
-
|
|
159
|
+
```bash
|
|
160
|
+
npm install --save-dev relateurl terser srcset
|
|
161
|
+
# if you prefer yarn
|
|
162
|
+
# yarn add --dev relateurl terser srcset
|
|
163
|
+
# if you prefer pnpm
|
|
164
|
+
# pnpm install --save-dev relateurl terser srcset
|
|
165
|
+
```
|
|
87
166
|
|
|
88
|
-
|
|
167
|
+
#### Options
|
|
168
|
+
|
|
169
|
+
The base URL to resolve against. Support `String` & `URL`.
|
|
89
170
|
|
|
90
171
|
```js
|
|
91
|
-
{
|
|
92
|
-
|
|
93
|
-
}
|
|
172
|
+
htmlnano.process(html, {
|
|
173
|
+
minifyUrls: 'https://example.com' // Valid configuration
|
|
174
|
+
});
|
|
94
175
|
```
|
|
95
176
|
|
|
96
|
-
```
|
|
97
|
-
|
|
177
|
+
```js
|
|
178
|
+
htmlnano.process(html, {
|
|
179
|
+
minifyUrls: new URL('https://example.com') // Valid configuration
|
|
180
|
+
});
|
|
98
181
|
```
|
|
99
182
|
|
|
100
|
-
|
|
183
|
+
```js
|
|
184
|
+
htmlnano.process(html, {
|
|
185
|
+
minifyUrls: false // The module will be disabled
|
|
186
|
+
});
|
|
187
|
+
```
|
|
101
188
|
|
|
102
|
-
```
|
|
103
|
-
|
|
189
|
+
```js
|
|
190
|
+
htmlnano.process(html, {
|
|
191
|
+
minifyUrls: true // Invalid configuration, the module will be disabled
|
|
192
|
+
});
|
|
104
193
|
```
|
|
105
194
|
|
|
106
|
-
|
|
195
|
+
#### Example
|
|
196
|
+
|
|
197
|
+
**Basic Usage**
|
|
198
|
+
|
|
199
|
+
Configuration:
|
|
107
200
|
|
|
108
201
|
```js
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
}
|
|
202
|
+
htmlnano.process(html, {
|
|
203
|
+
minifyUrls: 'https://example.com'
|
|
204
|
+
});
|
|
112
205
|
```
|
|
113
206
|
|
|
207
|
+
Source:
|
|
208
|
+
|
|
114
209
|
```html
|
|
115
|
-
<
|
|
210
|
+
<a href="https://example.com/foo/bar/baz">bar</a>
|
|
116
211
|
```
|
|
117
212
|
|
|
118
213
|
Minified:
|
|
119
214
|
|
|
120
215
|
```html
|
|
121
|
-
<
|
|
216
|
+
<a href="foo/bar/baz">bar</a>
|
|
122
217
|
```
|
|
123
218
|
|
|
124
|
-
|
|
219
|
+
**With sub-directory**
|
|
220
|
+
|
|
221
|
+
Configuration:
|
|
125
222
|
|
|
126
223
|
```js
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
224
|
+
htmlnano.process(html, {
|
|
225
|
+
minifyUrls: 'https://example.com/foo/baz/'
|
|
226
|
+
});
|
|
133
227
|
```
|
|
134
228
|
|
|
229
|
+
Source:
|
|
230
|
+
|
|
135
231
|
```html
|
|
136
|
-
<
|
|
232
|
+
<a href="https://example.com/foo/bar">bar</a>
|
|
137
233
|
```
|
|
138
234
|
|
|
139
235
|
Minified:
|
|
140
236
|
|
|
141
237
|
```html
|
|
142
|
-
<
|
|
238
|
+
<a href="../bar">bar</a>
|
|
143
239
|
```
|
|
144
240
|
|
|
145
241
|
|
|
146
|
-
###
|
|
147
|
-
|
|
242
|
+
### sortAttributes
|
|
243
|
+
Sort attributes inside elements.
|
|
148
244
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
```
|
|
245
|
+
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
|
246
|
+
|
|
247
|
+
#### Options
|
|
248
|
+
|
|
249
|
+
- `alphabetical`: Default option. Sort attributes in alphabetical order.
|
|
250
|
+
- `frequency`: Sort attributes by frequency.
|
|
156
251
|
|
|
157
252
|
#### Example
|
|
253
|
+
|
|
254
|
+
**alphabetical**
|
|
255
|
+
|
|
158
256
|
Source:
|
|
159
257
|
```html
|
|
160
|
-
<
|
|
258
|
+
<input type="text" class="form-control" name="testInput" autofocus="" autocomplete="off" id="testId">
|
|
161
259
|
```
|
|
162
260
|
|
|
163
|
-
|
|
261
|
+
Processed:
|
|
164
262
|
```html
|
|
165
|
-
<
|
|
263
|
+
<input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
|
|
166
264
|
```
|
|
167
265
|
|
|
168
|
-
|
|
169
|
-
Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
|
|
266
|
+
**frequency**
|
|
170
267
|
|
|
171
|
-
#### Example
|
|
172
268
|
Source:
|
|
173
269
|
```html
|
|
174
|
-
<
|
|
270
|
+
<input type="text" class="form-control" name="testInput" id="testId">
|
|
271
|
+
<a id="testId" href="#" class="testClass"></a>
|
|
272
|
+
<img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
|
|
175
273
|
```
|
|
176
274
|
|
|
177
|
-
|
|
275
|
+
Processed:
|
|
178
276
|
```html
|
|
179
|
-
<
|
|
277
|
+
<input class="form-control" id="testId" type="text" name="testInput">
|
|
278
|
+
<a class="testClass" id="testId" href="#"></a>
|
|
279
|
+
<img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
|
|
180
280
|
```
|
|
181
281
|
|
|
182
|
-
#### Notice
|
|
183
|
-
The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
|
|
184
|
-
|
|
185
|
-
For example:
|
|
186
282
|
|
|
187
|
-
```js
|
|
188
|
-
posthtml([
|
|
189
|
-
htmlnano({
|
|
190
|
-
removeAttributeQuotes: true
|
|
191
|
-
})
|
|
192
|
-
]).process(html, {
|
|
193
|
-
quoteAllAttributes: true
|
|
194
|
-
})
|
|
195
|
-
```
|
|
196
283
|
|
|
197
|
-
|
|
284
|
+
### sortAttributesWithLists
|
|
285
|
+
Sort values in list-like attributes (`class`, `rel`, `ping`).
|
|
198
286
|
|
|
199
|
-
|
|
287
|
+
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
|
200
288
|
|
|
201
|
-
|
|
202
|
-
or [PurgeCSS](https://github.com/FullHuman/purgecss).
|
|
289
|
+
#### Options
|
|
203
290
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
You have to install `uncss` in order to use this feature:
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
npm install --save-dev uncss
|
|
210
|
-
# if you prefer yarn
|
|
211
|
-
# yarn add --dev uncss
|
|
212
|
-
# if you prefer pnpm
|
|
213
|
-
# pnpm install --save-dev uncss
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
You can also use a mainted fork [@novaatwarren/uncss](https://www.npmjs.com/package/@novaatwarren/uncss) instead.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
##### Options
|
|
220
|
-
See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
|
|
221
|
-
|
|
222
|
-
uncss options can be passed directly to the `removeUnusedCss` module:
|
|
223
|
-
```js
|
|
224
|
-
htmlnano.process(html, {
|
|
225
|
-
removeUnusedCss: {
|
|
226
|
-
ignore: ['.do-not-remove']
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
The following uncss options are ignored if passed to the module:
|
|
232
|
-
|
|
233
|
-
- `stylesheets`
|
|
234
|
-
- `ignoreSheets`
|
|
235
|
-
- `raw`
|
|
236
|
-
|
|
237
|
-
#### With PurgeCSS
|
|
291
|
+
- `alphabetical`: Default option. Sort attribute values in alphabetical order.
|
|
292
|
+
- `frequency`: Sort attribute values by frequency.
|
|
238
293
|
|
|
239
|
-
|
|
294
|
+
#### Example
|
|
240
295
|
|
|
241
|
-
|
|
296
|
+
**alphabetical**
|
|
242
297
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# yarn add --dev purgecss
|
|
247
|
-
# if you prefer pnpm
|
|
248
|
-
# pnpm install --save-dev purgecss
|
|
298
|
+
Source:
|
|
299
|
+
```html
|
|
300
|
+
<div class="foo baz bar">click</div>
|
|
249
301
|
```
|
|
250
302
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
PurgeCSS options can be passed directly to the `removeUnusedCss` module:
|
|
256
|
-
```js
|
|
257
|
-
htmlnano.process(html, {
|
|
258
|
-
removeUnusedCss: {
|
|
259
|
-
tool: 'purgeCSS',
|
|
260
|
-
safelist: ['.do-not-remove']
|
|
261
|
-
}
|
|
262
|
-
});
|
|
303
|
+
Processed:
|
|
304
|
+
```html
|
|
305
|
+
<div class="bar baz foo">click</div>
|
|
263
306
|
```
|
|
264
307
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
- `content`
|
|
268
|
-
- `css`
|
|
269
|
-
- `extractors`
|
|
308
|
+
**frequency**
|
|
270
309
|
|
|
271
|
-
#### Example
|
|
272
310
|
Source:
|
|
273
311
|
```html
|
|
274
|
-
<div class="
|
|
275
|
-
<style>
|
|
276
|
-
.a {
|
|
277
|
-
margin: 10px 10px 10px 10px;
|
|
278
|
-
}
|
|
279
|
-
.b {
|
|
280
|
-
color: #ff0000;
|
|
281
|
-
}
|
|
282
|
-
</style>
|
|
283
|
-
</div>
|
|
312
|
+
<div class="foo baz bar"></div><div class="bar foo"></div>
|
|
284
313
|
```
|
|
285
314
|
|
|
286
|
-
|
|
315
|
+
Processed:
|
|
287
316
|
```html
|
|
288
|
-
<div class="
|
|
289
|
-
<style>
|
|
290
|
-
.b {
|
|
291
|
-
color: #ff0000;
|
|
292
|
-
}
|
|
293
|
-
</style>
|
|
294
|
-
</div>
|
|
317
|
+
<div class="foo bar baz"></div><div class="foo bar"></div>
|
|
295
318
|
```
|
|
296
319
|
|
|
297
320
|
|
|
298
|
-
### minifyCss
|
|
299
|
-
Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
|
|
300
321
|
|
|
301
|
-
You have to install `cssnano` and `postcss` in order to use this feature:
|
|
302
|
-
|
|
303
|
-
```bash
|
|
304
|
-
npm install --save-dev cssnano postcss
|
|
305
|
-
# if you prefer yarn
|
|
306
|
-
# yarn add --dev cssnano postcss
|
|
307
|
-
# if you prefer pnpm
|
|
308
|
-
# pnpm install --save-dev cssnano postcss
|
|
309
|
-
```
|
|
310
322
|
|
|
311
323
|
#### Options
|
|
312
|
-
|
|
313
|
-
|
|
324
|
+
- `conservative` — collapses all redundant white spaces to 1 space (default)
|
|
325
|
+
- `aggressive` — collapses all whitespaces that are redundant and safe to remove
|
|
326
|
+
- `all` — collapses all redundant white spaces
|
|
314
327
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
discardComments: {
|
|
321
|
-
removeAll: true,
|
|
322
|
-
},
|
|
323
|
-
}]
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
```
|
|
328
|
+
#### Side effects
|
|
329
|
+
|
|
330
|
+
*all*
|
|
331
|
+
`<i>hello</i> <i>world</i>` or `<i>hello</i><br><i>world</i>` after minification will be rendered as `helloworld`.
|
|
332
|
+
To prevent that use either the default `conservative` option, or the `aggressive` option.
|
|
327
333
|
|
|
328
334
|
#### Example
|
|
329
335
|
Source:
|
|
330
336
|
```html
|
|
331
337
|
<div>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
</style>
|
|
338
|
+
hello world!
|
|
339
|
+
<a href="#">answer</a>
|
|
340
|
+
<style>div { color: red; } </style>
|
|
341
|
+
<main></main>
|
|
338
342
|
</div>
|
|
339
343
|
```
|
|
340
344
|
|
|
341
|
-
Minified:
|
|
345
|
+
Minified (with `all`):
|
|
342
346
|
```html
|
|
343
|
-
<div>
|
|
344
|
-
<style>h1{margin:10px;color:red}</style>
|
|
345
|
-
</div>
|
|
347
|
+
<div>hello world!<a href="#">answer</a><style>div { color: red; } </style><main></main></div>
|
|
346
348
|
```
|
|
347
349
|
|
|
350
|
+
Minified (with `aggressive`):
|
|
351
|
+
```html
|
|
352
|
+
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style><main></main></div>
|
|
353
|
+
```
|
|
348
354
|
|
|
349
|
-
|
|
350
|
-
|
|
355
|
+
Minified (with `conservative`):
|
|
356
|
+
```html
|
|
357
|
+
<div> hello world! <a href="#">answer</a> <style>div { color: red; } </style> <main></main> </div>
|
|
358
|
+
```
|
|
351
359
|
|
|
352
|
-
You have to install `terser` in order to use this feature:
|
|
353
360
|
|
|
354
|
-
```bash
|
|
355
|
-
npm install --save-dev terser
|
|
356
|
-
# if you prefer yarn
|
|
357
|
-
# yarn add --dev terser
|
|
358
|
-
# if you prefer pnpm
|
|
359
|
-
# pnpm install --save-dev terser
|
|
360
|
-
```
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
|
|
364
|
-
Terser options can be passed directly to the `minifyJs` module:
|
|
365
|
-
```js
|
|
366
|
-
htmlnano.process(html, {
|
|
367
|
-
minifyJs: {
|
|
368
|
-
output: { quote_style: 1 },
|
|
369
|
-
},
|
|
370
|
-
});
|
|
371
|
-
```
|
|
362
|
+
## HTML Content
|
|
372
363
|
|
|
364
|
+
### collapseWhitespace
|
|
365
|
+
Collapses redundant white spaces (including new lines). It doesn’t affect white spaces in the elements `<style>`, `<textarea>`, `<script>` and `<pre>`.
|
|
373
366
|
|
|
374
367
|
|
|
368
|
+
### removeComments
|
|
369
|
+
#### Options
|
|
370
|
+
- `safe` – removes all HTML comments except the conditional comments and [`<!--noindex--><!--/noindex-->`](https://yandex.com/support/webmaster/controlling-robot/html.xml) (default)
|
|
371
|
+
- `all` — removes all HTML comments
|
|
372
|
+
- A `RegExp` — only HTML comments matching the given regexp will be removed.
|
|
373
|
+
- A `Function` that returns boolean — removes HTML comments that can make the given callback function returns truthy value.
|
|
374
|
+
|
|
375
375
|
#### Example
|
|
376
|
+
|
|
376
377
|
Source:
|
|
377
|
-
```html
|
|
378
|
-
<div>
|
|
379
|
-
<script>
|
|
380
|
-
/* comment */
|
|
381
|
-
const foo = function () {
|
|
382
378
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
379
|
+
```js
|
|
380
|
+
{
|
|
381
|
+
removeComments: 'all'
|
|
382
|
+
}
|
|
386
383
|
```
|
|
387
384
|
|
|
388
|
-
Minified:
|
|
389
385
|
```html
|
|
390
|
-
<div>
|
|
391
|
-
<script>const foo=function(){};</script>
|
|
392
|
-
</div>
|
|
386
|
+
<div><!-- test --></div>
|
|
393
387
|
```
|
|
394
388
|
|
|
389
|
+
Minified:
|
|
395
390
|
|
|
396
|
-
|
|
397
|
-
|
|
391
|
+
```html
|
|
392
|
+
<div></div>
|
|
393
|
+
```
|
|
398
394
|
|
|
399
|
-
#### Example
|
|
400
395
|
Source:
|
|
401
|
-
|
|
402
|
-
|
|
396
|
+
|
|
397
|
+
```js
|
|
403
398
|
{
|
|
404
|
-
|
|
399
|
+
removeComments: /<!--(\/)?noindex-->/
|
|
405
400
|
}
|
|
406
|
-
</script>
|
|
407
401
|
```
|
|
408
402
|
|
|
409
|
-
Minified:
|
|
410
403
|
```html
|
|
411
|
-
<
|
|
404
|
+
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
|
412
405
|
```
|
|
413
406
|
|
|
407
|
+
Minified:
|
|
414
408
|
|
|
415
|
-
|
|
416
|
-
|
|
409
|
+
```html
|
|
410
|
+
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Source:
|
|
417
414
|
|
|
418
|
-
#### Options
|
|
419
|
-
See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
|
|
420
|
-
SVGO options can be passed directly to the `minifySvg` module:
|
|
421
415
|
```js
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
name: 'preset-default',
|
|
427
|
-
params: {
|
|
428
|
-
overrides: {
|
|
429
|
-
builtinPluginName: {
|
|
430
|
-
optionName: 'optionValue'
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
},
|
|
434
|
-
}
|
|
435
|
-
]
|
|
416
|
+
{
|
|
417
|
+
removeComments: (comments) => {
|
|
418
|
+
if (comments.includes('noindex')) return true;
|
|
419
|
+
return false;
|
|
436
420
|
}
|
|
437
|
-
}
|
|
421
|
+
}
|
|
438
422
|
```
|
|
439
423
|
|
|
440
|
-
#### Example
|
|
441
|
-
Source:
|
|
442
424
|
```html
|
|
443
|
-
<
|
|
444
|
-
<rect width="100%" height="100%" fill="red" />
|
|
445
|
-
|
|
446
|
-
<circle cx="150" cy="100" r="80" fill="green" />
|
|
447
|
-
|
|
448
|
-
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
|
|
449
|
-
</svg>`
|
|
425
|
+
<div><!--noindex-->this text will not be indexed<!--/noindex-->Lorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
|
450
426
|
```
|
|
451
427
|
|
|
452
428
|
Minified:
|
|
429
|
+
|
|
453
430
|
```html
|
|
454
|
-
<
|
|
431
|
+
<div>this text will not be indexedLorem ipsum dolor sit amet<!--more-->Lorem ipsum dolor sit amet</div>
|
|
455
432
|
```
|
|
456
433
|
|
|
457
|
-
###
|
|
458
|
-
|
|
459
|
-
Minify content inside conditional comments.
|
|
434
|
+
### removeOptionalTags
|
|
435
|
+
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
|
460
436
|
|
|
461
437
|
#### Example
|
|
462
438
|
|
|
463
439
|
Source:
|
|
464
440
|
|
|
465
441
|
```html
|
|
466
|
-
|
|
467
|
-
<style type="text/css">
|
|
468
|
-
.title {
|
|
469
|
-
color: red;
|
|
470
|
-
}
|
|
471
|
-
</style>
|
|
472
|
-
<![endif]-->
|
|
442
|
+
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
|
473
443
|
```
|
|
474
444
|
|
|
475
445
|
Minified:
|
|
476
446
|
|
|
477
447
|
```html
|
|
478
|
-
|
|
448
|
+
<title>Title</title><p>Hi</p>
|
|
479
449
|
```
|
|
480
450
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
- `method="get"` from `<form>`
|
|
484
|
-
- `type="text"` from `<input>`
|
|
485
|
-
- `type="submit"` from `<button>`
|
|
486
|
-
- `language="javascript"` and `type="text/javascript"` from `<script>`
|
|
487
|
-
- `charset` from `<script>` if it's an external script
|
|
488
|
-
- `media="all"` from `<style>` and `<link>`
|
|
489
|
-
- `type="text/css"` from `<link rel="stylesheet">`
|
|
451
|
+
#### Notice
|
|
452
|
+
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
|
490
453
|
|
|
491
|
-
|
|
492
|
-
|
|
454
|
+
- `html`
|
|
455
|
+
- `head`
|
|
456
|
+
- `body`
|
|
457
|
+
- `colgroup`
|
|
458
|
+
- `tbody`
|
|
493
459
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
```CSS
|
|
497
|
-
form[method="get"] {
|
|
498
|
-
color: red;
|
|
499
|
-
}
|
|
500
|
-
```
|
|
460
|
+
### removeOptionalTags
|
|
461
|
+
Remove certain tags that can be omitted, see [HTML Standard - 13.1.2.4 Optional tags](https://html.spec.whatwg.org/multipage/syntax.html#optional-tags).
|
|
501
462
|
|
|
502
463
|
#### Example
|
|
464
|
+
|
|
503
465
|
Source:
|
|
466
|
+
|
|
504
467
|
```html
|
|
505
|
-
<
|
|
506
|
-
<input type="text">
|
|
507
|
-
</form>
|
|
468
|
+
<html><head><title>Title</title></head><body><p>Hi</p></body></html>
|
|
508
469
|
```
|
|
509
470
|
|
|
510
471
|
Minified:
|
|
472
|
+
|
|
511
473
|
```html
|
|
512
|
-
<
|
|
513
|
-
<input>
|
|
514
|
-
</form>
|
|
474
|
+
<title>Title</title><p>Hi</p>
|
|
515
475
|
```
|
|
516
476
|
|
|
477
|
+
#### Notice
|
|
478
|
+
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
|
517
479
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
to collapse additonal, AMP-specific boolean attributes:
|
|
524
|
-
```Json
|
|
525
|
-
"collapseBooleanAttributes": {
|
|
526
|
-
"amphtml": true
|
|
527
|
-
}
|
|
528
|
-
```
|
|
480
|
+
- `html`
|
|
481
|
+
- `head`
|
|
482
|
+
- `body`
|
|
483
|
+
- `colgroup`
|
|
484
|
+
- `tbody`
|
|
529
485
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
```CSS
|
|
533
|
-
button[disabled="disabled"] {
|
|
534
|
-
color: red;
|
|
535
|
-
}
|
|
536
|
-
```
|
|
486
|
+
### removeAttributeQuotes
|
|
487
|
+
Remove quotes around attributes when possible, see [HTML Standard - 12.1.2.3 Attributes - Unquoted attribute value syntax](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
|
|
537
488
|
|
|
538
489
|
#### Example
|
|
539
490
|
Source:
|
|
540
491
|
```html
|
|
541
|
-
<
|
|
542
|
-
<script defer=""></script>
|
|
492
|
+
<div class="foo" title="hello world"></div>
|
|
543
493
|
```
|
|
544
494
|
|
|
545
495
|
Minified:
|
|
546
496
|
```html
|
|
547
|
-
<
|
|
548
|
-
<script defer></script>
|
|
497
|
+
<div class=foo title="hello world"></div>
|
|
549
498
|
```
|
|
550
499
|
|
|
500
|
+
#### Notice
|
|
501
|
+
The feature is implemented by [posthtml-render's `quoteAllAttributes`](https://github.com/posthtml/posthtml-render#options), which is one of the PostHTML's option. So `removeAttributeQuotes` could be overriden by other PostHTML's plugins and PostHTML's configuration.
|
|
502
|
+
|
|
503
|
+
For example:
|
|
504
|
+
|
|
505
|
+
```js
|
|
506
|
+
posthtml([
|
|
507
|
+
htmlnano({
|
|
508
|
+
removeAttributeQuotes: true
|
|
509
|
+
})
|
|
510
|
+
]).process(html, {
|
|
511
|
+
quoteAllAttributes: true
|
|
512
|
+
})
|
|
513
|
+
```
|
|
551
514
|
|
|
515
|
+
`removeAttributeQuotes` will not work because PostHTML's `quoteAllAttributes` takes the priority.
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
## `<style>`, `<script>` and `<svg>` Tags
|
|
552
519
|
### mergeStyles
|
|
553
520
|
Merges multiple `<style>` with the same `media` and `type` into one tag.
|
|
554
521
|
`<style scoped>...</style>` are skipped.
|
|
@@ -597,242 +564,292 @@ Minified:
|
|
|
597
564
|
```
|
|
598
565
|
|
|
599
566
|
|
|
600
|
-
###
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
567
|
+
### minifyCss
|
|
568
|
+
Minifies CSS with [cssnano](http://cssnano.co/) inside `<style>` tags and `style` attributes.
|
|
569
|
+
|
|
570
|
+
You have to install `cssnano` and `postcss` in order to use this feature:
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
npm install --save-dev cssnano postcss
|
|
574
|
+
# if you prefer yarn
|
|
575
|
+
# yarn add --dev cssnano postcss
|
|
576
|
+
# if you prefer pnpm
|
|
577
|
+
# pnpm install --save-dev cssnano postcss
|
|
610
578
|
```
|
|
611
579
|
|
|
612
|
-
|
|
580
|
+
#### Options
|
|
581
|
+
See [the documentation of cssnano](http://cssnano.co/docs/optimisations/) for all supported optimizations.
|
|
582
|
+
By default CSS is minified with preset `default`, which shouldn't have any side-effects.
|
|
583
|
+
|
|
584
|
+
To use another preset or disabled some optimizations pass options to `minifyCss` module:
|
|
613
585
|
```js
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
586
|
+
htmlnano.process(html, {
|
|
587
|
+
minifyCss: {
|
|
588
|
+
preset: ['default', {
|
|
589
|
+
discardComments: {
|
|
590
|
+
removeAll: true,
|
|
591
|
+
},
|
|
592
|
+
}]
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
```
|
|
620
596
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
597
|
+
#### Example
|
|
598
|
+
Source:
|
|
599
|
+
```html
|
|
600
|
+
<div>
|
|
601
|
+
<style>
|
|
602
|
+
h1 {
|
|
603
|
+
margin: 10px 10px 10px 10px;
|
|
604
|
+
color: #ff0000;
|
|
624
605
|
}
|
|
625
|
-
|
|
626
|
-
|
|
606
|
+
</style>
|
|
607
|
+
</div>
|
|
627
608
|
```
|
|
628
609
|
|
|
629
|
-
|
|
610
|
+
Minified:
|
|
611
|
+
```html
|
|
612
|
+
<div>
|
|
613
|
+
<style>h1{margin:10px;color:red}</style>
|
|
614
|
+
</div>
|
|
615
|
+
```
|
|
630
616
|
|
|
631
|
-
### sortAttributesWithLists
|
|
632
|
-
Sort values in list-like attributes (`class`, `rel`, `ping`).
|
|
633
617
|
|
|
634
|
-
|
|
618
|
+
### minifyJs
|
|
619
|
+
Minifies JS using [Terser](https://github.com/fabiosantoscode/terser) inside `<script>` tags.
|
|
635
620
|
|
|
636
|
-
|
|
621
|
+
You have to install `terser` in order to use this feature:
|
|
637
622
|
|
|
638
|
-
|
|
639
|
-
|
|
623
|
+
```bash
|
|
624
|
+
npm install --save-dev terser
|
|
625
|
+
# if you prefer yarn
|
|
626
|
+
# yarn add --dev terser
|
|
627
|
+
# if you prefer pnpm
|
|
628
|
+
# pnpm install --save-dev terser
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
#### Options
|
|
632
|
+
See [the documentation of Terser](https://github.com/fabiosantoscode/terser#api-reference) for all supported options.
|
|
633
|
+
Terser options can be passed directly to the `minifyJs` module:
|
|
634
|
+
```js
|
|
635
|
+
htmlnano.process(html, {
|
|
636
|
+
minifyJs: {
|
|
637
|
+
output: { quote_style: 1 },
|
|
638
|
+
},
|
|
639
|
+
});
|
|
640
|
+
```
|
|
640
641
|
|
|
641
|
-
#### Example
|
|
642
642
|
|
|
643
|
-
**alphabetical**
|
|
644
643
|
|
|
644
|
+
#### Example
|
|
645
645
|
Source:
|
|
646
646
|
```html
|
|
647
|
-
<div
|
|
647
|
+
<div>
|
|
648
|
+
<script>
|
|
649
|
+
/* comment */
|
|
650
|
+
const foo = function () {
|
|
651
|
+
|
|
652
|
+
};
|
|
653
|
+
</script>
|
|
654
|
+
</div>
|
|
648
655
|
```
|
|
649
656
|
|
|
650
|
-
|
|
657
|
+
Minified:
|
|
651
658
|
```html
|
|
652
|
-
<div
|
|
659
|
+
<div>
|
|
660
|
+
<script>const foo=function(){};</script>
|
|
661
|
+
</div>
|
|
653
662
|
```
|
|
654
663
|
|
|
655
|
-
**frequency**
|
|
656
664
|
|
|
665
|
+
### minifyJson
|
|
666
|
+
Minifies JSON inside `<script type="application/json"></script>`.
|
|
667
|
+
|
|
668
|
+
#### Example
|
|
657
669
|
Source:
|
|
658
670
|
```html
|
|
659
|
-
<
|
|
671
|
+
<script type="application/json">
|
|
672
|
+
{
|
|
673
|
+
"user": "me"
|
|
674
|
+
}
|
|
675
|
+
</script>
|
|
660
676
|
```
|
|
661
677
|
|
|
662
|
-
|
|
678
|
+
Minified:
|
|
663
679
|
```html
|
|
664
|
-
<
|
|
680
|
+
<script type="application/json">{"user":"me"}</script>
|
|
665
681
|
```
|
|
666
682
|
|
|
667
|
-
### sortAttributes
|
|
668
|
-
Sort attributes inside elements.
|
|
669
683
|
|
|
670
|
-
|
|
684
|
+
### minifySvg
|
|
685
|
+
Minifies SVG inside `<svg>` tags using [SVGO](https://github.com/svg/svgo/).
|
|
671
686
|
|
|
672
687
|
#### Options
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
688
|
+
See [the documentation of SVGO](https://github.com/svg/svgo/blob/master/README.md) for all supported options.
|
|
689
|
+
SVGO options can be passed directly to the `minifySvg` module:
|
|
690
|
+
```js
|
|
691
|
+
htmlnano.process(html, {
|
|
692
|
+
minifySvg: {
|
|
693
|
+
plugins: [
|
|
694
|
+
{
|
|
695
|
+
name: 'preset-default',
|
|
696
|
+
params: {
|
|
697
|
+
overrides: {
|
|
698
|
+
builtinPluginName: {
|
|
699
|
+
optionName: 'optionValue'
|
|
700
|
+
},
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
}
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
```
|
|
676
708
|
|
|
677
709
|
#### Example
|
|
678
|
-
|
|
679
|
-
**alphabetical**
|
|
680
|
-
|
|
681
710
|
Source:
|
|
682
711
|
```html
|
|
683
|
-
<
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
Processed:
|
|
687
|
-
```html
|
|
688
|
-
<input autocomplete="off" autofocus="" class="form-control" id="testId" name="testInput" type="text">
|
|
689
|
-
```
|
|
712
|
+
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
|
|
713
|
+
<rect width="100%" height="100%" fill="red" />
|
|
690
714
|
|
|
691
|
-
|
|
715
|
+
<circle cx="150" cy="100" r="80" fill="green" />
|
|
692
716
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
<input type="text" class="form-control" name="testInput" id="testId">
|
|
696
|
-
<a id="testId" href="#" class="testClass"></a>
|
|
697
|
-
<img width="20" src="../images/image.png" height="40" alt="image" class="cls" id="id2">
|
|
717
|
+
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
|
|
718
|
+
</svg>`
|
|
698
719
|
```
|
|
699
720
|
|
|
700
|
-
|
|
721
|
+
Minified:
|
|
701
722
|
```html
|
|
702
|
-
<
|
|
703
|
-
<a class="testClass" id="testId" href="#"></a>
|
|
704
|
-
<img class="cls" id="id2" width="20" src="../images/image.png" height="40" alt="image">
|
|
723
|
+
<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>
|
|
705
724
|
```
|
|
706
725
|
|
|
707
|
-
###
|
|
708
|
-
Convert absolute URL to relative URL using [relateurl](https://www.npmjs.com/package/relateurl).
|
|
726
|
+
### removeUnusedCss
|
|
709
727
|
|
|
710
|
-
|
|
728
|
+
Removes unused CSS inside `<style>` tags with either [uncss](https://github.com/uncss/uncss)
|
|
729
|
+
or [PurgeCSS](https://github.com/FullHuman/purgecss).
|
|
730
|
+
|
|
731
|
+
#### With uncss
|
|
732
|
+
|
|
733
|
+
You have to install `uncss` in order to use this feature:
|
|
711
734
|
|
|
712
735
|
```bash
|
|
713
|
-
npm install --save-dev
|
|
736
|
+
npm install --save-dev uncss
|
|
714
737
|
# if you prefer yarn
|
|
715
|
-
# yarn add --dev
|
|
738
|
+
# yarn add --dev uncss
|
|
716
739
|
# if you prefer pnpm
|
|
717
|
-
# pnpm install --save-dev
|
|
740
|
+
# pnpm install --save-dev uncss
|
|
718
741
|
```
|
|
719
742
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
The base URL to resolve against. Support `String` & `URL`.
|
|
723
|
-
|
|
724
|
-
```js
|
|
725
|
-
htmlnano.process(html, {
|
|
726
|
-
minifyUrls: 'https://example.com' // Valid configuration
|
|
727
|
-
});
|
|
728
|
-
```
|
|
743
|
+
You can also use a mainted fork [@novaatwarren/uncss](https://www.npmjs.com/package/@novaatwarren/uncss) instead.
|
|
729
744
|
|
|
730
|
-
```js
|
|
731
|
-
htmlnano.process(html, {
|
|
732
|
-
minifyUrls: new URL('https://example.com') // Valid configuration
|
|
733
|
-
});
|
|
734
|
-
```
|
|
735
745
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
minifyUrls: false // The module will be disabled
|
|
739
|
-
});
|
|
740
|
-
```
|
|
746
|
+
##### Options
|
|
747
|
+
See [the documentation of uncss](https://github.com/uncss/uncss) for all supported options.
|
|
741
748
|
|
|
749
|
+
uncss options can be passed directly to the `removeUnusedCss` module:
|
|
742
750
|
```js
|
|
743
751
|
htmlnano.process(html, {
|
|
744
|
-
|
|
752
|
+
removeUnusedCss: {
|
|
753
|
+
ignore: ['.do-not-remove']
|
|
754
|
+
}
|
|
745
755
|
});
|
|
746
756
|
```
|
|
747
757
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
**Basic Usage**
|
|
751
|
-
|
|
752
|
-
Configuration:
|
|
758
|
+
The following uncss options are ignored if passed to the module:
|
|
753
759
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
});
|
|
758
|
-
```
|
|
760
|
+
- `stylesheets`
|
|
761
|
+
- `ignoreSheets`
|
|
762
|
+
- `raw`
|
|
759
763
|
|
|
760
|
-
|
|
764
|
+
#### With PurgeCSS
|
|
761
765
|
|
|
762
|
-
|
|
763
|
-
<a href="https://example.com/foo/bar/baz">bar</a>
|
|
764
|
-
```
|
|
766
|
+
Use PurgeCSS instead of uncss by adding `tool: 'purgeCSS'` to the options.
|
|
765
767
|
|
|
766
|
-
|
|
768
|
+
You have to install `purgecss` in order to use this feature:
|
|
767
769
|
|
|
768
|
-
```
|
|
769
|
-
|
|
770
|
+
```bash
|
|
771
|
+
npm install --save-dev purgecss
|
|
772
|
+
# if you prefer yarn
|
|
773
|
+
# yarn add --dev purgecss
|
|
774
|
+
# if you prefer pnpm
|
|
775
|
+
# pnpm install --save-dev purgecss
|
|
770
776
|
```
|
|
771
777
|
|
|
772
|
-
|
|
778
|
+
##### Options
|
|
773
779
|
|
|
774
|
-
|
|
780
|
+
See [the documentation of PurgeCSS](https://www.purgecss.com) for all supported options.
|
|
775
781
|
|
|
782
|
+
PurgeCSS options can be passed directly to the `removeUnusedCss` module:
|
|
776
783
|
```js
|
|
777
784
|
htmlnano.process(html, {
|
|
778
|
-
|
|
785
|
+
removeUnusedCss: {
|
|
786
|
+
tool: 'purgeCSS',
|
|
787
|
+
safelist: ['.do-not-remove']
|
|
788
|
+
}
|
|
779
789
|
});
|
|
780
790
|
```
|
|
781
791
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
```html
|
|
785
|
-
<a href="https://example.com/foo/bar">bar</a>
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
Minified:
|
|
789
|
-
|
|
790
|
-
```html
|
|
791
|
-
<a href="../bar">bar</a>
|
|
792
|
-
```
|
|
792
|
+
The following PurgeCSS options are ignored if passed to the module:
|
|
793
793
|
|
|
794
|
-
|
|
795
|
-
|
|
794
|
+
- `content`
|
|
795
|
+
- `css`
|
|
796
|
+
- `extractors`
|
|
796
797
|
|
|
797
798
|
#### Example
|
|
798
|
-
|
|
799
799
|
Source:
|
|
800
|
-
|
|
801
800
|
```html
|
|
802
|
-
<
|
|
801
|
+
<div class="b">
|
|
802
|
+
<style>
|
|
803
|
+
.a {
|
|
804
|
+
margin: 10px 10px 10px 10px;
|
|
805
|
+
}
|
|
806
|
+
.b {
|
|
807
|
+
color: #ff0000;
|
|
808
|
+
}
|
|
809
|
+
</style>
|
|
810
|
+
</div>
|
|
803
811
|
```
|
|
804
812
|
|
|
805
|
-
|
|
806
|
-
|
|
813
|
+
Optimized:
|
|
807
814
|
```html
|
|
808
|
-
<
|
|
815
|
+
<div class="b">
|
|
816
|
+
<style>
|
|
817
|
+
.b {
|
|
818
|
+
color: #ff0000;
|
|
819
|
+
}
|
|
820
|
+
</style>
|
|
821
|
+
</div>
|
|
809
822
|
```
|
|
810
823
|
|
|
811
|
-
|
|
812
|
-
Due to [the limitation of PostHTML](https://github.com/posthtml/htmlnano/issues/99), htmlnano can't remove only the start tag or the end tag of an element. Currently, htmlnano only supports removing the following optional tags, as htmlnano can remove their start tag and end tag at the same time:
|
|
813
|
-
|
|
814
|
-
- `html`
|
|
815
|
-
- `head`
|
|
816
|
-
- `body`
|
|
817
|
-
- `colgroup`
|
|
818
|
-
- `tbody`
|
|
819
|
-
|
|
820
|
-
### normalizeAttributeValues
|
|
821
|
-
|
|
822
|
-
Normalize casing of attribute values.
|
|
823
|
-
|
|
824
|
-
The module won't impact the plain-text size of the output. However it will improve the compression ratio of gzip/brotli used in HTTP compression.
|
|
825
|
-
|
|
826
|
-
#### Example
|
|
827
|
-
|
|
828
|
-
Source:
|
|
824
|
+
## Miscellaneous
|
|
829
825
|
|
|
830
|
-
|
|
831
|
-
|
|
826
|
+
### custom
|
|
827
|
+
It's also possible to pass custom modules in the minifier.
|
|
828
|
+
As a function:
|
|
829
|
+
```js
|
|
830
|
+
const options = {
|
|
831
|
+
custom: function (tree, options) {
|
|
832
|
+
// Some minification
|
|
833
|
+
return tree;
|
|
834
|
+
}
|
|
835
|
+
};
|
|
832
836
|
```
|
|
833
837
|
|
|
834
|
-
|
|
838
|
+
Or as a list of functions:
|
|
839
|
+
```js
|
|
840
|
+
const options = {
|
|
841
|
+
custom: [
|
|
842
|
+
function (tree, options) {
|
|
843
|
+
// Some minification
|
|
844
|
+
return tree;
|
|
845
|
+
},
|
|
835
846
|
|
|
836
|
-
|
|
837
|
-
|
|
847
|
+
function (tree, options) {
|
|
848
|
+
// Some other minification
|
|
849
|
+
return tree;
|
|
850
|
+
}
|
|
851
|
+
]
|
|
852
|
+
};
|
|
838
853
|
```
|
|
854
|
+
|
|
855
|
+
htmlnano's options are passed to your custom plugin by the second parameter `options`.
|