html-minifier-next 4.2.0 → 4.3.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/README.md +20 -19
- package/cli.js +12 -11
- package/dist/htmlminifier.cjs +30 -4
- package/dist/htmlminifier.esm.bundle.js +30 -4
- package/dist/types/htmlminifier.d.ts +8 -0
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/htmlminifier.js +30 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
HTML Minifier Next (HMN) is a highly **configurable, well-tested, JavaScript-based HTML minifier**.
|
|
6
6
|
|
|
7
|
-
The project
|
|
7
|
+
The project was based on [HTML Minifier Terser](https://github.com/terser/html-minifier-terser), which in turn had been based on [Juriy Zaytsev’s HTML Minifier](https://github.com/kangax/html-minifier). HMN offers additional features, but is backwards-compatible with both. The project was set up because as of 2025, both HTML Minifier Terser and HTML Minifier had been unmaintained for a few years. As the project seems maintainable [to me, [Jens](https://meiert.com/)]—even more so with community support—, it’s being [updated, extended, and documented](https://github.com/j9t/html-minifier-next/blob/main/CHANGELOG.md) further in this place.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -114,6 +114,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
|
|
|
114
114
|
| `collapseInlineTagWhitespace`<br>`--collapse-inline-tag-whitespace` | Don’t leave any spaces between `display: inline;` elements when collapsing—use with `collapseWhitespace: true` | `false` |
|
|
115
115
|
| `collapseWhitespace`<br>`--collapse-whitespace` | [Collapse whitespace that contributes to text nodes in a document tree](https://perfectionkills.com/experimenting-with-html-minifier#collapse_whitespace) | `false` |
|
|
116
116
|
| `conservativeCollapse`<br>`--conservative-collapse` | Always collapse to 1 space (never remove it entirely)—use with `collapseWhitespace: true` | `false` |
|
|
117
|
+
| `continueOnMinifyError`<br>`--no-continue-on-minify-error` | Continue on minification errors; when `false`, minification errors throw and abort processing | `true` |
|
|
117
118
|
| `continueOnParseError`<br>`--continue-on-parse-error` | [Handle parse errors](https://html.spec.whatwg.org/multipage/parsing.html#parse-errors) instead of aborting | `false` |
|
|
118
119
|
| `customAttrAssign`<br>`--custom-attr-assign` | Arrays of regexes that allow to support custom attribute assign expressions (e.g., `<div flex?="{{mode != cover}}"></div>`) | `[]` |
|
|
119
120
|
| `customAttrCollapse`<br>`--custom-attr-collapse` | Regex that specifies custom attribute to strip newlines from (e.g., `/ng-class/`) | |
|
|
@@ -178,10 +179,10 @@ const result = await minify(html, {
|
|
|
178
179
|
|
|
179
180
|
Available Lightning CSS options when passed as an object:
|
|
180
181
|
|
|
181
|
-
* `targets`: Browser targets for vendor prefix optimization (e.g., `{ chrome: 95, firefox: 90 }`)
|
|
182
|
-
* `unusedSymbols`: Array of class names, IDs, keyframe names, and CSS variables to remove
|
|
183
|
-
* `errorRecovery`: Boolean to skip invalid rules instead of throwing errors
|
|
184
|
-
* `sourceMap`: Boolean to generate source maps
|
|
182
|
+
* `targets`: Browser targets for vendor prefix optimization (e.g., `{ chrome: 95, firefox: 90 }`).
|
|
183
|
+
* `unusedSymbols`: Array of class names, IDs, keyframe names, and CSS variables to remove.
|
|
184
|
+
* `errorRecovery`: Boolean to skip invalid rules instead of throwing errors. This is disabled by default in Lightning CSS, but enabled in HMN when the `continueOnMinifyError` option is set to `true` (the default). Explicitly setting `errorRecovery` in `minifyCSS` options will override this automatic behavior.
|
|
185
|
+
* `sourceMap`: Boolean to generate source maps.
|
|
185
186
|
|
|
186
187
|
For advanced usage, you can also pass a function:
|
|
187
188
|
|
|
@@ -202,23 +203,23 @@ How does HTML Minifier Next compare to other solutions, like [minimize](https://
|
|
|
202
203
|
| Site | Original Size (KB) | HTML Minifier Next | minimize | htmlcompressor.com | htmlnano | minify-html |
|
|
203
204
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
204
205
|
| [A List Apart](https://alistapart.com/) | 62 | **52** | 58 | 56 | 54 | 55 |
|
|
205
|
-
| [Amazon](https://www.amazon.com/) |
|
|
206
|
-
| [Apple](https://www.apple.com/) |
|
|
207
|
-
| [BBC](https://www.bbc.co.uk/) |
|
|
208
|
-
| [CSS-Tricks](https://css-tricks.com/) |
|
|
209
|
-
| [ECMAScript](https://tc39.es/ecma262/) | 7238 | **6342** |
|
|
210
|
-
| [EFF](https://www.eff.org/) |
|
|
211
|
-
| [FAZ](https://www.faz.net/aktuell/) |
|
|
212
|
-
| [Frontend Dogma](https://frontenddogma.com/) |
|
|
213
|
-
| [Google](https://www.google.com/) | 18 | **
|
|
214
|
-
| [Ground News](https://ground.news/) |
|
|
206
|
+
| [Amazon](https://www.amazon.com/) | 822 | **735** | 806 | n/a | n/a | n/a |
|
|
207
|
+
| [Apple](https://www.apple.com/) | 210 | **166** | 195 | 192 | 186 | 191 |
|
|
208
|
+
| [BBC](https://www.bbc.co.uk/) | 698 | **632** | 692 | n/a | 655 | 656 |
|
|
209
|
+
| [CSS-Tricks](https://css-tricks.com/) | 163 | **124** | 149 | 146 | 127 | 145 |
|
|
210
|
+
| [ECMAScript](https://tc39.es/ecma262/) | 7238 | **6342** | 6615 | n/a | 6561 | 6567 |
|
|
211
|
+
| [EFF](https://www.eff.org/) | 54 | **46** | 49 | 49 | 49 | 47 |
|
|
212
|
+
| [FAZ](https://www.faz.net/aktuell/) | 1860 | **1737** | 1775 | n/a | n/a | 1779 |
|
|
213
|
+
| [Frontend Dogma](https://frontenddogma.com/) | 218 | **209** | 235 | 216 | 230 | 217 |
|
|
214
|
+
| [Google](https://www.google.com/) | 18 | **17** | 18 | 18 | **17** | n/a |
|
|
215
|
+
| [Ground News](https://ground.news/) | 1827 | **1585** | 1814 | n/a | 1679 | n/a |
|
|
215
216
|
| [HTML](https://html.spec.whatwg.org/multipage/) | 149 | **147** | 155 | 148 | 153 | 149 |
|
|
216
|
-
| [Leanpub](https://leanpub.com/) |
|
|
217
|
+
| [Leanpub](https://leanpub.com/) | 1161 | **974** | 1155 | n/a | 981 | n/a |
|
|
217
218
|
| [Mastodon](https://mastodon.social/explore) | 35 | **26** | 34 | 34 | 30 | 33 |
|
|
218
219
|
| [MDN](https://developer.mozilla.org/en-US/) | 107 | **62** | 67 | 68 | 64 | n/a |
|
|
219
|
-
| [Middle East Eye](https://www.middleeasteye.net/) |
|
|
220
|
-
| [SitePoint](https://www.sitepoint.com/) |
|
|
221
|
-
| [United Nations](https://www.un.org/en/) |
|
|
220
|
+
| [Middle East Eye](https://www.middleeasteye.net/) | 223 | **196** | 203 | 203 | 203 | 200 |
|
|
221
|
+
| [SitePoint](https://www.sitepoint.com/) | 494 | **353** | 491 | n/a | 429 | 474 |
|
|
222
|
+
| [United Nations](https://www.un.org/en/) | 152 | **113** | 131 | 124 | 122 | 126 |
|
|
222
223
|
| [W3C](https://www.w3.org/) | 50 | **36** | 41 | 39 | 39 | 39 |
|
|
223
224
|
|
|
224
225
|
## Examples
|
package/cli.js
CHANGED
|
@@ -121,6 +121,7 @@ const mainOptions = {
|
|
|
121
121
|
collapseInlineTagWhitespace: 'Don’t leave any spaces between “display: inline;” elements when collapsing—use with “collapseWhitespace=true”',
|
|
122
122
|
collapseWhitespace: 'Collapse whitespace that contributes to text nodes in a document tree',
|
|
123
123
|
conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)—use with “collapseWhitespace=true”',
|
|
124
|
+
continueOnMinifyError: 'Continue on minification errors',
|
|
124
125
|
continueOnParseError: 'Handle parse errors instead of aborting',
|
|
125
126
|
customAttrAssign: ['Arrays of regexes that allow to support custom attribute assign expressions (e.g., “<div flex?="{{mode != cover}}"></div>”)', parseJSONRegExpArray],
|
|
126
127
|
customAttrCollapse: ['Regex that specifies custom attribute to strip newlines from (e.g., /ng-class/)', parseRegExp],
|
|
@@ -167,7 +168,7 @@ mainOptionKeys.forEach(function (key) {
|
|
|
167
168
|
key = key === 'minifyURLs' ? '--minify-urls' : '--' + paramCase(key);
|
|
168
169
|
key += option[1] === parseJSON ? ' [value]' : ' <value>';
|
|
169
170
|
program.option(key, option[0], option[1]);
|
|
170
|
-
} else if (~['html5', 'includeAutoGeneratedTags'].indexOf(key)) {
|
|
171
|
+
} else if (~['html5', 'includeAutoGeneratedTags', 'continueOnMinifyError'].indexOf(key)) {
|
|
171
172
|
program.option('--no-' + paramCase(key), option);
|
|
172
173
|
} else {
|
|
173
174
|
program.option('--' + paramCase(key), option);
|
|
@@ -180,8 +181,8 @@ program.option('-d --dry', 'Dry run: process and report statistics without writi
|
|
|
180
181
|
function readFile(file) {
|
|
181
182
|
try {
|
|
182
183
|
return fs.readFileSync(file, { encoding: 'utf8' });
|
|
183
|
-
} catch (
|
|
184
|
-
fatal('Cannot read ' + file + '\n' +
|
|
184
|
+
} catch (err) {
|
|
185
|
+
fatal('Cannot read ' + file + '\n' + err.message);
|
|
185
186
|
}
|
|
186
187
|
}
|
|
187
188
|
|
|
@@ -196,7 +197,7 @@ async function loadConfigFromPath(configPath) {
|
|
|
196
197
|
// Try JSON first
|
|
197
198
|
try {
|
|
198
199
|
return JSON.parse(data);
|
|
199
|
-
} catch (
|
|
200
|
+
} catch (jsonErr) {
|
|
200
201
|
const abs = path.resolve(configPath);
|
|
201
202
|
|
|
202
203
|
// Try CJS require
|
|
@@ -204,13 +205,13 @@ async function loadConfigFromPath(configPath) {
|
|
|
204
205
|
const result = require(abs);
|
|
205
206
|
// Handle ESM interop: if `require()` loads an ESM file, it may return `{__esModule: true, default: …}`
|
|
206
207
|
return (result && result.__esModule && result.default) ? result.default : result;
|
|
207
|
-
} catch (
|
|
208
|
+
} catch (cjsErr) {
|
|
208
209
|
// Try ESM import
|
|
209
210
|
try {
|
|
210
211
|
const mod = await import(pathToFileURL(abs).href);
|
|
211
212
|
return mod.default || mod;
|
|
212
|
-
} catch (
|
|
213
|
-
fatal('Cannot read the specified config file.\nAs JSON: ' +
|
|
213
|
+
} catch (esmErr) {
|
|
214
|
+
fatal('Cannot read the specified config file.\nAs JSON: ' + jsonErr.message + '\nAs CJS: ' + cjsErr.message + '\nAs ESM: ' + esmErr.message);
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
}
|
|
@@ -307,8 +308,8 @@ program.option('--file-ext <extensions>', 'Specify file extension(s) to process
|
|
|
307
308
|
let minified;
|
|
308
309
|
try {
|
|
309
310
|
minified = await minify(data, createOptions());
|
|
310
|
-
} catch (
|
|
311
|
-
fatal('Minification error on ' + inputFile + '\n' +
|
|
311
|
+
} catch (err) {
|
|
312
|
+
fatal('Minification error on ' + inputFile + '\n' + err.message);
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
const stats = calculateStats(data, minified);
|
|
@@ -466,8 +467,8 @@ program.option('--file-ext <extensions>', 'Specify file extension(s) to process
|
|
|
466
467
|
|
|
467
468
|
try {
|
|
468
469
|
minified = await minify(content, minifierOptions);
|
|
469
|
-
} catch (
|
|
470
|
-
fatal('Minification error:\n' +
|
|
470
|
+
} catch (err) {
|
|
471
|
+
fatal('Minification error:\n' + err.message);
|
|
471
472
|
}
|
|
472
473
|
|
|
473
474
|
const stats = calculateStats(content, minified);
|
package/dist/htmlminifier.cjs
CHANGED
|
@@ -835,6 +835,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
835
835
|
const out = await options.minifyURLs(attrValue);
|
|
836
836
|
return typeof out === 'string' ? out : attrValue;
|
|
837
837
|
} catch (err) {
|
|
838
|
+
if (!options.continueOnMinifyError) {
|
|
839
|
+
throw err;
|
|
840
|
+
}
|
|
838
841
|
options.log && options.log(err);
|
|
839
842
|
return attrValue;
|
|
840
843
|
}
|
|
@@ -867,6 +870,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
867
870
|
const out = await options.minifyURLs(url);
|
|
868
871
|
return (typeof out === 'string' ? out : url) + descriptor;
|
|
869
872
|
} catch (err) {
|
|
873
|
+
if (!options.continueOnMinifyError) {
|
|
874
|
+
throw err;
|
|
875
|
+
}
|
|
870
876
|
options.log && options.log(err);
|
|
871
877
|
return url + descriptor;
|
|
872
878
|
}
|
|
@@ -1221,6 +1227,7 @@ const processOptions = (inputOptions) => {
|
|
|
1221
1227
|
},
|
|
1222
1228
|
canCollapseWhitespace,
|
|
1223
1229
|
canTrimWhitespace,
|
|
1230
|
+
continueOnMinifyError: true,
|
|
1224
1231
|
html5: true,
|
|
1225
1232
|
ignoreCustomComments: [
|
|
1226
1233
|
/^!/,
|
|
@@ -1266,6 +1273,9 @@ const processOptions = (inputOptions) => {
|
|
|
1266
1273
|
const out = await options.minifyURLs(url);
|
|
1267
1274
|
return prefix + quote + (typeof out === 'string' ? out : url) + quote + suffix;
|
|
1268
1275
|
} catch (err) {
|
|
1276
|
+
if (!options.continueOnMinifyError) {
|
|
1277
|
+
throw err;
|
|
1278
|
+
}
|
|
1269
1279
|
options.log && options.log(err);
|
|
1270
1280
|
return match;
|
|
1271
1281
|
}
|
|
@@ -1279,7 +1289,7 @@ const processOptions = (inputOptions) => {
|
|
|
1279
1289
|
filename: 'input.css',
|
|
1280
1290
|
code: Buffer.from(inputCSS),
|
|
1281
1291
|
minify: true,
|
|
1282
|
-
errorRecovery:
|
|
1292
|
+
errorRecovery: !!options.continueOnMinifyError,
|
|
1283
1293
|
...lightningCssOptions
|
|
1284
1294
|
});
|
|
1285
1295
|
|
|
@@ -1303,6 +1313,9 @@ const processOptions = (inputOptions) => {
|
|
|
1303
1313
|
|
|
1304
1314
|
return outputCSS;
|
|
1305
1315
|
} catch (err) {
|
|
1316
|
+
if (!options.continueOnMinifyError) {
|
|
1317
|
+
throw err;
|
|
1318
|
+
}
|
|
1306
1319
|
options.log && options.log(err);
|
|
1307
1320
|
return text;
|
|
1308
1321
|
}
|
|
@@ -1328,8 +1341,11 @@ const processOptions = (inputOptions) => {
|
|
|
1328
1341
|
try {
|
|
1329
1342
|
const result = await terser.minify(code, terserOptions);
|
|
1330
1343
|
return result.code.replace(/;$/, '');
|
|
1331
|
-
} catch (
|
|
1332
|
-
options.
|
|
1344
|
+
} catch (err) {
|
|
1345
|
+
if (!options.continueOnMinifyError) {
|
|
1346
|
+
throw err;
|
|
1347
|
+
}
|
|
1348
|
+
options.log && options.log(err);
|
|
1333
1349
|
return text;
|
|
1334
1350
|
}
|
|
1335
1351
|
};
|
|
@@ -1350,7 +1366,10 @@ const processOptions = (inputOptions) => {
|
|
|
1350
1366
|
try {
|
|
1351
1367
|
return RelateURL.relate(text, relateUrlOptions);
|
|
1352
1368
|
} catch (err) {
|
|
1353
|
-
options.
|
|
1369
|
+
if (!options.continueOnMinifyError) {
|
|
1370
|
+
throw err;
|
|
1371
|
+
}
|
|
1372
|
+
options.log && options.log(err);
|
|
1354
1373
|
return text;
|
|
1355
1374
|
}
|
|
1356
1375
|
};
|
|
@@ -2061,6 +2080,13 @@ var htmlminifier = { minify };
|
|
|
2061
2080
|
*
|
|
2062
2081
|
* Default: `false`
|
|
2063
2082
|
*
|
|
2083
|
+
* @prop {boolean} [continueOnMinifyError]
|
|
2084
|
+
* When set to `false`, minification errors may throw.
|
|
2085
|
+
* By default, the minifier will attempt to recover from minification
|
|
2086
|
+
* errors, or ignore them and preserve the original content.
|
|
2087
|
+
*
|
|
2088
|
+
* Default: `true`
|
|
2089
|
+
*
|
|
2064
2090
|
* @prop {boolean} [continueOnParseError]
|
|
2065
2091
|
* When true, the parser will attempt to continue on recoverable parse
|
|
2066
2092
|
* errors. Otherwise, parsing errors may throw.
|
|
@@ -39888,6 +39888,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
39888
39888
|
const out = await options.minifyURLs(attrValue);
|
|
39889
39889
|
return typeof out === 'string' ? out : attrValue;
|
|
39890
39890
|
} catch (err) {
|
|
39891
|
+
if (!options.continueOnMinifyError) {
|
|
39892
|
+
throw err;
|
|
39893
|
+
}
|
|
39891
39894
|
options.log && options.log(err);
|
|
39892
39895
|
return attrValue;
|
|
39893
39896
|
}
|
|
@@ -39920,6 +39923,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
39920
39923
|
const out = await options.minifyURLs(url);
|
|
39921
39924
|
return (typeof out === 'string' ? out : url) + descriptor;
|
|
39922
39925
|
} catch (err) {
|
|
39926
|
+
if (!options.continueOnMinifyError) {
|
|
39927
|
+
throw err;
|
|
39928
|
+
}
|
|
39923
39929
|
options.log && options.log(err);
|
|
39924
39930
|
return url + descriptor;
|
|
39925
39931
|
}
|
|
@@ -40274,6 +40280,7 @@ const processOptions = (inputOptions) => {
|
|
|
40274
40280
|
},
|
|
40275
40281
|
canCollapseWhitespace,
|
|
40276
40282
|
canTrimWhitespace,
|
|
40283
|
+
continueOnMinifyError: true,
|
|
40277
40284
|
html5: true,
|
|
40278
40285
|
ignoreCustomComments: [
|
|
40279
40286
|
/^!/,
|
|
@@ -40319,6 +40326,9 @@ const processOptions = (inputOptions) => {
|
|
|
40319
40326
|
const out = await options.minifyURLs(url);
|
|
40320
40327
|
return prefix + quote + (typeof out === 'string' ? out : url) + quote + suffix;
|
|
40321
40328
|
} catch (err) {
|
|
40329
|
+
if (!options.continueOnMinifyError) {
|
|
40330
|
+
throw err;
|
|
40331
|
+
}
|
|
40322
40332
|
options.log && options.log(err);
|
|
40323
40333
|
return match;
|
|
40324
40334
|
}
|
|
@@ -40332,7 +40342,7 @@ const processOptions = (inputOptions) => {
|
|
|
40332
40342
|
filename: 'input.css',
|
|
40333
40343
|
code: Buffer.from(inputCSS),
|
|
40334
40344
|
minify: true,
|
|
40335
|
-
errorRecovery:
|
|
40345
|
+
errorRecovery: !!options.continueOnMinifyError,
|
|
40336
40346
|
...lightningCssOptions
|
|
40337
40347
|
});
|
|
40338
40348
|
|
|
@@ -40356,6 +40366,9 @@ const processOptions = (inputOptions) => {
|
|
|
40356
40366
|
|
|
40357
40367
|
return outputCSS;
|
|
40358
40368
|
} catch (err) {
|
|
40369
|
+
if (!options.continueOnMinifyError) {
|
|
40370
|
+
throw err;
|
|
40371
|
+
}
|
|
40359
40372
|
options.log && options.log(err);
|
|
40360
40373
|
return text;
|
|
40361
40374
|
}
|
|
@@ -40381,8 +40394,11 @@ const processOptions = (inputOptions) => {
|
|
|
40381
40394
|
try {
|
|
40382
40395
|
const result = await minify$1(code, terserOptions);
|
|
40383
40396
|
return result.code.replace(/;$/, '');
|
|
40384
|
-
} catch (
|
|
40385
|
-
options.
|
|
40397
|
+
} catch (err) {
|
|
40398
|
+
if (!options.continueOnMinifyError) {
|
|
40399
|
+
throw err;
|
|
40400
|
+
}
|
|
40401
|
+
options.log && options.log(err);
|
|
40386
40402
|
return text;
|
|
40387
40403
|
}
|
|
40388
40404
|
};
|
|
@@ -40403,7 +40419,10 @@ const processOptions = (inputOptions) => {
|
|
|
40403
40419
|
try {
|
|
40404
40420
|
return RelateURL.relate(text, relateUrlOptions);
|
|
40405
40421
|
} catch (err) {
|
|
40406
|
-
options.
|
|
40422
|
+
if (!options.continueOnMinifyError) {
|
|
40423
|
+
throw err;
|
|
40424
|
+
}
|
|
40425
|
+
options.log && options.log(err);
|
|
40407
40426
|
return text;
|
|
40408
40427
|
}
|
|
40409
40428
|
};
|
|
@@ -41114,6 +41133,13 @@ var htmlminifier = { minify };
|
|
|
41114
41133
|
*
|
|
41115
41134
|
* Default: `false`
|
|
41116
41135
|
*
|
|
41136
|
+
* @prop {boolean} [continueOnMinifyError]
|
|
41137
|
+
* When set to `false`, minification errors may throw.
|
|
41138
|
+
* By default, the minifier will attempt to recover from minification
|
|
41139
|
+
* errors, or ignore them and preserve the original content.
|
|
41140
|
+
*
|
|
41141
|
+
* Default: `true`
|
|
41142
|
+
*
|
|
41117
41143
|
* @prop {boolean} [continueOnParseError]
|
|
41118
41144
|
* When true, the parser will attempt to continue on recoverable parse
|
|
41119
41145
|
* errors. Otherwise, parsing errors may throw.
|
|
@@ -73,6 +73,14 @@ export type MinifierOptions = {
|
|
|
73
73
|
* Default: `false`
|
|
74
74
|
*/
|
|
75
75
|
conservativeCollapse?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* When set to `false`, minification errors may throw.
|
|
78
|
+
* By default, the minifier will attempt to recover from minification
|
|
79
|
+
* errors, or ignore them and preserve the original content.
|
|
80
|
+
*
|
|
81
|
+
* Default: `true`
|
|
82
|
+
*/
|
|
83
|
+
continueOnMinifyError?: boolean;
|
|
76
84
|
/**
|
|
77
85
|
* When true, the parser will attempt to continue on recoverable parse
|
|
78
86
|
* errors. Otherwise, parsing errors may throw.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"AAs8CO,8BAJI,MAAM,YACN,eAAe,GACb,OAAO,CAAC,MAAM,CAAC,CAQ3B;;;;;;;;;UAQS,MAAM;YACN,MAAM;YACN,MAAM;mBACN,MAAM;iBACN,MAAM;kBACN,MAAM;;;;;;;;;;;;;4BAQN,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,qBAAqB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;wBAMjG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;;oBAMhH,OAAO;;;;;;;;gCAOP,OAAO;;;;;;;;kCAOP,OAAO;;;;;;;;yBAOP,OAAO;;;;;;;;2BAOP,OAAO;;;;;;;;4BAOP,OAAO;;;;;;;2BAOP,OAAO;;;;;;;;uBAMP,MAAM,EAAE;;;;;;yBAOR,MAAM;;;;;;yBAKN,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;;;;;;;4BAKlB,MAAM,EAAE;;;;;;;oCAMR,MAAM;;;;;;;qBAMN,OAAO;;;;;;;YAMP,OAAO;;;;;;;;2BAMP,MAAM,EAAE;;;;;;;;;4BAOR,MAAM,EAAE;;;;;;;+BAQR,OAAO;;;;;;;2BAMP,SAAS,CAAC,MAAM,CAAC;;;;;;uBAMjB,OAAO;;;;;;;;UAKP,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI;;;;;;;;qBAO1B,MAAM;;;;;;;oBAON,MAAM;;;;;;;;;;gBAMN,OAAO,GAAG,OAAO,CAAC,OAAO,cAAc,EAAE,gBAAgB,CAAC,OAAO,cAAc,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;;;;;;;;;;eAS9J,OAAO,GAAG,OAAO,QAAQ,EAAE,aAAa,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;;;;;;;;;;iBASzG,OAAO,GAAG,MAAM,GAAG,OAAO,WAAW,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;;;;;;;;WAS7F,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;;;;;;;+BAOxB,OAAO;;;;;;;;yBAMP,OAAO;;;;;;;gCAOP,OAAO;;;;;;;;iCAMP,OAAO;;;;;;;;;;qBAOP,MAAM,EAAE;;;;;;;qBASR,IAAI,GAAG,GAAG;;;;;;;4BAMV,OAAO;;;;;;;;qBAMP,OAAO;;;;;;;;;4BAOP,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;;;;;;;;0BAQtD,OAAO;;;;;;;;yBAOP,OAAO;;;;;;;;gCAOP,OAAO;;;;;;;iCAOP,OAAO;;;;;;;oCAMP,OAAO;;;;;;;;;;0BAMP,OAAO;;;;;;;;;qBASP,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;;;;;;;;;oBAQzD,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;;;;;;;;0BAQrC,OAAO;;;;;;;sBAOP,OAAO"}
|
package/package.json
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
23
23
|
"@rollup/plugin-terser": "^0.4.4",
|
|
24
24
|
"eslint": "^9.39.1",
|
|
25
|
-
"rollup": "^4.
|
|
25
|
+
"rollup": "^4.53.2",
|
|
26
26
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
27
27
|
"typescript": "^5.9.3",
|
|
28
|
-
"vite": "^7.
|
|
28
|
+
"vite": "^7.2.2"
|
|
29
29
|
},
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"test:watch": "node --test --watch tests/*.spec.js"
|
|
85
85
|
},
|
|
86
86
|
"type": "module",
|
|
87
|
-
"version": "4.
|
|
87
|
+
"version": "4.3.0"
|
|
88
88
|
}
|
package/src/htmlminifier.js
CHANGED
|
@@ -305,6 +305,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
305
305
|
const out = await options.minifyURLs(attrValue);
|
|
306
306
|
return typeof out === 'string' ? out : attrValue;
|
|
307
307
|
} catch (err) {
|
|
308
|
+
if (!options.continueOnMinifyError) {
|
|
309
|
+
throw err;
|
|
310
|
+
}
|
|
308
311
|
options.log && options.log(err);
|
|
309
312
|
return attrValue;
|
|
310
313
|
}
|
|
@@ -337,6 +340,9 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, min
|
|
|
337
340
|
const out = await options.minifyURLs(url);
|
|
338
341
|
return (typeof out === 'string' ? out : url) + descriptor;
|
|
339
342
|
} catch (err) {
|
|
343
|
+
if (!options.continueOnMinifyError) {
|
|
344
|
+
throw err;
|
|
345
|
+
}
|
|
340
346
|
options.log && options.log(err);
|
|
341
347
|
return url + descriptor;
|
|
342
348
|
}
|
|
@@ -691,6 +697,7 @@ const processOptions = (inputOptions) => {
|
|
|
691
697
|
},
|
|
692
698
|
canCollapseWhitespace,
|
|
693
699
|
canTrimWhitespace,
|
|
700
|
+
continueOnMinifyError: true,
|
|
694
701
|
html5: true,
|
|
695
702
|
ignoreCustomComments: [
|
|
696
703
|
/^!/,
|
|
@@ -736,6 +743,9 @@ const processOptions = (inputOptions) => {
|
|
|
736
743
|
const out = await options.minifyURLs(url);
|
|
737
744
|
return prefix + quote + (typeof out === 'string' ? out : url) + quote + suffix;
|
|
738
745
|
} catch (err) {
|
|
746
|
+
if (!options.continueOnMinifyError) {
|
|
747
|
+
throw err;
|
|
748
|
+
}
|
|
739
749
|
options.log && options.log(err);
|
|
740
750
|
return match;
|
|
741
751
|
}
|
|
@@ -749,7 +759,7 @@ const processOptions = (inputOptions) => {
|
|
|
749
759
|
filename: 'input.css',
|
|
750
760
|
code: Buffer.from(inputCSS),
|
|
751
761
|
minify: true,
|
|
752
|
-
errorRecovery:
|
|
762
|
+
errorRecovery: !!options.continueOnMinifyError,
|
|
753
763
|
...lightningCssOptions
|
|
754
764
|
});
|
|
755
765
|
|
|
@@ -773,6 +783,9 @@ const processOptions = (inputOptions) => {
|
|
|
773
783
|
|
|
774
784
|
return outputCSS;
|
|
775
785
|
} catch (err) {
|
|
786
|
+
if (!options.continueOnMinifyError) {
|
|
787
|
+
throw err;
|
|
788
|
+
}
|
|
776
789
|
options.log && options.log(err);
|
|
777
790
|
return text;
|
|
778
791
|
}
|
|
@@ -798,8 +811,11 @@ const processOptions = (inputOptions) => {
|
|
|
798
811
|
try {
|
|
799
812
|
const result = await terser(code, terserOptions);
|
|
800
813
|
return result.code.replace(/;$/, '');
|
|
801
|
-
} catch (
|
|
802
|
-
options.
|
|
814
|
+
} catch (err) {
|
|
815
|
+
if (!options.continueOnMinifyError) {
|
|
816
|
+
throw err;
|
|
817
|
+
}
|
|
818
|
+
options.log && options.log(err);
|
|
803
819
|
return text;
|
|
804
820
|
}
|
|
805
821
|
};
|
|
@@ -820,7 +836,10 @@ const processOptions = (inputOptions) => {
|
|
|
820
836
|
try {
|
|
821
837
|
return RelateURL.relate(text, relateUrlOptions);
|
|
822
838
|
} catch (err) {
|
|
823
|
-
options.
|
|
839
|
+
if (!options.continueOnMinifyError) {
|
|
840
|
+
throw err;
|
|
841
|
+
}
|
|
842
|
+
options.log && options.log(err);
|
|
824
843
|
return text;
|
|
825
844
|
}
|
|
826
845
|
};
|
|
@@ -1531,6 +1550,13 @@ export default { minify };
|
|
|
1531
1550
|
*
|
|
1532
1551
|
* Default: `false`
|
|
1533
1552
|
*
|
|
1553
|
+
* @prop {boolean} [continueOnMinifyError]
|
|
1554
|
+
* When set to `false`, minification errors may throw.
|
|
1555
|
+
* By default, the minifier will attempt to recover from minification
|
|
1556
|
+
* errors, or ignore them and preserve the original content.
|
|
1557
|
+
*
|
|
1558
|
+
* Default: `true`
|
|
1559
|
+
*
|
|
1534
1560
|
* @prop {boolean} [continueOnParseError]
|
|
1535
1561
|
* When true, the parser will attempt to continue on recoverable parse
|
|
1536
1562
|
* errors. Otherwise, parsing errors may throw.
|