html-minifier-next 4.17.0 → 4.17.2
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 +10 -10
- package/cli.js +2 -1
- package/dist/htmlminifier.cjs +30 -1
- package/dist/htmlminifier.esm.bundle.js +30 -1
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/dist/types/lib/options.d.ts.map +1 -1
- package/dist/types/presets.d.ts +0 -1
- package/dist/types/presets.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/htmlminifier.js +14 -0
- package/src/lib/options.js +17 -0
- package/src/presets.js +0 -1
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ You can use a configuration file to specify options. The file can be either JSON
|
|
|
61
61
|
|
|
62
62
|
**JavaScript module configuration example:**
|
|
63
63
|
|
|
64
|
-
```
|
|
64
|
+
```javascript
|
|
65
65
|
module.exports = {
|
|
66
66
|
collapseWhitespace: true,
|
|
67
67
|
removeComments: true,
|
|
@@ -74,7 +74,7 @@ module.exports = {
|
|
|
74
74
|
|
|
75
75
|
ESM with Node.js ≥16.14:
|
|
76
76
|
|
|
77
|
-
```
|
|
77
|
+
```javascript
|
|
78
78
|
import { minify } from 'html-minifier-next';
|
|
79
79
|
|
|
80
80
|
const result = await minify('<p title="example" id="moo">foo</p>', {
|
|
@@ -86,7 +86,7 @@ console.log(result); // “<p title=example id=moo>foo”
|
|
|
86
86
|
|
|
87
87
|
CommonJS:
|
|
88
88
|
|
|
89
|
-
```
|
|
89
|
+
```javascript
|
|
90
90
|
const { minify, getPreset } = require('html-minifier-next');
|
|
91
91
|
|
|
92
92
|
(async () => {
|
|
@@ -188,7 +188,7 @@ When `minifyCSS` is set to `true`, HTML Minifier Next uses [Lightning CSS](https
|
|
|
188
188
|
|
|
189
189
|
You can pass Lightning CSS configuration options by providing an object:
|
|
190
190
|
|
|
191
|
-
```
|
|
191
|
+
```javascript
|
|
192
192
|
const result = await minify(html, {
|
|
193
193
|
minifyCSS: {
|
|
194
194
|
targets: {
|
|
@@ -211,7 +211,7 @@ Available Lightning CSS options when passed as an object:
|
|
|
211
211
|
|
|
212
212
|
For advanced usage, you can also pass a function:
|
|
213
213
|
|
|
214
|
-
```
|
|
214
|
+
```javascript
|
|
215
215
|
const result = await minify(html, {
|
|
216
216
|
minifyCSS: function(text, type) {
|
|
217
217
|
// `text`: CSS string to minify
|
|
@@ -227,7 +227,7 @@ When `minifyJS` is set to `true`, HTML Minifier Next uses [Terser](https://githu
|
|
|
227
227
|
|
|
228
228
|
You can choose between different JS minifiers using the `engine` field:
|
|
229
229
|
|
|
230
|
-
```
|
|
230
|
+
```javascript
|
|
231
231
|
const result = await minify(html, {
|
|
232
232
|
minifyJS: {
|
|
233
233
|
engine: 'swc', // Use SWC for faster minification
|
|
@@ -253,7 +253,7 @@ npm i @swc/core
|
|
|
253
253
|
|
|
254
254
|
You can pass engine-specific configuration options:
|
|
255
255
|
|
|
256
|
-
```
|
|
256
|
+
```javascript
|
|
257
257
|
// Using Terser with custom options
|
|
258
258
|
const result = await minify(html, {
|
|
259
259
|
minifyJS: {
|
|
@@ -273,7 +273,7 @@ const result = await minify(html, {
|
|
|
273
273
|
|
|
274
274
|
For advanced usage, you can also pass a function:
|
|
275
275
|
|
|
276
|
-
```
|
|
276
|
+
```javascript
|
|
277
277
|
const result = await minify(html, {
|
|
278
278
|
minifyJS: function(text, inline) {
|
|
279
279
|
// `text`: JavaScript string to minify
|
|
@@ -287,7 +287,7 @@ const result = await minify(html, {
|
|
|
287
287
|
|
|
288
288
|
When `minifySVG` is set to `true`, HTML Minifier Next applies SVG-specific optimizations to SVG elements and their attributes. These optimizations are lightweight, fast, and safe:
|
|
289
289
|
|
|
290
|
-
```
|
|
290
|
+
```javascript
|
|
291
291
|
const result = await minify(html, {
|
|
292
292
|
minifySVG: true // Enable with default settings
|
|
293
293
|
});
|
|
@@ -313,7 +313,7 @@ What gets optimized:
|
|
|
313
313
|
|
|
314
314
|
You can customize the optimization behavior by providing an options object:
|
|
315
315
|
|
|
316
|
-
```
|
|
316
|
+
```javascript
|
|
317
317
|
const result = await minify(html, {
|
|
318
318
|
minifySVG: {
|
|
319
319
|
precision: 2, // Use 2 decimal places instead of 3
|
package/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* html-minifier-next CLI tool
|
|
4
5
|
*
|
|
@@ -324,7 +325,7 @@ program.option('--file-ext <extensions>', 'Specify file extension(s) to process
|
|
|
324
325
|
if (presetName) {
|
|
325
326
|
const preset = getPreset(presetName);
|
|
326
327
|
if (!preset) {
|
|
327
|
-
fatal(`Unknown preset
|
|
328
|
+
fatal(`Unknown preset “${presetName}”. Available presets: ${getPresetNames().join(', ')}`);
|
|
328
329
|
}
|
|
329
330
|
Object.assign(options, preset);
|
|
330
331
|
}
|
package/dist/htmlminifier.cjs
CHANGED
|
@@ -778,7 +778,6 @@ const presets = {
|
|
|
778
778
|
comprehensive: {
|
|
779
779
|
caseSensitive: true,
|
|
780
780
|
collapseBooleanAttributes: true,
|
|
781
|
-
collapseInlineTagWhitespace: true,
|
|
782
781
|
collapseWhitespace: true,
|
|
783
782
|
continueOnParseError: true,
|
|
784
783
|
decodeEntities: true,
|
|
@@ -1830,9 +1829,25 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, cssM
|
|
|
1830
1829
|
});
|
|
1831
1830
|
};
|
|
1832
1831
|
|
|
1832
|
+
// Apply preset first if specified (so user options can override preset values)
|
|
1833
|
+
if (inputOptions.preset) {
|
|
1834
|
+
const preset = getPreset(inputOptions.preset);
|
|
1835
|
+
if (preset) {
|
|
1836
|
+
Object.assign(options, preset);
|
|
1837
|
+
} else {
|
|
1838
|
+
const available = getPresetNames().join(', ');
|
|
1839
|
+
console.warn(`HTML Minifier Next: Unknown preset “${inputOptions.preset}”. Available presets: ${available}`);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1833
1843
|
Object.keys(inputOptions).forEach(function (key) {
|
|
1834
1844
|
const option = inputOptions[key];
|
|
1835
1845
|
|
|
1846
|
+
// Skip preset key—it’s already been processed
|
|
1847
|
+
if (key === 'preset') {
|
|
1848
|
+
return;
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1836
1851
|
if (key === 'caseSensitive') {
|
|
1837
1852
|
if (option) {
|
|
1838
1853
|
options.name = identity;
|
|
@@ -3914,6 +3929,20 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
3914
3929
|
text = entities.decodeHTML(text);
|
|
3915
3930
|
}
|
|
3916
3931
|
}
|
|
3932
|
+
// Trim outermost newline-based whitespace inside `pre`/`textarea` elements
|
|
3933
|
+
// This removes trailing newlines often added by template engines before closing tags
|
|
3934
|
+
// Only trims single trailing newlines (multiple newlines are likely intentional formatting)
|
|
3935
|
+
if (options.collapseWhitespace && stackNoTrimWhitespace.length) {
|
|
3936
|
+
const topTag = stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1];
|
|
3937
|
+
if (stackNoTrimWhitespace.includes('pre') || stackNoTrimWhitespace.includes('textarea')) {
|
|
3938
|
+
// Trim trailing whitespace only if it ends with a single newline (not multiple)
|
|
3939
|
+
// Multiple newlines are likely intentional formatting, single newline is often a template artifact
|
|
3940
|
+
// Treat CRLF (`\r\n`), CR (`\r`), and LF (`\n`) as single line-ending units
|
|
3941
|
+
if (nextTag && nextTag === '/' + topTag && /[^\r\n](?:\r\n|\r|\n)[ \t]*$/.test(text)) {
|
|
3942
|
+
text = text.replace(/(?:\r\n|\r|\n)[ \t]*$/, '');
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3917
3946
|
if (options.collapseWhitespace) {
|
|
3918
3947
|
if (!stackNoTrimWhitespace.length) {
|
|
3919
3948
|
if (prevTag === 'comment') {
|
|
@@ -3390,7 +3390,6 @@ const presets = {
|
|
|
3390
3390
|
comprehensive: {
|
|
3391
3391
|
caseSensitive: true,
|
|
3392
3392
|
collapseBooleanAttributes: true,
|
|
3393
|
-
collapseInlineTagWhitespace: true,
|
|
3394
3393
|
collapseWhitespace: true,
|
|
3395
3394
|
continueOnParseError: true,
|
|
3396
3395
|
decodeEntities: true,
|
|
@@ -6972,9 +6971,25 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, cssM
|
|
|
6972
6971
|
});
|
|
6973
6972
|
};
|
|
6974
6973
|
|
|
6974
|
+
// Apply preset first if specified (so user options can override preset values)
|
|
6975
|
+
if (inputOptions.preset) {
|
|
6976
|
+
const preset = getPreset(inputOptions.preset);
|
|
6977
|
+
if (preset) {
|
|
6978
|
+
Object.assign(options, preset);
|
|
6979
|
+
} else {
|
|
6980
|
+
const available = getPresetNames().join(', ');
|
|
6981
|
+
console.warn(`HTML Minifier Next: Unknown preset “${inputOptions.preset}”. Available presets: ${available}`);
|
|
6982
|
+
}
|
|
6983
|
+
}
|
|
6984
|
+
|
|
6975
6985
|
Object.keys(inputOptions).forEach(function (key) {
|
|
6976
6986
|
const option = inputOptions[key];
|
|
6977
6987
|
|
|
6988
|
+
// Skip preset key—it’s already been processed
|
|
6989
|
+
if (key === 'preset') {
|
|
6990
|
+
return;
|
|
6991
|
+
}
|
|
6992
|
+
|
|
6978
6993
|
if (key === 'caseSensitive') {
|
|
6979
6994
|
if (option) {
|
|
6980
6995
|
options.name = identity;
|
|
@@ -9056,6 +9071,20 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
9056
9071
|
text = decodeHTML(text);
|
|
9057
9072
|
}
|
|
9058
9073
|
}
|
|
9074
|
+
// Trim outermost newline-based whitespace inside `pre`/`textarea` elements
|
|
9075
|
+
// This removes trailing newlines often added by template engines before closing tags
|
|
9076
|
+
// Only trims single trailing newlines (multiple newlines are likely intentional formatting)
|
|
9077
|
+
if (options.collapseWhitespace && stackNoTrimWhitespace.length) {
|
|
9078
|
+
const topTag = stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1];
|
|
9079
|
+
if (stackNoTrimWhitespace.includes('pre') || stackNoTrimWhitespace.includes('textarea')) {
|
|
9080
|
+
// Trim trailing whitespace only if it ends with a single newline (not multiple)
|
|
9081
|
+
// Multiple newlines are likely intentional formatting, single newline is often a template artifact
|
|
9082
|
+
// Treat CRLF (`\r\n`), CR (`\r`), and LF (`\n`) as single line-ending units
|
|
9083
|
+
if (nextTag && nextTag === '/' + topTag && /[^\r\n](?:\r\n|\r|\n)[ \t]*$/.test(text)) {
|
|
9084
|
+
text = text.replace(/(?:\r\n|\r|\n)[ \t]*$/, '');
|
|
9085
|
+
}
|
|
9086
|
+
}
|
|
9087
|
+
}
|
|
9059
9088
|
if (options.collapseWhitespace) {
|
|
9060
9089
|
if (!stackNoTrimWhitespace.length) {
|
|
9061
9090
|
if (prevTag === 'comment') {
|
|
@@ -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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"AAYA,6DAUC;AAID;;;;;;;;;;GAUG;AACH,6CAVW,OAAO,CAAC,eAAe,CAAC,0FAEhC;IAAuB,eAAe;IACf,SAAS;IACT,MAAM;CAA2B,GAI9C,eAAe,CA4V3B"}
|
package/dist/types/presets.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export namespace presets {
|
|
|
28
28
|
export let caseSensitive: boolean;
|
|
29
29
|
let collapseBooleanAttributes_1: boolean;
|
|
30
30
|
export { collapseBooleanAttributes_1 as collapseBooleanAttributes };
|
|
31
|
-
export let collapseInlineTagWhitespace: boolean;
|
|
32
31
|
let collapseWhitespace_1: boolean;
|
|
33
32
|
export { collapseWhitespace_1 as collapseWhitespace };
|
|
34
33
|
let continueOnParseError_1: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAMvB;AAED;;;GAGG;AACH,kCAFa,MAAM,EAAE,CAIpB"}
|
package/package.json
CHANGED
|
@@ -15,18 +15,18 @@
|
|
|
15
15
|
},
|
|
16
16
|
"description": "Super-configurable, well-tested, JavaScript-based HTML minifier (enhanced successor of HTML Minifier)",
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@commitlint/cli": "^20.
|
|
18
|
+
"@commitlint/cli": "^20.3.0",
|
|
19
19
|
"@eslint/js": "^9.39.2",
|
|
20
20
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
21
21
|
"@rollup/plugin-json": "^6.1.0",
|
|
22
22
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
23
23
|
"@rollup/plugin-terser": "^0.4.4",
|
|
24
|
-
"@swc/core": "^1.15.
|
|
24
|
+
"@swc/core": "^1.15.8",
|
|
25
25
|
"eslint": "^9.39.2",
|
|
26
|
-
"rollup": "^4.
|
|
26
|
+
"rollup": "^4.55.1",
|
|
27
27
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
28
28
|
"typescript": "^5.9.3",
|
|
29
|
-
"vite": "^7.3.
|
|
29
|
+
"vite": "^7.3.1"
|
|
30
30
|
},
|
|
31
31
|
"exports": {
|
|
32
32
|
".": {
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
},
|
|
99
99
|
"type": "module",
|
|
100
100
|
"types": "./dist/types/htmlminifier.d.ts",
|
|
101
|
-
"version": "4.17.
|
|
101
|
+
"version": "4.17.2"
|
|
102
102
|
}
|
package/src/htmlminifier.js
CHANGED
|
@@ -1088,6 +1088,20 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1088
1088
|
text = decodeHTML(text);
|
|
1089
1089
|
}
|
|
1090
1090
|
}
|
|
1091
|
+
// Trim outermost newline-based whitespace inside `pre`/`textarea` elements
|
|
1092
|
+
// This removes trailing newlines often added by template engines before closing tags
|
|
1093
|
+
// Only trims single trailing newlines (multiple newlines are likely intentional formatting)
|
|
1094
|
+
if (options.collapseWhitespace && stackNoTrimWhitespace.length) {
|
|
1095
|
+
const topTag = stackNoTrimWhitespace[stackNoTrimWhitespace.length - 1];
|
|
1096
|
+
if (stackNoTrimWhitespace.includes('pre') || stackNoTrimWhitespace.includes('textarea')) {
|
|
1097
|
+
// Trim trailing whitespace only if it ends with a single newline (not multiple)
|
|
1098
|
+
// Multiple newlines are likely intentional formatting, single newline is often a template artifact
|
|
1099
|
+
// Treat CRLF (`\r\n`), CR (`\r`), and LF (`\n`) as single line-ending units
|
|
1100
|
+
if (nextTag && nextTag === '/' + topTag && /[^\r\n](?:\r\n|\r|\n)[ \t]*$/.test(text)) {
|
|
1101
|
+
text = text.replace(/(?:\r\n|\r|\n)[ \t]*$/, '');
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1091
1105
|
if (options.collapseWhitespace) {
|
|
1092
1106
|
if (!stackNoTrimWhitespace.length) {
|
|
1093
1107
|
if (prevTag === 'comment') {
|
package/src/lib/options.js
CHANGED
|
@@ -6,6 +6,7 @@ import { RE_TRAILING_SEMICOLON } from './constants.js';
|
|
|
6
6
|
import { canCollapseWhitespace, canTrimWhitespace } from './whitespace.js';
|
|
7
7
|
import { wrapCSS, unwrapCSS } from './content.js';
|
|
8
8
|
import { getSVGMinifierOptions } from './svg.js';
|
|
9
|
+
import { getPreset, getPresetNames } from '../presets.js';
|
|
9
10
|
|
|
10
11
|
// Helper functions
|
|
11
12
|
|
|
@@ -84,9 +85,25 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, cssM
|
|
|
84
85
|
});
|
|
85
86
|
};
|
|
86
87
|
|
|
88
|
+
// Apply preset first if specified (so user options can override preset values)
|
|
89
|
+
if (inputOptions.preset) {
|
|
90
|
+
const preset = getPreset(inputOptions.preset);
|
|
91
|
+
if (preset) {
|
|
92
|
+
Object.assign(options, preset);
|
|
93
|
+
} else {
|
|
94
|
+
const available = getPresetNames().join(', ');
|
|
95
|
+
console.warn(`HTML Minifier Next: Unknown preset “${inputOptions.preset}”. Available presets: ${available}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
Object.keys(inputOptions).forEach(function (key) {
|
|
88
100
|
const option = inputOptions[key];
|
|
89
101
|
|
|
102
|
+
// Skip preset key—it’s already been processed
|
|
103
|
+
if (key === 'preset') {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
90
107
|
if (key === 'caseSensitive') {
|
|
91
108
|
if (option) {
|
|
92
109
|
options.name = identity;
|