html-minifier-next 7.0.0 → 7.2.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 +19 -7
- package/cli.js +1 -4
- package/dist/types/lib/attributes.d.ts.map +1 -1
- package/dist/types/lib/option-definitions.d.ts +64 -46
- package/html-minifier-next.schema.json +303 -0
- package/package.json +9 -7
- package/src/lib/attributes.js +30 -3
- package/src/lib/option-definitions.js +12 -0
- package/src/lib/options.js +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Use `npx html-minifier-next --help` to check all available options:
|
|
|
40
40
|
| `--output <file>`, `-o <file>` | Specify output file (reads from `--input` file argument or STDIN; outputs to STDOUT if not specified) | File to file: `npx html-minifier-next input.html -o output.html`<br>File to file (explicit): `npx html-minifier-next -i 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` |
|
|
41
41
|
| `--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='*'` |
|
|
42
42
|
| `--preset <name>`, `-p <name>` | Use a preset configuration (conservative or comprehensive) | `--preset=conservative` |
|
|
43
|
-
| `--config-file <file>`, `-c <file>` | Use a configuration file | `--config-file=html-minifier.json` |
|
|
43
|
+
| `--config-file <file>`, `-c <file>` | Use a configuration file | `--config-file=html-minifier-next.json` |
|
|
44
44
|
| `--verbose`, `-v` | Show detailed processing information (active options, file statistics) | `npx html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace` |
|
|
45
45
|
| `--dry`, `-d` | Dry run: Process and report statistics without writing output | `npx html-minifier-next input.html --dry --collapse-whitespace` |
|
|
46
46
|
|
|
@@ -59,6 +59,18 @@ You can use a configuration file to specify options. The file can be either in J
|
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
For editor support (validation, autocomplete, and inline documentation) in JSON configuration files, reference the [JSON Schema](https://raw.githubusercontent.com/j9t/html-minifier-next/main/html-minifier-next.schema.json) that ships with the package:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"$schema": "https://raw.githubusercontent.com/j9t/html-minifier-next/main/html-minifier-next.schema.json",
|
|
67
|
+
"collapseWhitespace": true,
|
|
68
|
+
"removeComments": true
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
(If HMN is installed locally, you can also use the path `./node_modules/html-minifier-next/html-minifier-next.schema.json` instead of the URL.)
|
|
73
|
+
|
|
62
74
|
**JavaScript module configuration example** (requires `"type": "module"` in the project’s package.json, or use a .mjs extension):
|
|
63
75
|
|
|
64
76
|
```javascript
|
|
@@ -100,8 +112,8 @@ To review the specific options set, [presets.js](https://github.com/j9t/html-min
|
|
|
100
112
|
npx html-minifier-next --preset conservative input.html
|
|
101
113
|
|
|
102
114
|
# Via config file
|
|
103
|
-
npx html-minifier-next --config-file=html-minifier.json input.html
|
|
104
|
-
# where html-minifier.json contains: { "preset": "conservative" }
|
|
115
|
+
npx html-minifier-next --config-file=html-minifier-next.json input.html
|
|
116
|
+
# where html-minifier-next.json contains: { "preset": "conservative" }
|
|
105
117
|
|
|
106
118
|
# Override preset options
|
|
107
119
|
npx html-minifier-next --preset conservative --remove-empty-attributes input.html
|
|
@@ -360,13 +372,13 @@ npx html-minifier-next --minify-css --minify-js --minify-svg input.html
|
|
|
360
372
|
|
|
361
373
|
* Single file processing: Default `500` is sufficient
|
|
362
374
|
* Batch processing: Increase to `1000` or higher for better cache hit rates
|
|
363
|
-
* Memory-constrained environments:
|
|
375
|
+
* Memory-constrained environments: Cache sizes can be lowered, though the savings are usually negligible—entries are typically kilobyte-scale, so even full caches only hold a few megabytes
|
|
364
376
|
* Hundreds/thousands of files: Increase to `1000`–`2000` for optimal performance
|
|
365
377
|
|
|
366
378
|
**Important:**
|
|
367
379
|
|
|
368
380
|
* Cache locking: Caches are created on the first `minify()` call and persist for the process lifetime. Cache sizes are locked after first initialization—subsequent calls reuse the same caches even if different `cacheCSS`, `cacheJS`, or `cacheSVG` options are provided. The first call’s options determine the cache sizes.
|
|
369
|
-
* Zero values: Explicit `0` values are coerced to `1` (minimum functional cache size) to avoid immediate eviction.
|
|
381
|
+
* Zero values: Explicit `0` values are coerced to `1` (minimum functional cache size) to avoid immediate eviction. To keep the cache footprint as small as possible, use a small number like `10` or `50` instead of `0`.
|
|
370
382
|
|
|
371
383
|
The caches persist across multiple `minify()` calls, making them particularly effective when processing many files in a batch operation.
|
|
372
384
|
|
|
@@ -396,7 +408,7 @@ npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist
|
|
|
396
408
|
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext=html,php
|
|
397
409
|
|
|
398
410
|
# Using configuration file that sets `fileExt` (e.g., `"fileExt": "html,php"`)
|
|
399
|
-
npx html-minifier-next --config-file=html-minifier.json --input-dir=src --output-dir=dist
|
|
411
|
+
npx html-minifier-next --config-file=html-minifier-next.json --input-dir=src --output-dir=dist
|
|
400
412
|
|
|
401
413
|
# Process all files (explicit wildcard)
|
|
402
414
|
npx html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist --file-ext='*'
|
|
@@ -608,7 +620,7 @@ Parameters:
|
|
|
608
620
|
* `--save`: Saves the run as the baseline (e.g., on `main` before switching to a branch)
|
|
609
621
|
* `--core`: Disables the external minifiers (CSS, JS, SVG, URLs) to isolate HMN’s own processing time
|
|
610
622
|
* `--iterations=N`: Sets the number of timed iterations (default 5; the median is reported)
|
|
611
|
-
* `--config=PATH`: Uses an alternative options file (default `html-minifier.json`)
|
|
623
|
+
* `--config=PATH`: Uses an alternative options file (default `html-minifier-next.json`)
|
|
612
624
|
|
|
613
625
|
To compare branches (A/B run), execute `npm run benchmark -- --save` on `main`, then `npm run benchmark` on the branch to see the deltas. Add `--core` on both ends when measuring changes to HMN’s own code rather than the bundled minifiers.
|
|
614
626
|
|
package/cli.js
CHANGED
|
@@ -227,7 +227,7 @@ async function loadConfigFromPath(configPath) {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// Config keys the CLI handles itself, beyond the options in `optionDefinitions`
|
|
230
|
-
const CONFIG_KEYS_EXTRA = new Set(['preset', 'fileExt', 'ignoreDir']);
|
|
230
|
+
const CONFIG_KEYS_EXTRA = new Set(['$schema', 'preset', 'fileExt', 'ignoreDir']);
|
|
231
231
|
|
|
232
232
|
/**
|
|
233
233
|
* Normalize and validate config object by applying parsers and transforming values.
|
|
@@ -283,9 +283,6 @@ program.option('-O --output-dir <dir>', 'Specify an output directory');
|
|
|
283
283
|
program.option('-f --file-ext <extensions>', 'Specify file extension(s) to process (comma-separated); defaults to “html,htm,shtml,shtm”; use “*” for all files');
|
|
284
284
|
program.option('-p --preset <name>', `Use a preset configuration (${getPresetNames().join(', ')})`);
|
|
285
285
|
program.option('-c --config-file <file>', 'Use config file');
|
|
286
|
-
program.option('--cache-css <size>', 'Set CSS minification cache size (number of entries, default: 500)', parseValidInt('cacheCSS'));
|
|
287
|
-
program.option('--cache-js <size>', 'Set JavaScript minification cache size (number of entries, default: 500)', parseValidInt('cacheJS'));
|
|
288
|
-
program.option('--cache-svg <size>', 'Set SVG minification cache size (number of entries, default: 500)', parseValidInt('cacheSVG'));
|
|
289
286
|
program.version(pkg.version, '-V, --version', 'Output the version number');
|
|
290
287
|
program.helpOption('-h, --help', 'Display help for command');
|
|
291
288
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":";;;4BA0Ba;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE;AAiB3I;;;GAGG;AACH,uCAHW,MAAM,WACN,gBAAgB,WAS1B;AAED;;;GAGG;AACH,2CAHW,MAAM,WACN;IAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,WAa5C;AAED,4BAA4B;AAC5B,gDADY,MAAM,WAIjB;AAED;;;GAGG;AACH,8CAHW,aAAa,EAAE,aACf,MAAM,WAShB;AA+BD;;;;;GAKG;AACH,0CALW,MAAM,YACN,MAAM,aACN,MAAM,SACN,aAAa,EAAE,WAyCzB;AAED,mEAGC;AAED,qEAGC;AAED;;;GAGG;AACH,wCAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED,sEAGC;AAED;;;GAGG;AACH,oCAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED;;;GAGG;AACH,6CAHW,MAAM,aACN,MAAM,uBAMhB;AAmBD;;;GAGG;AACH,6CAHW,MAAM,OACN,MAAM,WAKhB;AAgBD;;;GAGG;AACH,gDAHW,MAAM,OACN,MAAM,WAKhB;AAED;;;;GAIG;AACH,gCAJW,MAAM,SACN,aAAa,EAAE,SACf,MAAM,WAYhB;AAED;;;;GAIG;AACH,kCAJW,MAAM,SACN,aAAa,EAAE,YACf,MAAM,WAIhB;AAED;;;GAGG;AACH,mCAHW,MAAM,OACN,MAAM,
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":";;;4BA0Ba;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE;AAiB3I;;;GAGG;AACH,uCAHW,MAAM,WACN,gBAAgB,WAS1B;AAED;;;GAGG;AACH,2CAHW,MAAM,WACN;IAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,WAa5C;AAED,4BAA4B;AAC5B,gDADY,MAAM,WAIjB;AAED;;;GAGG;AACH,8CAHW,aAAa,EAAE,aACf,MAAM,WAShB;AA+BD;;;;;GAKG;AACH,0CALW,MAAM,YACN,MAAM,aACN,MAAM,SACN,aAAa,EAAE,WAyCzB;AAED,mEAGC;AAED,qEAGC;AAED;;;GAGG;AACH,wCAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED,sEAGC;AAED;;;GAGG;AACH,oCAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED;;;GAGG;AACH,6CAHW,MAAM,aACN,MAAM,uBAMhB;AAmBD;;;GAGG;AACH,6CAHW,MAAM,OACN,MAAM,WAKhB;AAgBD;;;GAGG;AACH,gDAHW,MAAM,OACN,MAAM,WAKhB;AAED;;;;GAIG;AACH,gCAJW,MAAM,SACN,aAAa,EAAE,SACf,MAAM,WAYhB;AAED;;;;GAIG;AACH,kCAJW,MAAM,SACN,aAAa,EAAE,YACf,MAAM,WAIhB;AAED;;;GAGG;AACH,mCAHW,MAAM,OACN,MAAM,WAKhB;AAED;;;GAGG;AACH,oCAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED;;;GAGG;AACH,6CAHW,MAAM,SACN,aAAa,EAAE,WAYzB;AAED;;;;;GAKG;AACH,6CALW,MAAM,YACN,MAAM,aACN,MAAM,GAAG,SAAS,WAClB;IAAC,qBAAqB,CAAC,EAAE,OAAO,WAAW,CAAA;CAAC,OAWtD;AAED;;;GAGG;AACH,kCAHW,MAAM,SACN,aAAa,EAAE,WASzB;AAUD;;;;;;;GAOG;AACH,yCAPW,MAAM,YACN,MAAM,aACN,MAAM,WACN,gBAAgB,SAChB,aAAa,EAAE,iCA4NzB;AAwBD;;;;;;GAMG;AACH,oCANW,aAAa,SACb,aAAa,EAAE,OACf,MAAM,WACN,gBAAgB;;;;;;;;2BAe1B;AA0DD;;;;;;GAMG;AACH,sCANW;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAC,iBAC9D,MAAM,GAAG,OAAO,GAAG,SAAS,WAC5B,gBAAgB,UAChB,OAAO,WACP,MAAM,GAAG,SAAS,UA0H5B;AApuBD;;;;;;;GAOG;AACH,6CAJW,aAAa,EAAE,iBACf,OAAO,GACL,aAAa,EAAE,CAqB3B;sCAlGqC,cAAc"}
|
|
@@ -1,273 +1,291 @@
|
|
|
1
1
|
export namespace optionDefinitions {
|
|
2
|
-
namespace
|
|
2
|
+
namespace cacheCSS {
|
|
3
3
|
let description: string;
|
|
4
4
|
let type: string;
|
|
5
5
|
}
|
|
6
|
-
namespace
|
|
6
|
+
namespace cacheJS {
|
|
7
7
|
let description_1: string;
|
|
8
8
|
export { description_1 as description };
|
|
9
9
|
let type_1: string;
|
|
10
10
|
export { type_1 as type };
|
|
11
11
|
}
|
|
12
|
-
namespace
|
|
12
|
+
namespace cacheSVG {
|
|
13
13
|
let description_2: string;
|
|
14
14
|
export { description_2 as description };
|
|
15
15
|
let type_2: string;
|
|
16
16
|
export { type_2 as type };
|
|
17
17
|
}
|
|
18
|
-
namespace
|
|
18
|
+
namespace caseSensitive {
|
|
19
19
|
let description_3: string;
|
|
20
20
|
export { description_3 as description };
|
|
21
21
|
let type_3: string;
|
|
22
22
|
export { type_3 as type };
|
|
23
23
|
}
|
|
24
|
-
namespace
|
|
24
|
+
namespace collapseAttributeWhitespace {
|
|
25
25
|
let description_4: string;
|
|
26
26
|
export { description_4 as description };
|
|
27
27
|
let type_4: string;
|
|
28
28
|
export { type_4 as type };
|
|
29
29
|
}
|
|
30
|
-
namespace
|
|
30
|
+
namespace collapseBooleanAttributes {
|
|
31
31
|
let description_5: string;
|
|
32
32
|
export { description_5 as description };
|
|
33
33
|
let type_5: string;
|
|
34
34
|
export { type_5 as type };
|
|
35
35
|
}
|
|
36
|
-
namespace
|
|
36
|
+
namespace collapseInlineTagWhitespace {
|
|
37
37
|
let description_6: string;
|
|
38
38
|
export { description_6 as description };
|
|
39
|
-
export let descriptionAffirmative: string;
|
|
40
39
|
let type_6: string;
|
|
41
40
|
export { type_6 as type };
|
|
42
41
|
}
|
|
43
|
-
namespace
|
|
42
|
+
namespace collapseWhitespace {
|
|
44
43
|
let description_7: string;
|
|
45
44
|
export { description_7 as description };
|
|
46
45
|
let type_7: string;
|
|
47
46
|
export { type_7 as type };
|
|
48
47
|
}
|
|
49
|
-
namespace
|
|
48
|
+
namespace conservativeCollapse {
|
|
50
49
|
let description_8: string;
|
|
51
50
|
export { description_8 as description };
|
|
52
51
|
let type_8: string;
|
|
53
52
|
export { type_8 as type };
|
|
54
53
|
}
|
|
55
|
-
namespace
|
|
54
|
+
namespace continueOnMinifyError {
|
|
56
55
|
let description_9: string;
|
|
57
56
|
export { description_9 as description };
|
|
57
|
+
export let descriptionAffirmative: string;
|
|
58
58
|
let type_9: string;
|
|
59
59
|
export { type_9 as type };
|
|
60
60
|
}
|
|
61
|
-
namespace
|
|
61
|
+
namespace continueOnParseError {
|
|
62
62
|
let description_10: string;
|
|
63
63
|
export { description_10 as description };
|
|
64
64
|
let type_10: string;
|
|
65
65
|
export { type_10 as type };
|
|
66
66
|
}
|
|
67
|
-
namespace
|
|
67
|
+
namespace customAttrAssign {
|
|
68
68
|
let description_11: string;
|
|
69
69
|
export { description_11 as description };
|
|
70
70
|
let type_11: string;
|
|
71
71
|
export { type_11 as type };
|
|
72
72
|
}
|
|
73
|
-
namespace
|
|
73
|
+
namespace customAttrCollapse {
|
|
74
74
|
let description_12: string;
|
|
75
75
|
export { description_12 as description };
|
|
76
76
|
let type_12: string;
|
|
77
77
|
export { type_12 as type };
|
|
78
78
|
}
|
|
79
|
-
namespace
|
|
79
|
+
namespace customAttrSurround {
|
|
80
80
|
let description_13: string;
|
|
81
81
|
export { description_13 as description };
|
|
82
82
|
let type_13: string;
|
|
83
83
|
export { type_13 as type };
|
|
84
84
|
}
|
|
85
|
-
namespace
|
|
85
|
+
namespace customEventAttributes {
|
|
86
86
|
let description_14: string;
|
|
87
87
|
export { description_14 as description };
|
|
88
88
|
let type_14: string;
|
|
89
89
|
export { type_14 as type };
|
|
90
90
|
}
|
|
91
|
-
namespace
|
|
91
|
+
namespace customFragmentQuantifierLimit {
|
|
92
92
|
let description_15: string;
|
|
93
93
|
export { description_15 as description };
|
|
94
94
|
let type_15: string;
|
|
95
95
|
export { type_15 as type };
|
|
96
96
|
}
|
|
97
|
-
namespace
|
|
97
|
+
namespace decodeEntities {
|
|
98
98
|
let description_16: string;
|
|
99
99
|
export { description_16 as description };
|
|
100
100
|
let type_16: string;
|
|
101
101
|
export { type_16 as type };
|
|
102
102
|
}
|
|
103
|
-
namespace
|
|
103
|
+
namespace ignoreCustomComments {
|
|
104
104
|
let description_17: string;
|
|
105
105
|
export { description_17 as description };
|
|
106
106
|
let type_17: string;
|
|
107
107
|
export { type_17 as type };
|
|
108
108
|
}
|
|
109
|
-
namespace
|
|
109
|
+
namespace ignoreCustomFragments {
|
|
110
110
|
let description_18: string;
|
|
111
111
|
export { description_18 as description };
|
|
112
112
|
let type_18: string;
|
|
113
113
|
export { type_18 as type };
|
|
114
114
|
}
|
|
115
|
-
namespace
|
|
115
|
+
namespace includeAutoGeneratedTags {
|
|
116
116
|
let description_19: string;
|
|
117
117
|
export { description_19 as description };
|
|
118
118
|
let type_19: string;
|
|
119
119
|
export { type_19 as type };
|
|
120
120
|
}
|
|
121
|
-
namespace
|
|
121
|
+
namespace inlineCustomElements {
|
|
122
122
|
let description_20: string;
|
|
123
123
|
export { description_20 as description };
|
|
124
124
|
let type_20: string;
|
|
125
125
|
export { type_20 as type };
|
|
126
126
|
}
|
|
127
|
-
namespace
|
|
127
|
+
namespace keepClosingSlash {
|
|
128
128
|
let description_21: string;
|
|
129
129
|
export { description_21 as description };
|
|
130
130
|
let type_21: string;
|
|
131
131
|
export { type_21 as type };
|
|
132
132
|
}
|
|
133
|
-
namespace
|
|
133
|
+
namespace maxInputLength {
|
|
134
134
|
let description_22: string;
|
|
135
135
|
export { description_22 as description };
|
|
136
136
|
let type_22: string;
|
|
137
137
|
export { type_22 as type };
|
|
138
138
|
}
|
|
139
|
-
namespace
|
|
139
|
+
namespace maxLineLength {
|
|
140
140
|
let description_23: string;
|
|
141
141
|
export { description_23 as description };
|
|
142
142
|
let type_23: string;
|
|
143
143
|
export { type_23 as type };
|
|
144
144
|
}
|
|
145
|
-
namespace
|
|
145
|
+
namespace mergeScripts {
|
|
146
146
|
let description_24: string;
|
|
147
147
|
export { description_24 as description };
|
|
148
148
|
let type_24: string;
|
|
149
149
|
export { type_24 as type };
|
|
150
150
|
}
|
|
151
|
-
namespace
|
|
151
|
+
namespace minifyCSS {
|
|
152
152
|
let description_25: string;
|
|
153
153
|
export { description_25 as description };
|
|
154
154
|
let type_25: string;
|
|
155
155
|
export { type_25 as type };
|
|
156
156
|
}
|
|
157
|
-
namespace
|
|
157
|
+
namespace minifyJS {
|
|
158
158
|
let description_26: string;
|
|
159
159
|
export { description_26 as description };
|
|
160
160
|
let type_26: string;
|
|
161
161
|
export { type_26 as type };
|
|
162
162
|
}
|
|
163
|
-
namespace
|
|
163
|
+
namespace minifySVG {
|
|
164
164
|
let description_27: string;
|
|
165
165
|
export { description_27 as description };
|
|
166
166
|
let type_27: string;
|
|
167
167
|
export { type_27 as type };
|
|
168
168
|
}
|
|
169
|
-
namespace
|
|
169
|
+
namespace minifyURLs {
|
|
170
170
|
let description_28: string;
|
|
171
171
|
export { description_28 as description };
|
|
172
172
|
let type_28: string;
|
|
173
173
|
export { type_28 as type };
|
|
174
174
|
}
|
|
175
|
-
namespace
|
|
175
|
+
namespace noNewlinesBeforeTagClose {
|
|
176
176
|
let description_29: string;
|
|
177
177
|
export { description_29 as description };
|
|
178
178
|
let type_29: string;
|
|
179
179
|
export { type_29 as type };
|
|
180
180
|
}
|
|
181
|
-
namespace
|
|
181
|
+
namespace partialMarkup {
|
|
182
182
|
let description_30: string;
|
|
183
183
|
export { description_30 as description };
|
|
184
184
|
let type_30: string;
|
|
185
185
|
export { type_30 as type };
|
|
186
186
|
}
|
|
187
|
-
namespace
|
|
187
|
+
namespace preserveLineBreaks {
|
|
188
188
|
let description_31: string;
|
|
189
189
|
export { description_31 as description };
|
|
190
190
|
let type_31: string;
|
|
191
191
|
export { type_31 as type };
|
|
192
192
|
}
|
|
193
|
-
namespace
|
|
193
|
+
namespace preventAttributesEscaping {
|
|
194
194
|
let description_32: string;
|
|
195
195
|
export { description_32 as description };
|
|
196
196
|
let type_32: string;
|
|
197
197
|
export { type_32 as type };
|
|
198
198
|
}
|
|
199
|
-
namespace
|
|
199
|
+
namespace processScripts {
|
|
200
200
|
let description_33: string;
|
|
201
201
|
export { description_33 as description };
|
|
202
202
|
let type_33: string;
|
|
203
203
|
export { type_33 as type };
|
|
204
204
|
}
|
|
205
|
-
namespace
|
|
205
|
+
namespace quoteCharacter {
|
|
206
206
|
let description_34: string;
|
|
207
207
|
export { description_34 as description };
|
|
208
208
|
let type_34: string;
|
|
209
209
|
export { type_34 as type };
|
|
210
210
|
}
|
|
211
|
-
namespace
|
|
211
|
+
namespace removeAttributeQuotes {
|
|
212
212
|
let description_35: string;
|
|
213
213
|
export { description_35 as description };
|
|
214
214
|
let type_35: string;
|
|
215
215
|
export { type_35 as type };
|
|
216
216
|
}
|
|
217
|
-
namespace
|
|
217
|
+
namespace removeComments {
|
|
218
218
|
let description_36: string;
|
|
219
219
|
export { description_36 as description };
|
|
220
220
|
let type_36: string;
|
|
221
221
|
export { type_36 as type };
|
|
222
222
|
}
|
|
223
|
-
namespace
|
|
223
|
+
namespace removeDefaultTypeAttributes {
|
|
224
224
|
let description_37: string;
|
|
225
225
|
export { description_37 as description };
|
|
226
226
|
let type_37: string;
|
|
227
227
|
export { type_37 as type };
|
|
228
228
|
}
|
|
229
|
-
namespace
|
|
229
|
+
namespace removeEmptyAttributes {
|
|
230
230
|
let description_38: string;
|
|
231
231
|
export { description_38 as description };
|
|
232
232
|
let type_38: string;
|
|
233
233
|
export { type_38 as type };
|
|
234
234
|
}
|
|
235
|
-
namespace
|
|
235
|
+
namespace removeEmptyElements {
|
|
236
236
|
let description_39: string;
|
|
237
237
|
export { description_39 as description };
|
|
238
238
|
let type_39: string;
|
|
239
239
|
export { type_39 as type };
|
|
240
240
|
}
|
|
241
|
-
namespace
|
|
241
|
+
namespace removeEmptyElementsExcept {
|
|
242
242
|
let description_40: string;
|
|
243
243
|
export { description_40 as description };
|
|
244
244
|
let type_40: string;
|
|
245
245
|
export { type_40 as type };
|
|
246
246
|
}
|
|
247
|
-
namespace
|
|
247
|
+
namespace removeOptionalTags {
|
|
248
248
|
let description_41: string;
|
|
249
249
|
export { description_41 as description };
|
|
250
250
|
let type_41: string;
|
|
251
251
|
export { type_41 as type };
|
|
252
252
|
}
|
|
253
|
-
namespace
|
|
253
|
+
namespace removeRedundantAttributes {
|
|
254
254
|
let description_42: string;
|
|
255
255
|
export { description_42 as description };
|
|
256
256
|
let type_42: string;
|
|
257
257
|
export { type_42 as type };
|
|
258
258
|
}
|
|
259
|
-
namespace
|
|
259
|
+
namespace removeTagWhitespace {
|
|
260
260
|
let description_43: string;
|
|
261
261
|
export { description_43 as description };
|
|
262
262
|
let type_43: string;
|
|
263
263
|
export { type_43 as type };
|
|
264
264
|
}
|
|
265
|
-
namespace
|
|
265
|
+
namespace sortAttributes {
|
|
266
266
|
let description_44: string;
|
|
267
267
|
export { description_44 as description };
|
|
268
268
|
let type_44: string;
|
|
269
269
|
export { type_44 as type };
|
|
270
270
|
}
|
|
271
|
+
namespace sortClassNames {
|
|
272
|
+
let description_45: string;
|
|
273
|
+
export { description_45 as description };
|
|
274
|
+
let type_45: string;
|
|
275
|
+
export { type_45 as type };
|
|
276
|
+
}
|
|
277
|
+
namespace trimCustomFragments {
|
|
278
|
+
let description_46: string;
|
|
279
|
+
export { description_46 as description };
|
|
280
|
+
let type_46: string;
|
|
281
|
+
export { type_46 as type };
|
|
282
|
+
}
|
|
283
|
+
namespace useShortDoctype {
|
|
284
|
+
let description_47: string;
|
|
285
|
+
export { description_47 as description };
|
|
286
|
+
let type_47: string;
|
|
287
|
+
export { type_47 as type };
|
|
288
|
+
}
|
|
271
289
|
}
|
|
272
290
|
export namespace optionDefaults {
|
|
273
291
|
let continueOnMinifyError_1: boolean;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/j9t/html-minifier-next/main/html-minifier-next.schema.json",
|
|
4
|
+
"title": "HTML Minifier Next configuration",
|
|
5
|
+
"description": "Configuration file for HTML Minifier Next (HMN), used via `--config-file`",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"$schema": {
|
|
9
|
+
"description": "JSON Schema reference for this configuration file (enables editor validation and autocomplete)",
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"preset": {
|
|
13
|
+
"description": "Preset configuration to start from—config file options override preset options",
|
|
14
|
+
"enum": [
|
|
15
|
+
"conservative",
|
|
16
|
+
"comprehensive"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"fileExt": {
|
|
20
|
+
"description": "File extension(s) to process, as comma-separated string or array (default: `html,htm,shtml,shtm`; use `*` for all files)",
|
|
21
|
+
"type": [
|
|
22
|
+
"string",
|
|
23
|
+
"array"
|
|
24
|
+
],
|
|
25
|
+
"items": {
|
|
26
|
+
"type": "string"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"ignoreDir": {
|
|
30
|
+
"description": "Directories—relative to the input directory—to exclude from processing, as comma-separated string or array",
|
|
31
|
+
"type": [
|
|
32
|
+
"string",
|
|
33
|
+
"array"
|
|
34
|
+
],
|
|
35
|
+
"items": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"cacheCSS": {
|
|
40
|
+
"description": "Set CSS minification cache size (number of entries, default: 500)",
|
|
41
|
+
"type": "integer",
|
|
42
|
+
"minimum": 0
|
|
43
|
+
},
|
|
44
|
+
"cacheJS": {
|
|
45
|
+
"description": "Set JavaScript minification cache size (number of entries, default: 500)",
|
|
46
|
+
"type": "integer",
|
|
47
|
+
"minimum": 0
|
|
48
|
+
},
|
|
49
|
+
"cacheSVG": {
|
|
50
|
+
"description": "Set SVG minification cache size (number of entries, default: 500)",
|
|
51
|
+
"type": "integer",
|
|
52
|
+
"minimum": 0
|
|
53
|
+
},
|
|
54
|
+
"caseSensitive": {
|
|
55
|
+
"description": "Treat attributes in case-sensitive manner (useful for custom HTML elements)",
|
|
56
|
+
"type": "boolean"
|
|
57
|
+
},
|
|
58
|
+
"collapseAttributeWhitespace": {
|
|
59
|
+
"description": "Trim and collapse whitespace characters within attribute values",
|
|
60
|
+
"type": "boolean"
|
|
61
|
+
},
|
|
62
|
+
"collapseBooleanAttributes": {
|
|
63
|
+
"description": "Omit attribute values from boolean attributes",
|
|
64
|
+
"type": "boolean"
|
|
65
|
+
},
|
|
66
|
+
"collapseInlineTagWhitespace": {
|
|
67
|
+
"description": "Collapse whitespace more aggressively between inline elements—use with `--collapse-whitespace`",
|
|
68
|
+
"type": "boolean"
|
|
69
|
+
},
|
|
70
|
+
"collapseWhitespace": {
|
|
71
|
+
"description": "Collapse whitespace that contributes to text nodes in a document tree",
|
|
72
|
+
"type": "boolean"
|
|
73
|
+
},
|
|
74
|
+
"conservativeCollapse": {
|
|
75
|
+
"description": "Always collapse to one space (never remove it entirely)—use with `--collapse-whitespace`",
|
|
76
|
+
"type": "boolean"
|
|
77
|
+
},
|
|
78
|
+
"continueOnMinifyError": {
|
|
79
|
+
"description": "Continue on minification errors",
|
|
80
|
+
"type": "boolean"
|
|
81
|
+
},
|
|
82
|
+
"continueOnParseError": {
|
|
83
|
+
"description": "Handle parse errors instead of aborting",
|
|
84
|
+
"type": "boolean"
|
|
85
|
+
},
|
|
86
|
+
"customAttrAssign": {
|
|
87
|
+
"description": "Array of regexes that allow to support custom attribute assign expressions (e.g., `<div flex?=\"{{mode != cover}}\"></div>`)",
|
|
88
|
+
"type": [
|
|
89
|
+
"string",
|
|
90
|
+
"array"
|
|
91
|
+
],
|
|
92
|
+
"items": {
|
|
93
|
+
"type": "string"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"customAttrCollapse": {
|
|
97
|
+
"description": "Regex that specifies custom attribute to strip newlines from (e.g., `/ng-class/`)",
|
|
98
|
+
"type": "string"
|
|
99
|
+
},
|
|
100
|
+
"customAttrSurround": {
|
|
101
|
+
"description": "Array of regexes that allow to support custom attribute surround expressions (e.g., `<input {{#if value}}checked=\"checked\"{{/if}}>`)",
|
|
102
|
+
"type": [
|
|
103
|
+
"string",
|
|
104
|
+
"array"
|
|
105
|
+
],
|
|
106
|
+
"items": {
|
|
107
|
+
"type": "string"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"customEventAttributes": {
|
|
111
|
+
"description": "Array of regexes that allow to support custom event attributes for minifyJS (e.g., `ng-click`)",
|
|
112
|
+
"type": [
|
|
113
|
+
"string",
|
|
114
|
+
"array"
|
|
115
|
+
],
|
|
116
|
+
"items": {
|
|
117
|
+
"type": "string"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"customFragmentQuantifierLimit": {
|
|
121
|
+
"description": "Set maximum quantifier limit for custom fragments to prevent ReDoS attacks (default: 200)",
|
|
122
|
+
"type": "integer",
|
|
123
|
+
"minimum": 0
|
|
124
|
+
},
|
|
125
|
+
"decodeEntities": {
|
|
126
|
+
"description": "Use direct Unicode characters whenever possible",
|
|
127
|
+
"type": "boolean"
|
|
128
|
+
},
|
|
129
|
+
"ignoreCustomComments": {
|
|
130
|
+
"description": "Array of regexes that allow to ignore matching comments",
|
|
131
|
+
"type": [
|
|
132
|
+
"string",
|
|
133
|
+
"array"
|
|
134
|
+
],
|
|
135
|
+
"items": {
|
|
136
|
+
"type": "string"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"ignoreCustomFragments": {
|
|
140
|
+
"description": "Array of regexes that allow to ignore certain fragments, when matched (e.g., `<?php … ?>`, `{{ … }}`)",
|
|
141
|
+
"type": [
|
|
142
|
+
"string",
|
|
143
|
+
"array"
|
|
144
|
+
],
|
|
145
|
+
"items": {
|
|
146
|
+
"type": "string"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"includeAutoGeneratedTags": {
|
|
150
|
+
"description": "Insert elements generated by HTML parser",
|
|
151
|
+
"type": "boolean"
|
|
152
|
+
},
|
|
153
|
+
"inlineCustomElements": {
|
|
154
|
+
"description": "Array of names of custom elements which are inline, for whitespace handling",
|
|
155
|
+
"type": [
|
|
156
|
+
"string",
|
|
157
|
+
"array"
|
|
158
|
+
],
|
|
159
|
+
"items": {
|
|
160
|
+
"type": "string"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"keepClosingSlash": {
|
|
164
|
+
"description": "Keep the trailing slash on void elements",
|
|
165
|
+
"type": "boolean"
|
|
166
|
+
},
|
|
167
|
+
"maxInputLength": {
|
|
168
|
+
"description": "Maximum input length to prevent ReDoS attacks",
|
|
169
|
+
"type": "integer",
|
|
170
|
+
"minimum": 0
|
|
171
|
+
},
|
|
172
|
+
"maxLineLength": {
|
|
173
|
+
"description": "Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points",
|
|
174
|
+
"type": "integer",
|
|
175
|
+
"minimum": 0
|
|
176
|
+
},
|
|
177
|
+
"mergeScripts": {
|
|
178
|
+
"description": "Merge consecutive inline `script` elements into one",
|
|
179
|
+
"type": "boolean"
|
|
180
|
+
},
|
|
181
|
+
"minifyCSS": {
|
|
182
|
+
"description": "Minify CSS in `style` elements and attributes (uses Lightning CSS)",
|
|
183
|
+
"type": [
|
|
184
|
+
"boolean",
|
|
185
|
+
"string",
|
|
186
|
+
"object"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
"minifyJS": {
|
|
190
|
+
"description": "Minify JavaScript in `script` elements and event attributes (uses Terser or SWC; pass `{\"engine\": \"swc\"}` for SWC)",
|
|
191
|
+
"type": [
|
|
192
|
+
"boolean",
|
|
193
|
+
"string",
|
|
194
|
+
"object"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
"minifySVG": {
|
|
198
|
+
"description": "Minify SVG elements (uses SVGO)",
|
|
199
|
+
"type": [
|
|
200
|
+
"boolean",
|
|
201
|
+
"string",
|
|
202
|
+
"object"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
"minifyURLs": {
|
|
206
|
+
"description": "Minify URLs in various attributes",
|
|
207
|
+
"type": [
|
|
208
|
+
"boolean",
|
|
209
|
+
"string",
|
|
210
|
+
"object"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"noNewlinesBeforeTagClose": {
|
|
214
|
+
"description": "Never add a newline before a tag that closes an element",
|
|
215
|
+
"type": "boolean"
|
|
216
|
+
},
|
|
217
|
+
"partialMarkup": {
|
|
218
|
+
"description": "Treat input as a partial HTML fragment, preserving stray end tags and unclosed tags",
|
|
219
|
+
"type": "boolean"
|
|
220
|
+
},
|
|
221
|
+
"preserveLineBreaks": {
|
|
222
|
+
"description": "Always collapse to one line break (never remove it entirely) when whitespace between tags includes a line break—use with `--collapse-whitespace`",
|
|
223
|
+
"type": "boolean"
|
|
224
|
+
},
|
|
225
|
+
"preventAttributesEscaping": {
|
|
226
|
+
"description": "Prevents the escaping of the values of attributes",
|
|
227
|
+
"type": "boolean"
|
|
228
|
+
},
|
|
229
|
+
"processScripts": {
|
|
230
|
+
"description": "Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.)",
|
|
231
|
+
"type": [
|
|
232
|
+
"string",
|
|
233
|
+
"array"
|
|
234
|
+
],
|
|
235
|
+
"items": {
|
|
236
|
+
"type": "string"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"quoteCharacter": {
|
|
240
|
+
"description": "Type of quote to use for attribute values (`'` or `\"`)",
|
|
241
|
+
"type": "string"
|
|
242
|
+
},
|
|
243
|
+
"removeAttributeQuotes": {
|
|
244
|
+
"description": "Remove quotes around attributes when possible",
|
|
245
|
+
"type": "boolean"
|
|
246
|
+
},
|
|
247
|
+
"removeComments": {
|
|
248
|
+
"description": "Strip HTML comments",
|
|
249
|
+
"type": "boolean"
|
|
250
|
+
},
|
|
251
|
+
"removeDefaultTypeAttributes": {
|
|
252
|
+
"description": "Remove default `type` attributes from `style`/`link` (e.g., `type=\"text/css\"`) and `script` (e.g., `type=\"text/javascript\"`) elements; other `type` attribute values are left intact",
|
|
253
|
+
"type": "boolean"
|
|
254
|
+
},
|
|
255
|
+
"removeEmptyAttributes": {
|
|
256
|
+
"description": "Remove all attributes with whitespace-only values",
|
|
257
|
+
"type": "boolean"
|
|
258
|
+
},
|
|
259
|
+
"removeEmptyElements": {
|
|
260
|
+
"description": "Remove all elements with empty contents",
|
|
261
|
+
"type": "boolean"
|
|
262
|
+
},
|
|
263
|
+
"removeEmptyElementsExcept": {
|
|
264
|
+
"description": "Array of elements to preserve when `--remove-empty-elements` is enabled (e.g., `td`, `<span aria-hidden=\"true\">`)",
|
|
265
|
+
"type": [
|
|
266
|
+
"string",
|
|
267
|
+
"array"
|
|
268
|
+
],
|
|
269
|
+
"items": {
|
|
270
|
+
"type": "string"
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"removeOptionalTags": {
|
|
274
|
+
"description": "Remove optional tags",
|
|
275
|
+
"type": "boolean"
|
|
276
|
+
},
|
|
277
|
+
"removeRedundantAttributes": {
|
|
278
|
+
"description": "Remove attributes when value matches default",
|
|
279
|
+
"type": "boolean"
|
|
280
|
+
},
|
|
281
|
+
"removeTagWhitespace": {
|
|
282
|
+
"description": "Remove space between attributes whenever possible; note that this will result in invalid HTML",
|
|
283
|
+
"type": "boolean"
|
|
284
|
+
},
|
|
285
|
+
"sortAttributes": {
|
|
286
|
+
"description": "Sort attributes by frequency",
|
|
287
|
+
"type": "boolean"
|
|
288
|
+
},
|
|
289
|
+
"sortClassNames": {
|
|
290
|
+
"description": "Sort style classes by frequency",
|
|
291
|
+
"type": "boolean"
|
|
292
|
+
},
|
|
293
|
+
"trimCustomFragments": {
|
|
294
|
+
"description": "Trim whitespace around custom fragments (`--ignore-custom-fragments`)",
|
|
295
|
+
"type": "boolean"
|
|
296
|
+
},
|
|
297
|
+
"useShortDoctype": {
|
|
298
|
+
"description": "Replaces the doctype with the short HTML doctype",
|
|
299
|
+
"type": "boolean"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
"additionalProperties": false
|
|
303
|
+
}
|
package/package.json
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
},
|
|
15
15
|
"description": "Super-configurable and well-tested web page minifier (enhanced successor to HTML Minifier)",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@commitlint/cli": "^21.0
|
|
17
|
+
"@commitlint/cli": "^21.2.0",
|
|
18
18
|
"@eslint/js": "^10.0.1",
|
|
19
|
-
"@swc/core": "^1.15.
|
|
20
|
-
"@types/node": "^
|
|
21
|
-
"eslint": "^10.
|
|
19
|
+
"@swc/core": "^1.15.41",
|
|
20
|
+
"@types/node": "^26.1.0",
|
|
21
|
+
"eslint": "^10.6.0",
|
|
22
22
|
"typescript": "^6.0.3",
|
|
23
|
-
"vite": "^8.0.
|
|
23
|
+
"vite": "^8.0.16"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=22"
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"cli.js",
|
|
37
|
+
"html-minifier-next.schema.json",
|
|
37
38
|
"dist/types/",
|
|
38
39
|
"src/"
|
|
39
40
|
],
|
|
@@ -78,8 +79,9 @@
|
|
|
78
79
|
"url": "git+https://github.com/j9t/html-minifier-next.git"
|
|
79
80
|
},
|
|
80
81
|
"scripts": {
|
|
81
|
-
"build": "tsc",
|
|
82
|
+
"build": "tsc && npm run build:schema",
|
|
82
83
|
"build:docs": "vite build --base /html-minifier-next/",
|
|
84
|
+
"build:schema": "node scripts/build-schema.js",
|
|
83
85
|
"deploy": "npm run build && npm run build:docs",
|
|
84
86
|
"lint": "eslint .",
|
|
85
87
|
"prebuild": "node --input-type=module --eval \"import {rmSync} from 'fs';rmSync('dist',{recursive:true,force:true})\"",
|
|
@@ -91,5 +93,5 @@
|
|
|
91
93
|
"test:watch": "node --test --watch tests/*.spec.js"
|
|
92
94
|
},
|
|
93
95
|
"type": "module",
|
|
94
|
-
"version": "7.
|
|
96
|
+
"version": "7.2.0"
|
|
95
97
|
}
|
package/src/lib/attributes.js
CHANGED
|
@@ -303,7 +303,8 @@ function isMediaQuery(tag, attrs, attrName) {
|
|
|
303
303
|
* @param {string} tag
|
|
304
304
|
*/
|
|
305
305
|
function isSrcset(attrName, tag) {
|
|
306
|
-
return attrName === 'srcset' && srcsetElements.has(tag)
|
|
306
|
+
return (attrName === 'srcset' && srcsetElements.has(tag)) ||
|
|
307
|
+
(attrName === 'imagesrcset' && tag === 'link');
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
/**
|
|
@@ -492,8 +493,34 @@ function cleanAttributeValue(tag, attrName, attrValue, options, attrs, minifyHTM
|
|
|
492
493
|
}
|
|
493
494
|
|
|
494
495
|
if (isSrcset(attrName, tag)) {
|
|
495
|
-
//
|
|
496
|
-
|
|
496
|
+
// Split into image candidate strings following the spec parsing algorithm
|
|
497
|
+
// (https://html.spec.whatwg.org/multipage/images.html#parsing-a-srcset-attribute);
|
|
498
|
+
// a naive split on commas would corrupt URLs that contain commas
|
|
499
|
+
const value = trimWhitespace(attrValue);
|
|
500
|
+
/** @type {string[]} */
|
|
501
|
+
const candidates = [];
|
|
502
|
+
let pos = 0;
|
|
503
|
+
while (pos < value.length) {
|
|
504
|
+
// Skip whitespace and separator commas
|
|
505
|
+
while (pos < value.length && /[\s,]/.test(value.charAt(pos))) pos++;
|
|
506
|
+
if (pos >= value.length) break;
|
|
507
|
+
const start = pos;
|
|
508
|
+
// URL: a run of non-whitespace characters (which may contain commas)
|
|
509
|
+
while (pos < value.length && !/\s/.test(value.charAt(pos))) pos++;
|
|
510
|
+
if (value.charAt(pos - 1) === ',') {
|
|
511
|
+
// Trailing comma(s) end the candidate—a URL without descriptor
|
|
512
|
+
candidates.push(value.slice(start, pos).replace(/,+$/, ''));
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
// Descriptor: everything up to the next comma outside parentheses
|
|
516
|
+
let inParens = false;
|
|
517
|
+
while (pos < value.length && (inParens || value.charAt(pos) !== ',')) {
|
|
518
|
+
if (value.charAt(pos) === '(') inParens = true;
|
|
519
|
+
else if (value.charAt(pos) === ')') inParens = false;
|
|
520
|
+
pos++;
|
|
521
|
+
}
|
|
522
|
+
candidates.push(trimWhitespace(value.slice(start, pos)));
|
|
523
|
+
}
|
|
497
524
|
const processed = candidates.map(candidate => {
|
|
498
525
|
let url = candidate;
|
|
499
526
|
let descriptor = '';
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
// Single source of truth for minifier option names, descriptions, types, and shared defaults
|
|
2
2
|
|
|
3
3
|
const optionDefinitions = {
|
|
4
|
+
cacheCSS: {
|
|
5
|
+
description: 'Set CSS minification cache size (number of entries, default: 500)',
|
|
6
|
+
type: 'int'
|
|
7
|
+
},
|
|
8
|
+
cacheJS: {
|
|
9
|
+
description: 'Set JavaScript minification cache size (number of entries, default: 500)',
|
|
10
|
+
type: 'int'
|
|
11
|
+
},
|
|
12
|
+
cacheSVG: {
|
|
13
|
+
description: 'Set SVG minification cache size (number of entries, default: 500)',
|
|
14
|
+
type: 'int'
|
|
15
|
+
},
|
|
4
16
|
caseSensitive: {
|
|
5
17
|
description: 'Treat attributes in case-sensitive manner (useful for custom HTML elements)',
|
|
6
18
|
type: 'boolean'
|
package/src/lib/options.js
CHANGED
|
@@ -50,7 +50,7 @@ function shouldMinifyInnerHTML(options) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// User-facing option keys that are valid but not listed in `optionDefinitions`
|
|
53
|
-
const optionKeysExtra = new Set(['preset', 'log', 'canCollapseWhitespace', 'canTrimWhitespace'
|
|
53
|
+
const optionKeysExtra = new Set(['preset', 'log', 'canCollapseWhitespace', 'canTrimWhitespace']);
|
|
54
54
|
|
|
55
55
|
// Unknown option keys and preset names already warned about—warn once per
|
|
56
56
|
// key per process, so repeated `minify` calls (e.g., batch runs) don’t flood STDERR
|