html-minifier-next 6.2.7 → 6.2.8
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 +32 -44
- package/dist/htmlminifier.cjs +46 -38
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/htmlminifier.js +46 -38
package/README.md
CHANGED
|
@@ -4,17 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
Your web page optimization precision tool: HTML Minifier Next (HMN) is a **super-configurable, well-tested, JavaScript-based HTML minifier** able to also handle in-document CSS, JavaScript, and SVG minification.
|
|
6
6
|
|
|
7
|
-
The project was based on [HTML Minifier Terser (HMT)](https://github.com/terser/html-minifier-terser), which in turn had been based on [Juriy “kangax” Zaytsev’s HTML Minifier (HM)](https://github.com/kangax/html-minifier)
|
|
7
|
+
The project was based on [HTML Minifier Terser (HMT)](https://github.com/terser/html-minifier-terser), which in turn had been based on [Juriy “kangax” Zaytsev’s HTML Minifier (HM)](https://github.com/kangax/html-minifier). It is now **the official successor to HTML Minifier**. HMN is maintained, easier to use, offers new features, and has been optimized for speed.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```shell
|
|
14
|
-
npm i -g html-minifier-next
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Directly with npx:
|
|
11
|
+
For use as a command-line app, use npx:
|
|
18
12
|
|
|
19
13
|
```shell
|
|
20
14
|
npx html-minifier-next --help
|
|
@@ -22,30 +16,30 @@ npx html-minifier-next --help
|
|
|
22
16
|
|
|
23
17
|
(For immediate, zero-config use in the current folder: `npx html-minifier-next --zero`)
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
For programmatic use, install as a development dependency:
|
|
26
20
|
|
|
27
21
|
```shell
|
|
28
|
-
npm i html-minifier-next
|
|
22
|
+
npm i -D html-minifier-next
|
|
29
23
|
```
|
|
30
24
|
|
|
31
25
|
## General usage
|
|
32
26
|
|
|
33
27
|
### CLI
|
|
34
28
|
|
|
35
|
-
Use `html-minifier-next --help` to check all available options:
|
|
29
|
+
Use `npx html-minifier-next --help` to check all available options:
|
|
36
30
|
|
|
37
31
|
| Option | Description | Example |
|
|
38
32
|
| --- | --- | --- |
|
|
39
|
-
| `--zero`, `-z` | Minify all HTML files in the current folder and its subfolders in place (except node_modules), using comprehensive settings (standalone—flag is ignored when combined with other options) | `html-minifier-next --zero` |
|
|
33
|
+
| `--zero`, `-z` | Minify all HTML files in the current folder and its subfolders in place (except node_modules), using comprehensive settings (standalone—flag is ignored when combined with other options) | `npx html-minifier-next --zero` |
|
|
40
34
|
| `--input-dir <dir>`, `-I <dir>` | Specify an input directory | `--input-dir=src` |
|
|
41
35
|
| `--ignore-dir <patterns>`, `-X <patterns>` | Exclude directories—relative to input directory—from processing (comma-separated, overrides config file setting) | `--ignore-dir=libs`, `--ignore-dir=libs,vendor,node_modules` |
|
|
42
36
|
| `--output-dir <dir>`, `-O <dir>` | Specify an output directory | `--output-dir=dist` |
|
|
43
|
-
| `--output <file>`, `-o <file>` | Specify output file (reads from file arguments or STDIN) | File to file: `html-minifier-next input.html -o output.html`<br>Pipe to file: `cat input.html \| html-minifier-next -o output.html`<br>File to STDOUT: `html-minifier-next input.html` |
|
|
37
|
+
| `--output <file>`, `-o <file>` | Specify output file (reads from file arguments or STDIN) | File to file: `npx html-minifier-next input.html -o output.html`<br>Pipe to file: `cat input.html \| npx html-minifier-next -o output.html`<br>File to STDOUT: `npx html-minifier-next input.html` |
|
|
44
38
|
| `--file-ext <extensions>`, `-f <extensions>` | Specify file extension(s) to process (comma-separated, overrides config file setting); defaults to `html,htm,shtml,shtm`; use `*` for all files | `--file-ext=html,php`, `--file-ext='*'` |
|
|
45
39
|
| `--preset <name>`, `-p <name>` | Use a preset configuration (conservative or comprehensive) | `--preset=conservative` |
|
|
46
40
|
| `--config-file <file>`, `-c <file>` | Use a configuration file | `--config-file=html-minifier.json` |
|
|
47
|
-
| `--verbose`, `-v` | Show detailed processing information (active options, file statistics) | `html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace` |
|
|
48
|
-
| `--dry`, `-d` | Dry run: Process and report statistics without writing output | `html-minifier-next input.html --dry --collapse-whitespace` |
|
|
41
|
+
| `--verbose`, `-v` | Show detailed processing information (active options, file statistics) | `npx html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace` |
|
|
42
|
+
| `--dry`, `-d` | Dry run: Process and report statistics without writing output | `npx html-minifier-next input.html --dry --collapse-whitespace` |
|
|
49
43
|
|
|
50
44
|
### Configuration file
|
|
51
45
|
|
|
@@ -113,14 +107,14 @@ To review the specific options set, [presets.js](https://github.com/j9t/html-min
|
|
|
113
107
|
|
|
114
108
|
```shell
|
|
115
109
|
# Via CLI flag
|
|
116
|
-
html-minifier-next --preset conservative input.html
|
|
110
|
+
npx html-minifier-next --preset conservative input.html
|
|
117
111
|
|
|
118
112
|
# Via config file
|
|
119
|
-
html-minifier-next --config-file=html-minifier.json input.html
|
|
113
|
+
npx html-minifier-next --config-file=html-minifier.json input.html
|
|
120
114
|
# where html-minifier.json contains: { "preset": "conservative" }
|
|
121
115
|
|
|
122
116
|
# Override preset options
|
|
123
|
-
html-minifier-next --preset conservative --remove-empty-attributes input.html
|
|
117
|
+
npx html-minifier-next --preset conservative --remove-empty-attributes input.html
|
|
124
118
|
```
|
|
125
119
|
|
|
126
120
|
**Priority order:** Presets are applied first, then config file options, then CLI flags. This allows you to start with a preset and customize as needed.
|
|
@@ -246,14 +240,12 @@ const result = await minify(html, {
|
|
|
246
240
|
* `terser` (default): The standard JavaScript minifier with excellent compression
|
|
247
241
|
* [`swc`](https://swc.rs/): Rust-based minifier that’s significantly faster than Terser (requires separate installation)
|
|
248
242
|
|
|
249
|
-
**To use SWC**, install it as a dependency:
|
|
243
|
+
**To use SWC**, install it as a development dependency:
|
|
250
244
|
|
|
251
245
|
```shell
|
|
252
|
-
npm i @swc/core
|
|
246
|
+
npm i -D @swc/core
|
|
253
247
|
```
|
|
254
248
|
|
|
255
|
-
(Build-only users may want to install it as a dev dependency: `npm i -D @swc/core`.)
|
|
256
|
-
|
|
257
249
|
**Important:** Inline event handlers (e.g., `onclick="return false"`) always use Terser regardless of the `engine` setting, as SWC doesn’t support bare return statements. This is handled automatically—you don’t need to do anything special.
|
|
258
250
|
|
|
259
251
|
You can pass engine-specific configuration options:
|
|
@@ -340,7 +332,7 @@ const result = await minify(html, {
|
|
|
340
332
|
**Via CLI flags:**
|
|
341
333
|
|
|
342
334
|
```shell
|
|
343
|
-
html-minifier-next --minify-css --cache-css 750 --minify-js --cache-js 250 --minify-svg --cache-svg 100 input.html
|
|
335
|
+
npx html-minifier-next --minify-css --cache-css 750 --minify-js --cache-js 250 --minify-svg --cache-svg 100 input.html
|
|
344
336
|
```
|
|
345
337
|
|
|
346
338
|
**Via environment variables:**
|
|
@@ -349,7 +341,7 @@ html-minifier-next --minify-css --cache-css 750 --minify-js --cache-js 250 --min
|
|
|
349
341
|
export HMN_CACHE_CSS=750
|
|
350
342
|
export HMN_CACHE_JS=250
|
|
351
343
|
export HMN_CACHE_SVG=100
|
|
352
|
-
html-minifier-next --minify-css --minify-js --minify-svg input.html
|
|
344
|
+
npx html-minifier-next --minify-css --minify-js --minify-svg input.html
|
|
353
345
|
```
|
|
354
346
|
|
|
355
347
|
**Configuration file:**
|
|
@@ -390,12 +382,8 @@ Please see [**the Minifier Benchmarks project**](https://github.com/j9t/minifier
|
|
|
390
382
|
**Sample command line:**
|
|
391
383
|
|
|
392
384
|
```shell
|
|
393
|
-
html-minifier-next --collapse-whitespace --remove-comments --minify-js --input-dir=. --output-dir=example
|
|
394
|
-
```
|
|
385
|
+
npx html-minifier-next --collapse-whitespace --remove-comments --minify-js --input-dir=. --output-dir=example
|
|
395
386
|
|
|
396
|
-
Example using npx:
|
|
397
|
-
|
|
398
|
-
```shell
|
|
399
387
|
npx html-minifier-next --input-dir=test --preset comprehensive --output-dir example
|
|
400
388
|
```
|
|
401
389
|
|
|
@@ -403,39 +391,39 @@ npx html-minifier-next --input-dir=test --preset comprehensive --output-dir exam
|
|
|
403
391
|
|
|
404
392
|
```shell
|
|
405
393
|
# Process default extensions (html, htm, shtml, shtm)
|
|
406
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist
|
|
394
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist
|
|
407
395
|
|
|
408
396
|
# Process only specific extensions
|
|
409
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext=html,php
|
|
397
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext=html,php
|
|
410
398
|
|
|
411
399
|
# Using configuration file that sets `fileExt` (e.g., `"fileExt": "html,php"`)
|
|
412
|
-
html-minifier-next --config-file=html-minifier.json --input-dir=src --output-dir=dist
|
|
400
|
+
npx html-minifier-next --config-file=html-minifier.json --input-dir=src --output-dir=dist
|
|
413
401
|
|
|
414
402
|
# Process all files (explicit wildcard)
|
|
415
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext='*'
|
|
403
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext='*'
|
|
416
404
|
```
|
|
417
405
|
|
|
418
406
|
**Exclude directories from processing:**
|
|
419
407
|
|
|
420
408
|
```shell
|
|
421
409
|
# Ignore a single directory
|
|
422
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=libs
|
|
410
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=libs
|
|
423
411
|
|
|
424
412
|
# Ignore multiple directories
|
|
425
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=libs,vendor,node_modules
|
|
413
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=libs,vendor,node_modules
|
|
426
414
|
|
|
427
415
|
# Ignore by relative path (only ignores src/static/libs, not other “libs” directories)
|
|
428
|
-
html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=static/libs
|
|
416
|
+
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --ignore-dir=static/libs
|
|
429
417
|
```
|
|
430
418
|
|
|
431
419
|
**Dry run mode (preview outcome without writing files):**
|
|
432
420
|
|
|
433
421
|
```shell
|
|
434
422
|
# Preview with output file
|
|
435
|
-
html-minifier-next input.html -o output.html --dry --collapse-whitespace
|
|
423
|
+
npx html-minifier-next input.html -o output.html --dry --collapse-whitespace
|
|
436
424
|
|
|
437
425
|
# Preview directory processing with statistics per file and total
|
|
438
|
-
html-minifier-next --input-dir=src --output-dir=dist --dry --collapse-whitespace
|
|
426
|
+
npx html-minifier-next --input-dir=src --output-dir=dist --dry --collapse-whitespace
|
|
439
427
|
# Output: [DRY RUN] Would process directory: src → dist
|
|
440
428
|
# index.html: 1,234 → 892 bytes (-342, 27.7%)
|
|
441
429
|
# about.html: 2,100 → 1,654 bytes (-446, 21.2%)
|
|
@@ -447,7 +435,7 @@ html-minifier-next --input-dir=src --output-dir=dist --dry --collapse-whitespace
|
|
|
447
435
|
|
|
448
436
|
```shell
|
|
449
437
|
# Show processing details while minifying
|
|
450
|
-
html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace
|
|
438
|
+
npx html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace
|
|
451
439
|
# Output: CLI options: collapseWhitespace
|
|
452
440
|
# ✓ src/index.html: 1,234 → 892 bytes (-342, 27.7%)
|
|
453
441
|
# ✓ src/about.html: 2,100 → 1,654 bytes (-446, 21.2%)
|
|
@@ -455,7 +443,7 @@ html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whites
|
|
|
455
443
|
# Total: 3,334 → 2,546 bytes (-788, 23.6%)
|
|
456
444
|
|
|
457
445
|
# `--dry` automatically enables verbose output
|
|
458
|
-
html-minifier-next --input-dir=src --output-dir=dist --dry --collapse-whitespace
|
|
446
|
+
npx html-minifier-next --input-dir=src --output-dir=dist --dry --collapse-whitespace
|
|
459
447
|
```
|
|
460
448
|
|
|
461
449
|
## Special cases
|
|
@@ -560,13 +548,13 @@ ignoreCustomFragments: [/\{%[\s\S]{0,1000}?%\}/, /\{\{[\s\S]{0,500}?\}\}/]
|
|
|
560
548
|
**CLI (via config file—recommended):**
|
|
561
549
|
|
|
562
550
|
```shell
|
|
563
|
-
html-minifier-next --config-file=config.json input.html
|
|
551
|
+
npx html-minifier-next --config-file=config.json input.html
|
|
564
552
|
```
|
|
565
553
|
|
|
566
554
|
**CLI (inline—not recommended due to complex escaping):**
|
|
567
555
|
|
|
568
556
|
```shell
|
|
569
|
-
html-minifier-next --ignore-custom-fragments '[\\\"\\\\{%[\\\\s\\\\S]{0,1000}?%\\\\}\\\"]' input.html
|
|
557
|
+
npx html-minifier-next --ignore-custom-fragments '[\\\"\\\\{%[\\\\s\\\\S]{0,1000}?%\\\\}\\\"]' input.html
|
|
570
558
|
```
|
|
571
559
|
|
|
572
560
|
For CLI usage, using a config file is strongly recommended to avoid complex shell and JSON escaping.
|
|
@@ -577,7 +565,7 @@ For CLI usage, using a config file is strongly recommended to avoid complex shel
|
|
|
577
565
|
\{%[\s\S]{0,1000}?%\} \{\{[\s\S]{0,500}?\}\}
|
|
578
566
|
```
|
|
579
567
|
|
|
580
|
-
##
|
|
568
|
+
## Working on HTML Minifier Next
|
|
581
569
|
|
|
582
570
|
### Local server
|
|
583
571
|
|
|
@@ -609,6 +597,6 @@ With many thanks to the previous authors of and contributors to HTML Minifier, e
|
|
|
609
597
|
|
|
610
598
|
You might like some of my other work:
|
|
611
599
|
|
|
612
|
-
* Optimization tools: HTML Minifier Next · [ObsoHTML](https://github.com/j9t/obsohtml) · [Image Guard](https://github.com/j9t/image-guard) · [Compressor.js Next](https://github.com/j9t/compressorjs-next) · [.htaccess Punk](https://github.com/j9t/htaccess-punk)
|
|
600
|
+
* Optimization tools: [hihtml](https://github.com/j9t/hihtml) · HTML Minifier Next · [ObsoHTML](https://github.com/j9t/obsohtml) · [Image Guard](https://github.com/j9t/image-guard) · [Compressor.js Next](https://github.com/j9t/compressorjs-next) · [.htaccess Punk](https://github.com/j9t/htaccess-punk)
|
|
613
601
|
* Defense tools: [IA Defensa](https://iadefensa.com/solutions/)
|
|
614
602
|
* Resources for quality web development: [Articles](https://meiert.com/topics/development/) · [Books](https://meiert.com/topics/books/) (including [_On Web Development_](https://meiert.com/blog/on-web-development-2/)) · [News](https://frontenddogma.com/) · [Terminology](https://webglossary.info/)
|
package/dist/htmlminifier.cjs
CHANGED
|
@@ -3973,47 +3973,55 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
3973
3973
|
const maxQuantifier = options.customFragmentQuantifierLimit || 200;
|
|
3974
3974
|
const whitespacePattern = `\\s{0,${maxQuantifier}}`;
|
|
3975
3975
|
|
|
3976
|
-
//
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
3976
|
+
// Fast path: The padded replace below is costly on large inputs because the
|
|
3977
|
+
// `\s{0,N}` padding makes the regex engine consume and backtrack at every
|
|
3978
|
+
// whitespace run; since the padding is optional and the fragment group requires
|
|
3979
|
+
// at least one match, a single unpadded probe that finds nothing proves the
|
|
3980
|
+
// replace would be a no-op—so skip it entirely
|
|
3981
|
+
const reFragmentProbe = new RegExp('(?:' + customFragments.join('|') + ')');
|
|
3982
|
+
if (reFragmentProbe.test(value)) {
|
|
3983
|
+
// Use bounded quantifiers to prevent ReDoS—this approach prevents exponential backtracking
|
|
3984
|
+
const reCustomIgnore = new RegExp(
|
|
3985
|
+
whitespacePattern + '(?:' + customFragments.join('|') + '){1,' + maxQuantifier + '}' + whitespacePattern,
|
|
3986
|
+
'g'
|
|
3987
|
+
);
|
|
3988
|
+
// Temporarily replace custom ignored fragments with unique attributes
|
|
3989
|
+
value = value.replace(reCustomIgnore, function (match) {
|
|
3990
|
+
if (!uidAttr) {
|
|
3991
|
+
uidAttr = uniqueId(value);
|
|
3992
|
+
uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)' + uidAttr + '(\\s*)', 'g');
|
|
3993
|
+
uidAttrLeadingPattern = new RegExp('^\\s*' + uidAttr + '(\\d+)' + uidAttr);
|
|
3994
|
+
|
|
3995
|
+
if (options.minifyCSS) {
|
|
3996
|
+
options.minifyCSS = (function (fn) {
|
|
3997
|
+
return function (text, type) {
|
|
3998
|
+
text = text.replace(uidPattern, function (match, prefix, index) {
|
|
3999
|
+
const chunks = ignoredCustomMarkupChunks[+index];
|
|
4000
|
+
return chunks[1] + uidAttr + index + uidAttr + chunks[2];
|
|
4001
|
+
});
|
|
4002
|
+
|
|
4003
|
+
return fn(text, type);
|
|
4004
|
+
};
|
|
4005
|
+
})(options.minifyCSS);
|
|
4006
|
+
}
|
|
4000
4007
|
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4008
|
+
if (options.minifyJS) {
|
|
4009
|
+
options.minifyJS = (function (fn) {
|
|
4010
|
+
return function (text, inline, isModule) {
|
|
4011
|
+
return fn(text.replace(uidPattern, function (match, prefix, index) {
|
|
4012
|
+
const chunks = ignoredCustomMarkupChunks[+index];
|
|
4013
|
+
return chunks[1] + uidAttr + index + uidAttr + chunks[2];
|
|
4014
|
+
}), inline, isModule);
|
|
4015
|
+
};
|
|
4016
|
+
})(options.minifyJS);
|
|
4017
|
+
}
|
|
4010
4018
|
}
|
|
4011
|
-
}
|
|
4012
4019
|
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4020
|
+
const token = uidAttr + ignoredCustomMarkupChunks.length + uidAttr;
|
|
4021
|
+
ignoredCustomMarkupChunks.push(/^(\s*)[\s\S]*?(\s*)$/.exec(match));
|
|
4022
|
+
return '\t' + token + '\t';
|
|
4023
|
+
});
|
|
4024
|
+
}
|
|
4017
4025
|
}
|
|
4018
4026
|
|
|
4019
4027
|
function canCollapseWhitespace$1(tag, attrs) {
|
|
@@ -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":"AAozDO,8BAJI,MAAM,YACN,eAAe,GACb,OAAO,CAAC,MAAM,CAAC,CAwB3B;;;;;;;;;;;;UApiDS,MAAM;;;;;;;;;;;;;;;;;;mCAaA,MAAM,SAAS,aAAa,EAAE,yBAAyB,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;+BAM3F,MAAM,GAAG,IAAI,SAAS,aAAa,EAAE,GAAG,SAAS,qBAAqB,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA6JtG,OAAO,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2HA2BiF,MAAM,SAAS,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;iBASxG,QAAQ,GAAG,KAAK;gBAAgC,MAAM,WAAW,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;eAa/H,MAAM;gBAAY,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;;mBAiBzE,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDA+DF,MAAM,OAAO,MAAM,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA2EpC,MAAM,SAAS,aAAa,EAAE,KAAK,IAAI;;;;;;;;;wCAQrC,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;wBAtqBK,cAAc;0BAAd,cAAc;+BAAd,cAAc"}
|
package/package.json
CHANGED
|
@@ -10,21 +10,21 @@
|
|
|
10
10
|
"entities": "^8.0.0",
|
|
11
11
|
"lightningcss": "^1.32.0",
|
|
12
12
|
"svgo": "^4.0.1",
|
|
13
|
-
"terser": "^5.
|
|
13
|
+
"terser": "^5.47.1"
|
|
14
14
|
},
|
|
15
15
|
"description": "Super-configurable and well-tested web page minifier (enhanced successor of HTML Minifier)",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@commitlint/cli": "^
|
|
17
|
+
"@commitlint/cli": "^21.0.1",
|
|
18
18
|
"@eslint/js": "^10.0.1",
|
|
19
19
|
"@rollup/plugin-commonjs": "^29.0.2",
|
|
20
20
|
"@rollup/plugin-json": "^6.1.0",
|
|
21
21
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
22
|
-
"@swc/core": "^1.15.
|
|
23
|
-
"eslint": "^10.
|
|
24
|
-
"rollup": "^4.60.
|
|
22
|
+
"@swc/core": "^1.15.40",
|
|
23
|
+
"eslint": "^10.4.0",
|
|
24
|
+
"rollup": "^4.60.4",
|
|
25
25
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
|
-
"vite": "^8.0.
|
|
27
|
+
"vite": "^8.0.14"
|
|
28
28
|
},
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
},
|
|
98
98
|
"type": "module",
|
|
99
99
|
"types": "./dist/types/htmlminifier.d.ts",
|
|
100
|
-
"version": "6.2.
|
|
100
|
+
"version": "6.2.8"
|
|
101
101
|
}
|
package/src/htmlminifier.js
CHANGED
|
@@ -1031,47 +1031,55 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1031
1031
|
const maxQuantifier = options.customFragmentQuantifierLimit || 200;
|
|
1032
1032
|
const whitespacePattern = `\\s{0,${maxQuantifier}}`;
|
|
1033
1033
|
|
|
1034
|
-
//
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1034
|
+
// Fast path: The padded replace below is costly on large inputs because the
|
|
1035
|
+
// `\s{0,N}` padding makes the regex engine consume and backtrack at every
|
|
1036
|
+
// whitespace run; since the padding is optional and the fragment group requires
|
|
1037
|
+
// at least one match, a single unpadded probe that finds nothing proves the
|
|
1038
|
+
// replace would be a no-op—so skip it entirely
|
|
1039
|
+
const reFragmentProbe = new RegExp('(?:' + customFragments.join('|') + ')');
|
|
1040
|
+
if (reFragmentProbe.test(value)) {
|
|
1041
|
+
// Use bounded quantifiers to prevent ReDoS—this approach prevents exponential backtracking
|
|
1042
|
+
const reCustomIgnore = new RegExp(
|
|
1043
|
+
whitespacePattern + '(?:' + customFragments.join('|') + '){1,' + maxQuantifier + '}' + whitespacePattern,
|
|
1044
|
+
'g'
|
|
1045
|
+
);
|
|
1046
|
+
// Temporarily replace custom ignored fragments with unique attributes
|
|
1047
|
+
value = value.replace(reCustomIgnore, function (match) {
|
|
1048
|
+
if (!uidAttr) {
|
|
1049
|
+
uidAttr = uniqueId(value);
|
|
1050
|
+
uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)' + uidAttr + '(\\s*)', 'g');
|
|
1051
|
+
uidAttrLeadingPattern = new RegExp('^\\s*' + uidAttr + '(\\d+)' + uidAttr);
|
|
1052
|
+
|
|
1053
|
+
if (options.minifyCSS) {
|
|
1054
|
+
options.minifyCSS = (function (fn) {
|
|
1055
|
+
return function (text, type) {
|
|
1056
|
+
text = text.replace(uidPattern, function (match, prefix, index) {
|
|
1057
|
+
const chunks = ignoredCustomMarkupChunks[+index];
|
|
1058
|
+
return chunks[1] + uidAttr + index + uidAttr + chunks[2];
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
return fn(text, type);
|
|
1062
|
+
};
|
|
1063
|
+
})(options.minifyCSS);
|
|
1064
|
+
}
|
|
1058
1065
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1066
|
+
if (options.minifyJS) {
|
|
1067
|
+
options.minifyJS = (function (fn) {
|
|
1068
|
+
return function (text, inline, isModule) {
|
|
1069
|
+
return fn(text.replace(uidPattern, function (match, prefix, index) {
|
|
1070
|
+
const chunks = ignoredCustomMarkupChunks[+index];
|
|
1071
|
+
return chunks[1] + uidAttr + index + uidAttr + chunks[2];
|
|
1072
|
+
}), inline, isModule);
|
|
1073
|
+
};
|
|
1074
|
+
})(options.minifyJS);
|
|
1075
|
+
}
|
|
1068
1076
|
}
|
|
1069
|
-
}
|
|
1070
1077
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1078
|
+
const token = uidAttr + ignoredCustomMarkupChunks.length + uidAttr;
|
|
1079
|
+
ignoredCustomMarkupChunks.push(/^(\s*)[\s\S]*?(\s*)$/.exec(match));
|
|
1080
|
+
return '\t' + token + '\t';
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1075
1083
|
}
|
|
1076
1084
|
|
|
1077
1085
|
function canCollapseWhitespace(tag, attrs) {
|