html-minifier-next 8.3.1 → 8.4.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 CHANGED
@@ -36,6 +36,7 @@ Use `npx html-minifier-next --help` to check all available options:
36
36
  | `--input-dir <dir>`, `-I <dir>` | Specify an input directory | `--input-dir=src` |
37
37
  | `--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` |
38
38
  | `--output-dir <dir>`, `-O <dir>` | Specify an output directory | `--output-dir=dist` |
39
+ | `--workers <n>`, `-w <n>` | Number of worker threads for multi-file runs; defaults to half the available cores, at most 6, for runs of 128 files or more (below that threads cost more than they save) | `--workers=4` |
39
40
  | `--input <file>`, `-i <file>` | Specify input file (alternative to positional argument; pair with `--output` for file output) | `npx html-minifier-next -i input.html -o output.html` |
40
41
  | `--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
42
  | `--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='*'` |
@@ -337,7 +338,9 @@ const result = await minify(html, {
337
338
  **Available engines:**
338
339
 
339
340
  * `terser` (default): The standard JavaScript minifier with excellent compression
340
- * [`swc`](https://swc.rs/): Rust-based minifier that’s significantly faster than Terser (requires separate installation)
341
+ * [`swc`](https://swc.rs/): Rust-based minifier multiple times faster than Terser (requires separate installation)
342
+
343
+ The engine also decides how work is scheduled: SWC minifies a document’s script bodies as one batch dispatched ahead of the parse, while Terser shares the thread the parse runs on.
341
344
 
342
345
  **To use SWC**, install it as a development dependency:
343
346
 
@@ -466,7 +469,7 @@ npx html-minifier-next --minify-css --minify-js --minify-svg input.html
466
469
  **Important:**
467
470
 
468
471
  * 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.
469
- * 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`.
472
+ * Values: `0` switches the cache off; negative and non-finite values fall back to the default size.
470
473
  * Entry size cap: Individual CSS, JavaScript, or SVG blocks larger than 1 MB are minified normally but not stored in the cache—this bounds worst-case cache memory without affecting realistically sized inline content. (This cutoff is fixed and not configurable.)
471
474
 
472
475
  The caches persist across multiple `minify()` calls, making them particularly effective when processing many files in a batch operation.
@@ -735,17 +738,20 @@ npm i;
735
738
  npm run benchmark
736
739
  ```
737
740
 
738
- It reuses the backtest corpus (run `npm run backtest` once to download it) and reports per-file output size and median processing time.
741
+ It reuses the backtest corpus (run `npm run backtest` once to download it) and reports per-file output size and processing time.
739
742
 
740
743
  Parameters:
741
744
 
742
745
  * No argument: Runs and, if a baseline exists, shows size and time deltas
743
746
  * `--save`: Saves the run as the baseline (e.g., on `main` before switching to a branch)
744
747
  * `--core`: Disables the external minifiers (CSS, JS, SVG, URLs) to isolate HMN’s processing time
745
- * `--iterations=N`: Sets the number of timed iterations (default 5; the median is reported)
746
- * `--config=PATH`: Uses an alternative options file (default html-minifier-next.config.json)
748
+ * `--cold`: Switches the minification caches off so CSS, JS, and SVG work is redone on every iteration—without it, warm caches serve those results from memory after the warm-up run and the benchmark cannot see changes to those minifiers
749
+ * `--iterations=N`: Sets the number of timed iterations (default: 5)
750
+ * `--config=PATH`: Uses an alternative options file (default: html-minifier-next.config.json)
751
+
752
+ 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 rather than bundled minifiers, or `--cold` when measuring changes to the CSS, JS, or SVG minification paths.
747
753
 
748
- 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 rather than bundled minifiers.
754
+ Reported times are the *fastest* iteration, not the median: Interference can only make a run slower, so the minimum is the most stable estimate. Each run also reports its noise—how far the reported figure moves between the first and second half of the iterations—and any delta smaller than that is marked `within noise` rather than shown as a win or a regression. Raise `--iterations` until the noise sits below the change you are trying to measure.
749
755
 
750
756
  #### Profiling
751
757
 
package/cli.js CHANGED
@@ -310,11 +310,12 @@ function normalizeConfig(config) {
310
310
  let config = {};
311
311
  program.option('-z, --zero', '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)');
312
312
  program.option('-I --input-dir <dir>', 'Specify an input directory');
313
- program.option('-X --ignore-dir <patterns>', 'Exclude directories—relative to input directory—from processing (comma-separated), e.g., `libs` or `libs,vendor,node_modules`');
313
+ program.option('-X --ignore-dir <patterns>', 'Exclude directories—relative to input directory—from processing (comma-separated, overrides config file setting)');
314
314
  program.option('-O --output-dir <dir>', 'Specify an output directory');
315
- program.option('-f --file-ext <extensions>', 'Specify file extension(s) to process (comma-separated); defaults to `html,htm,shtml,shtm`; use `*` for all files');
315
+ program.option('-w --workers <n>', 'Number of worker threads for multi-file runs; defaults to half the available cores, at most 6, for runs of 128 files or more (below that threads cost more than they save)', parseValidInt('workers'));
316
+ program.option('-f --file-ext <extensions>', 'Specify file extension(s) to process (comma-separated, overrides config file setting); defaults to `html,htm,shtml,shtm`; use `*` for all files');
316
317
  program.option('-p --preset <name>', `Use a preset configuration (${getPresetNames().join(', ')})`);
317
- program.option('-c --config-file <file>', 'Use config file');
318
+ program.option('-c --config-file <file>', 'Use a configuration file (defaults to html-minifier-next.config.json in the working directory, if present)');
318
319
  program.version(pkg.version, '-V, --version', 'Output the version number');
319
320
  program.helpOption('-h, --help', 'Display help for command');
320
321
 
@@ -478,27 +479,37 @@ program.helpOption('-h, --help', 'Display help for command');
478
479
 
479
480
  // 4. Surface minifier diagnostics when verbose
480
481
  if (programOptions.verbose || programOptions.dry) {
481
- options.log = (/** @type {unknown} */ message) => {
482
- // The hook carries the minifier’s per-call timing as well, which the run's own
483
- // per-file statistics already cover
484
- if (typeof message === 'string' && message.startsWith('minified in: ')) {
485
- return;
486
- }
487
- // Only `continueOnMinifyError` passes `Error` objects, always after leaving the
488
- // offending content unminified—so say that
489
- if (message instanceof Error) {
490
- console.error(` ${MARK_WARNING}Warning: Minification failed, content left as-is: ${message.message || message}${MARK_RESET}`);
491
- } else if (String(message).startsWith('Warning: ') || String(message).startsWith('HTML Minifier Next: ')) {
492
- console.error(` ${MARK_WARNING}${message}${MARK_RESET}`);
493
- } else {
494
- console.error(` ${message}`);
495
- }
496
- };
482
+ options.log = createLog();
497
483
  }
498
484
 
499
485
  return options;
500
486
  }
501
487
 
488
+ /**
489
+ * Diagnostics name no file of their own, so a run over a directory—where several are in
490
+ * flight at once and lines interleave—says which file each came from
491
+ * @param {string} [fileLabel]
492
+ */
493
+ function createLog(fileLabel) {
494
+ const where = fileLabel ? ` (${fileLabel})` : '';
495
+ return (/** @type {unknown} */ message) => {
496
+ // The hook carries the minifier’s per-call timing as well, which the run's own
497
+ // per-file statistics already cover
498
+ if (typeof message === 'string' && message.startsWith('minified in: ')) {
499
+ return;
500
+ }
501
+ // Only `continueOnMinifyError` passes `Error` objects, always after leaving the
502
+ // offending content unminified—so say that
503
+ if (message instanceof Error) {
504
+ console.error(` ${MARK_WARNING}Warning: Minification failed, content left as-is: ${message.message || message}${where}${MARK_RESET}`);
505
+ } else if (String(message).startsWith('Warning: ') || String(message).startsWith('HTML Minifier Next: ')) {
506
+ console.error(` ${MARK_WARNING}${message}${where}${MARK_RESET}`);
507
+ } else {
508
+ console.error(` ${message}${where}`);
509
+ }
510
+ };
511
+ }
512
+
502
513
  /** @param {Record<string, unknown>} minifierOptions */
503
514
  function getActiveOptionsDisplay(minifierOptions) {
504
515
  const presetName = programOptions.preset || config.preset;
@@ -518,14 +529,71 @@ program.helpOption('-h, --help', 'Display help for command');
518
529
  * @param {string} minified
519
530
  */
520
531
  function calculateStats(original, minified) {
521
- const originalSize = Buffer.byteLength(original, 'utf8');
522
- const minifiedSize = Buffer.byteLength(minified, 'utf8');
532
+ return calculateSizeStats(Buffer.byteLength(original, 'utf8'), Buffer.byteLength(minified, 'utf8'));
533
+ }
534
+
535
+ /**
536
+ * @param {number} originalSize
537
+ * @param {number} minifiedSize
538
+ */
539
+ function calculateSizeStats(originalSize, minifiedSize) {
523
540
  const saved = originalSize - minifiedSize;
524
541
  const sign = saved >= 0 ? '-' : '+';
525
542
  const percentage = originalSize ? ((Math.abs(saved) / originalSize) * 100).toFixed(1) : '0.0';
526
543
  return { originalSize, minifiedSize, saved, sign, percentage };
527
544
  }
528
545
 
546
+ // Below this many files the threads spend more time warming up than they save: Each
547
+ // runs its own isolate and so warms its own JIT, which a short run never earns back
548
+ const FILES_PER_RUN_MIN = 128;
549
+ // Each worker warms up its own JIT, so the useful count tops out well short of the cores
550
+ const WORKERS_MAX = 6;
551
+
552
+ /**
553
+ * A pool for this run, or `null` where one wouldn’t pay or wouldn’t work—in which case
554
+ * the caller minifies in process exactly as before
555
+ * @param {number} fileCount
556
+ */
557
+ async function createPool(fileCount) {
558
+ const requested = programOptions.workers;
559
+ // `availableParallelism` reports what this process may actually use, which under a
560
+ // CPU affinity mask—a container, commonly—is less than the machine’s core count
561
+ const isDefault = requested === undefined;
562
+ const size = isDefault
563
+ ? Math.max(1, Math.min(Math.floor(os.availableParallelism() / 2), WORKERS_MAX))
564
+ : requested;
565
+
566
+ // The file count only decides the default; asking for workers outright is the
567
+ // caller’s judgment to make, whatever the run looks like
568
+ if (size <= 1 || (isDefault && fileCount < FILES_PER_RUN_MIN)) {
569
+ return null;
570
+ }
571
+
572
+ // `log` is a closure over this process’s console and is rebuilt inside the worker;
573
+ // anything else unclonable (which the CLI itself never produces) stays in process
574
+ const { log, ...options } = createOptions();
575
+ try {
576
+ structuredClone(options);
577
+ } catch {
578
+ return null;
579
+ }
580
+
581
+ try {
582
+ const { createFilePool } = await import('./src/lib/file-pool.js');
583
+ return createFilePool({
584
+ options,
585
+ size: Math.min(size, fileCount),
586
+ // `log` is only set when the run asks for diagnostics
587
+ onLog: log
588
+ ? (/** @type {string} */ message, /** @type {boolean} */ isError, /** @type {string} */ file) =>
589
+ createLog(path.relative(process.cwd(), file))(isError ? new Error(message) : message)
590
+ : undefined
591
+ });
592
+ } catch {
593
+ return null;
594
+ }
595
+ }
596
+
529
597
  // Print a one-line-per-cache hits/misses/size summary to STDERR, skipping caches
530
598
  // that were never touched (e.g., their minifier is disabled)
531
599
  async function printCacheStats() {
@@ -561,7 +629,11 @@ program.helpOption('-h, --help', 'Display help for command');
561
629
  let minified;
562
630
  try {
563
631
  const minify = await getMinify();
564
- minified = await minify(data, createOptions());
632
+ const fileOptions = createOptions();
633
+ if (fileOptions.log) {
634
+ fileOptions.log = createLog(path.relative(process.cwd(), inputFile));
635
+ }
636
+ minified = await minify(data, fileOptions);
565
637
  } catch (err) {
566
638
  fatal('Minification error on ' + inputFile + '\n' + errorMessage(err));
567
639
  }
@@ -801,22 +873,56 @@ program.helpOption('-h, --help', 'Display help for command');
801
873
  // Collect all files first for bounded parallel processing
802
874
  const list = await collectFiles(inputDir, extensions, skipRootAbs, ignorePatterns, baseDir);
803
875
  const allStats = new Array(list.length);
804
- const concurrency = Math.max(1, Math.min(os.cpus().length || 4, 8));
805
- await runWithConcurrency(list, concurrency, async (inputFile, idx) => {
806
- const rel = path.relative(inputDir, inputFile);
807
- const outFile = path.join(outputDir, rel);
808
- const outDir = path.dirname(outFile);
876
+
877
+ const prepareOutDir = async (/** @type {string} */ inputFile) => {
878
+ const outFile = path.join(outputDir, path.relative(inputDir, inputFile));
809
879
  if (!isDryRun) {
810
- await fs.promises.mkdir(outDir, { recursive: true }).catch(err => {
811
- fatal('Cannot create directory ' + outDir + '\n' + errorMessage(err));
880
+ await fs.promises.mkdir(path.dirname(outFile), { recursive: true }).catch(err => {
881
+ fatal('Cannot create directory ' + path.dirname(outFile) + '\n' + errorMessage(err));
812
882
  });
813
883
  }
814
- const stats = await processFile(inputFile, outFile, isDryRun, isVerbose);
815
- allStats[idx] = stats;
884
+ return outFile;
885
+ };
886
+
887
+ const advanceProgress = () => {
816
888
  if (progress) {
817
889
  progress.current++;
818
890
  updateProgress(progress.current, progress.total);
819
891
  }
892
+ };
893
+
894
+ const pool = await createPool(list.length);
895
+ if (pool) {
896
+ try {
897
+ await Promise.all(list.map(async (inputFile, idx) => {
898
+ const outFile = await prepareOutDir(inputFile);
899
+ const sizes = await pool.run({ inputFile, outputFile: outFile, dryRun: isDryRun })
900
+ .catch(err => {
901
+ // A worker names the step it failed at, so the wording matches what this
902
+ // file would have got had it been minified in this process
903
+ if (err?.stage === 'read') fatal('Cannot read ' + inputFile + '\n' + errorMessage(err));
904
+ if (err?.stage === 'write') fatal('Cannot write ' + outFile + '\n' + errorMessage(err));
905
+ fatal('Minification error on ' + inputFile + '\n' + errorMessage(err));
906
+ });
907
+ const stats = calculateSizeStats(sizes.originalSize, sizes.minifiedSize);
908
+ if (isDryRun || isVerbose) {
909
+ console.error(` ${MARK_SUCCESS}✓${MARK_RESET} ${path.relative(process.cwd(), inputFile)}: ${stats.originalSize.toLocaleString()} → ${stats.minifiedSize.toLocaleString()} bytes (${stats.sign}${Math.abs(stats.saved).toLocaleString()}, ${stats.percentage}%)`);
910
+ }
911
+ allStats[idx] = { originalSize: stats.originalSize, minifiedSize: stats.minifiedSize, saved: stats.saved };
912
+ advanceProgress();
913
+ }));
914
+ } finally {
915
+ await pool.close();
916
+ }
917
+ return allStats.filter(Boolean);
918
+ }
919
+
920
+ const concurrency = Math.max(1, Math.min(os.cpus().length || 4, 8));
921
+ await runWithConcurrency(list, concurrency, async (inputFile, idx) => {
922
+ const outFile = await prepareOutDir(inputFile);
923
+ const stats = await processFile(inputFile, outFile, isDryRun, isVerbose);
924
+ allStats[idx] = stats;
925
+ advanceProgress();
820
926
  });
821
927
  return allStats.filter(Boolean);
822
928
  }
@@ -27,7 +27,7 @@ export type MinifierOptions = {
27
27
  * improve performance for inputs with repeated CSS (e.g., batch processing).
28
28
  * - Cache is created on first `minify()` call and persists for the process lifetime
29
29
  * - Cache size is locked after first call—subsequent calls reuse the same cache
30
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
30
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
31
31
  *
32
32
  * Default: `500`
33
33
  */
@@ -37,7 +37,7 @@ export type MinifierOptions = {
37
37
  * values improve performance for inputs with repeated JavaScript.
38
38
  * - Cache is created on first `minify()` call and persists for the process lifetime
39
39
  * - Cache size is locked after first call—subsequent calls reuse the same cache
40
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
40
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
41
41
  *
42
42
  * Default: `500`
43
43
  */
@@ -47,7 +47,7 @@ export type MinifierOptions = {
47
47
  * values improve performance for inputs with repeated SVG content.
48
48
  * - Cache is created on first `minify()` call and persists for the process lifetime
49
49
  * - Cache size is locked after first call—subsequent calls reuse the same cache
50
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
50
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
51
51
  *
52
52
  * Default: `500`
53
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * HTML attribute parsing, decoding, and minification
3
+ */
1
4
  import type { ProcessedOptions } from './options.js';
2
5
  export type HTMLAttribute = {
3
6
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Regex patterns, element sets, and default configuration
3
+ */
1
4
  declare const RE_WS_START: RegExp;
2
5
  declare const RE_WS_END: RegExp;
3
6
  declare const RE_WS_ONLY: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * CSS and script content wrapping for minification
3
+ */
1
4
  import type { ProcessedOptions } from './options.js';
2
5
  /** @import { ProcessedOptions } from './options.js' */
3
6
  /**
@@ -33,5 +36,16 @@ declare function processScript(text: string, options: ProcessedOptions, currentA
33
36
  name: string;
34
37
  value?: string | undefined;
35
38
  }>, minifyHTML: Function): Promise<any>;
36
- export { wrapCSS, unwrapCSS, minifyJson, hasJsonScriptType, processScript };
39
+ /**
40
+ * Collects the bodies of executable inline scripts, in document order, so they can be
41
+ * minified as one batch ahead of the parse. Duplicates are dropped: The minifier is
42
+ * content-keyed, so the same body only needs dispatching once.
43
+ * @param {string} html
44
+ * @returns {Array<{code: string, isModule: boolean}>}
45
+ */
46
+ declare function extractScriptBodies(html: string): Array<{
47
+ code: string;
48
+ isModule: boolean;
49
+ }>;
50
+ export { wrapCSS, unwrapCSS, minifyJson, hasJsonScriptType, extractScriptBodies, processScript };
37
51
  //# sourceMappingURL=content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/content.js"],"names":[],"mappings":"AAKI,OAAQ,KAAA,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAApD,uDAAuD;AAMvD;;;GAGG;AACH,iBAAS,OAAO,CAAC,IAAI,EAHV,MAGU,EAAE,IAAI,AAFxB,CAAsB,EAAd,MAEgB,UAS1B;AAED;;;GAGG;AACH,iBAAS,SAAS,CAAC,IAAI,EAHZ,MAGY,EAAE,IAAI,AAF1B,CAAsB,EAAd,MAEkB,UAW5B;AAKD;;;GAGG;AACH,iBAAS,UAAU,CAAC,IAAI,EAHb,MAGa,EAAE,OAAO,EAFtB;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,WAAU;CAE1B,UAWhC;AAED,2DAA2D;AAC3D,iBAAS,iBAAiB,CAAC,KAAK,EADpB,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAChB,WAU/B;AAED;;;;;GAKG;AACH,iBAAe,aAAa,CAAC,IAAI,EALtB,MAKsB,EAAE,OAAO,EAJ/B,gBAI+B,EAAE,YAAY,EAH7C,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,CAGH,EAAE,UAAU,UAAA,gBAiBnE;AAID,OAAO,EAEL,OAAO,EACP,SAAS,EAGT,UAAU,EACV,iBAAiB,EACjB,aAAa,EACd,CAAC"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/content.js"],"names":[],"mappings":"AAAA;;GAEG;AASC,OAAQ,KAAA,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAApD,uDAAuD;AAMvD;;;GAGG;AACH,iBAAS,OAAO,CAAC,IAAI,EAHV,MAGU,EAAE,IAAI,AAFxB,CAAsB,EAAd,MAEgB,UAS1B;AAED;;;GAGG;AACH,iBAAS,SAAS,CAAC,IAAI,EAHZ,MAGY,EAAE,IAAI,AAF1B,CAAsB,EAAd,MAEkB,UAW5B;AAKD;;;GAGG;AACH,iBAAS,UAAU,CAAC,IAAI,EAHb,MAGa,EAAE,OAAO,EAFtB;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,WAAU;CAE1B,UAWhC;AAED,2DAA2D;AAC3D,iBAAS,iBAAiB,CAAC,KAAK,EADpB,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAChB,WAU/B;AAED;;;;;GAKG;AACH,iBAAe,aAAa,CAAC,IAAI,EALtB,MAKsB,EAAE,OAAO,EAJ/B,gBAI+B,EAAE,YAAY,EAH7C,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,CAGH,EAAE,UAAU,UAAA,gBAiBnE;AAWD;;;;;;GAMG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAHtB,MAGsB,GAFpB,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAC,CAAC,CAsDpD;AAID,OAAO,EAEL,OAAO,EACP,SAAS,EAGT,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACd,CAAC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * HTML element tag omission rules
3
+ */
1
4
  import type { HTMLAttribute } from './attributes.js';
2
5
  import type { ProcessedOptions } from './options.js';
3
6
  /** @import { HTMLAttribute } from './attributes.js' */
@@ -1 +1 @@
1
- {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../../src/lib/elements.js"],"names":[],"mappings":"AAaI,OAAQ,KAAA,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAQ,KAAA,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AADpD,uDAAuD;AACvD,uDAAuD;AAIvD;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,gBAAgB,EAHjC,MAGiC,EAAE,GAAG,EAFtC,MAEsC,WAahD;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,cAAc,EAHhC,MAGgC,EAAE,GAAG,EAFrC,MAEqC,WAQ/C;AAED;;;GAGG;AACH,iBAAS,qBAAqB,CAAC,cAAc,EAHlC,MAGkC,EAAE,GAAG,EAFvC,MAEuC,WAmCjD;AAID;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAHlB,MAGkB,EAAE,KAAK,EAFzB,aAAa,EAEY,WAsCnC;AAED;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAJlB,MAIkB,EAAE,OAAO,EAH3B,gBAG2B,GAFzB;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,GAAC,IAAI,CAgD7E;AAED;;;;GAIG;AACH,iBAAS,8BAA8B,CAAC,KAAK,EAJlC,MAAM,EAI4B,EAAE,OAAO,EAH3C,gBAG2C,GAFzC,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,CAAC,CAoB/E;AAED;;;;;GAKG;AACH,iBAAS,0BAA0B,CAAC,GAAG,EAL5B,MAK4B,EAAE,KAAK,EAJnC,aAAa,EAIsB,EAAE,YAAY,EAHjD,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,CAGjB,GAF/C,OAAO,CAkCnB;AAID,OAAO,EAEL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EAGrB,gBAAgB,EAChB,gBAAgB,EAChB,8BAA8B,EAC9B,0BAA0B,EAC3B,CAAC"}
1
+ {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../../src/lib/elements.js"],"names":[],"mappings":"AAAA;;GAEG;AAeC,OAAQ,KAAA,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAQ,KAAA,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AADpD,uDAAuD;AACvD,uDAAuD;AAIvD;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,gBAAgB,EAHjC,MAGiC,EAAE,GAAG,EAFtC,MAEsC,WAahD;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,cAAc,EAHhC,MAGgC,EAAE,GAAG,EAFrC,MAEqC,WAQ/C;AAED;;;GAGG;AACH,iBAAS,qBAAqB,CAAC,cAAc,EAHlC,MAGkC,EAAE,GAAG,EAFvC,MAEuC,WAmCjD;AAID;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAHlB,MAGkB,EAAE,KAAK,EAFzB,aAAa,EAEY,WAsCnC;AAED;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,GAAG,EAJlB,MAIkB,EAAE,OAAO,EAH3B,gBAG2B,GAFzB;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,GAAC,IAAI,CAgD7E;AAED;;;;GAIG;AACH,iBAAS,8BAA8B,CAAC,KAAK,EAJlC,MAAM,EAI4B,EAAE,OAAO,EAH3C,gBAG2C,GAFzC,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,CAAC,CAoB/E;AAED;;;;;GAKG;AACH,iBAAS,0BAA0B,CAAC,GAAG,EAL5B,MAK4B,EAAE,KAAK,EAJnC,aAAa,EAIsB,EAAE,YAAY,EAHjD,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qCAAkC,IAAI,CAAA;CAAC,CAGjB,GAF/C,OAAO,CAkCnB;AAID,OAAO,EAEL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EAGrB,gBAAgB,EAChB,gBAAgB,EAChB,8BAA8B,EAC9B,0BAA0B,EAC3B,CAAC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Single source of truth for minifier option names, descriptions, types, and shared defaults
3
+ */
1
4
  export type OptionDefinition = {
2
5
  /**
3
6
  * Help text, phrased for the option’s primary CLI form
@@ -1 +1 @@
1
- {"version":3,"file":"option-definitions.d.ts","sourceRoot":"","sources":["../../../src/lib/option-definitions.js"],"names":[],"mappings":"AAGG,YAAkB,gBAAgB,GAClC;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAoB,sBAAsB,AAA1C,CACA,EADW,MAAM,CACjB;;;;IAAmB,IAAI,EAAZ,MAAM,CACnB;CAAA,CAAA;AALD;;;;;GAKG;AAEH,+CAA+C;AAC/C,QAAA,MAAM,iBAAiB,EADZ,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAuMzC,CAAC;AAEF,QAAA,MAAM,cAAc;IAClB,qBAAqB;IACrB,oBAAoB;IAIpB,qBAAqB;IAIrB,wBAAwB;CACzB,CAAC;AAIF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACf,CAAC"}
1
+ {"version":3,"file":"option-definitions.d.ts","sourceRoot":"","sources":["../../../src/lib/option-definitions.js"],"names":[],"mappings":"AAAA;;GAEG;AAGA,YAAkB,gBAAgB,GAClC;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAoB,sBAAsB,AAA1C,CACA,EADW,MAAM,CACjB;;;;IAAmB,IAAI,EAAZ,MAAM,CACnB;CAAA,CAAA;AALD;;;;;GAKG;AAEH,+CAA+C;AAC/C,QAAA,MAAM,iBAAiB,EADZ,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAuMzC,CAAC;AAEF,QAAA,MAAM,cAAc;IAClB,qBAAqB;IACrB,oBAAoB;IAIpB,qBAAqB;IAIrB,wBAAwB;CACzB,CAAC;AAIF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACf,CAAC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Options processing and per-document minification state
3
+ */
1
4
  import { LRU } from './utils.js';
2
5
  import type { MinifierOptions, HTMLAttribute } from '../htmlminifier.js';
3
6
  export type CSSContext = {
@@ -23,6 +26,7 @@ export type ProcessedOptions = Omit<MinifierOptions, 'preset' | 'canCollapseWhit
23
26
  scripts: boolean;
24
27
  } | null;
25
28
  cssContext?: CSSContext;
29
+ parallelJS?: boolean;
26
30
  nameParent?: (name: string) => string;
27
31
  nameHTML?: (name: string) => string;
28
32
  keepClosingSlashHTML?: boolean;
@@ -62,6 +66,7 @@ export type ProcessedOptions = Omit<MinifierOptions, 'preset' | 'canCollapseWhit
62
66
  * minifySVG: ((svgContent: string) => string | Promise<string>) | null,
63
67
  * removeUnusedCSS: {safelist: Array<string | RegExp>, scripts: boolean} | null,
64
68
  * cssContext?: CSSContext,
69
+ * parallelJS?: boolean,
65
70
  * nameParent?: (name: string) => string,
66
71
  * nameHTML?: (name: string) => string,
67
72
  * keepClosingSlashHTML?: boolean,
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAmJ,MAAM,YAAY,CAAC;AAQ9K,OAAQ,KAAA,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AASrE,YAA4D,UAAU,GAA5D;IAAC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAC,CAAY;AAOtE,YAA6C,SAAS,GAA5C;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAC,CAAW;AAUtD,YAiBG,gBAAgB,GAjBT,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,GAAG,sBAAsB,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,CAAC,GAAG;IACvM,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,qBAAqB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO,CAAC;IAC7G,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO,CAAC;IACzG,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3F,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3F,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACrE,eAAe,EAAE;QAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,GAAG,IAAI,CAAC;IAC7E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAkB;AA3CtB,2EAA2E;AAI3E;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,wCAAwC;AACxC,iBAAS,qBAAqB,CAAC,OAAO,EAD1B,gBAC0B,WAUrC;AA+CE,YAAkB,gBAAgB,GAM3B,gBAAgB,EAAE,CAAC;AAZ7B;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;eAYT,kCAAkC,QAAvB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;IAI5C,CAAC;AAYF;;;;GAIG;AACH,QAAA,MAAM,cAAc,iBAJT,eAAe,mGACf;IAAC,eAAe,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,GAAG,SAAS,CAAA;CAAC,KAC5O,gBA2iBZ,CAAC;AAIF,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACf,CAAC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Unused-CSS removal
3
+ */
1
4
  /**
2
5
  * Collect the class names and IDs a document references.
3
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"unused-css.d.ts","sourceRoot":"","sources":["../../../src/lib/unused-css.js"],"names":[],"mappings":"AAwKA;;;;;;;;;;;;;GAaG;AACH,iBAAS,kBAAkB,CAAC,IAAI,EALrB,MAKqB,EAAE,cAAc,EAJrC,OAIqC,EAAE,MAAM,AAHrD,CACA,EADQ,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAGoB,GAF3C,GAAG,CAAC,MAAM,CAAC,CA0FvB;AAED;;;;;;GAMG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EALnB,MAKmB,EAAE,IAAI,EAJzB,GAAG,CAAC,MAAM,CAIe,EAAE,QAAQ,EAHnC,KAAK,CAAC,MAAM,GAAG,MAAM,CAGc,GAFjC,MAAM,EAAE,CAuCpB;AAID;;;;;;;;;;GAUG;AACH,iBAAS,yBAAyB,CAAC,MAAM,EAJ9B,OAAO,GAAG;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAC,GAAG,SAIrC,EAAE,IAAI,AAH5C,CACA,EADQ,CAAC,OAAO,EAAE,MAAM,KAAK,OAGe,GAFlC;IAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,GAAG,IAAI,CAyCvE;AAED,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EAC1B,CAAC"}
1
+ {"version":3,"file":"unused-css.d.ts","sourceRoot":"","sources":["../../../src/lib/unused-css.js"],"names":[],"mappings":"AAAA;;GAEG;AAwKH;;;;;;;;;;;;;GAaG;AACH,iBAAS,kBAAkB,CAAC,IAAI,EALrB,MAKqB,EAAE,cAAc,EAJrC,OAIqC,EAAE,MAAM,AAHrD,CACA,EADQ,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAGoB,GAF3C,GAAG,CAAC,MAAM,CAAC,CA0FvB;AAED;;;;;;GAMG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EALnB,MAKmB,EAAE,IAAI,EAJzB,GAAG,CAAC,MAAM,CAIe,EAAE,QAAQ,EAHnC,KAAK,CAAC,MAAM,GAAG,MAAM,CAGc,GAFjC,MAAM,EAAE,CAuCpB;AAID;;;;;;;;;;GAUG;AACH,iBAAS,yBAAyB,CAAC,MAAM,EAJ9B,OAAO,GAAG;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAC,GAAG,SAIrC,EAAE,IAAI,AAH5C,CACA,EADQ,CAAC,OAAO,EAAE,MAAM,KAAK,OAGe,GAFlC;IAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,GAAG,IAAI,CAyCvE;AAED,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EAC1B,CAAC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * General utility functions
3
+ */
1
4
  /**
2
5
  * @param {unknown} obj
3
6
  * @returns {string}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,iBAAS,eAAe,CAAC,GAAG,EAHjB,OAGiB,GAFf,MAAM,CAYlB;AAID,cAAM,GAAG;IAEA,KAAK;IACL,IAAI;IACJ,IAAI;IACT,mCAAmC;IAC9B,GAAG,EADG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAJjC,YAAY,KAAK,SAAM,EAMtB;IACD,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EADK,MACL,WAUN;IACD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAHI,MAGJ,EAAE,KAAK,EAFH,OAEG,QAOb;IACD,0BAA0B;IAC1B,MAAM,CAAC,GAAG,EADE,MACF,QAA2B;IACrC,6EAA6E;IAC7E,KAAK,IADS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAGxE;CACF;AAKD,QAAA,MAAM,oBAAoB,QAAc,CAAC;AAIzC,0BAA0B;AAC1B,iBAAS,WAAW,CAAC,GAAG,EADZ,MACY,UAOvB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAMtB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAEtB;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,KAAK,EAHd,OAGc,GAFZ,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAIrC;AAED,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAGD,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAID;;;;;;GAMG;AACH,iBAAe,YAAY,CAAC,GAAG,EALpB,MAKoB,EAAE,KAAK,EAJ3B,MAI2B,EAAE,OAAO,UAAA,GAFlC,OAAO,CAAC,MAAM,CAAC,CAe3B;AAID,qCAAqC;AACrC,iBAAS,WAAW,CAAC,KAAK,EADd,MAAM,GAAG,MACK,sBAUzB;AAyYD;;;;;;;;;GASG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAJd,MAIc,GAHZ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAqDlC;AAED;;;;;;;;;GASG;AACH,iBAAS,WAAW,CAAC,OAAO,EAHjB,MAGiB,GAFf,MAAM,CAOlB;AAGE,YAA6D,MAAM,GAAzD;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAA;CAAC,CAE7D;AAqKD;;;;;GAKG;AACH,iBAAS,sBAAsB,CAAC,OAAO,EAL5B,MAAM,GAAG,MAKmB,GAH1B,MAAM,GAAG,IAAI,CAqBzB;AAED;;;;;;;GAOG;AACH,iBAAS,UAAU,CAAC,IAAI,EALb,MAKa,EAAE,GAAG,EAJlB,MAIkB,EAAE,KAAK,AAHjC,CACA,EADQ,MAGuC,GAFrC,MAAM,CAelB;AAID,OAAO,EACL,eAAe,EACf,UAAU,EACV,GAAG,EACH,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,EACR,sBAAsB,EACvB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,iBAAS,eAAe,CAAC,GAAG,EAHjB,OAGiB,GAFf,MAAM,CAYlB;AAID,cAAM,GAAG;IAEA,KAAK;IACL,IAAI;IACJ,IAAI;IACT,mCAAmC;IAC9B,GAAG,EADG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAJjC,YAAY,KAAK,SAAM,EAMtB;IACD,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EADK,MACL,WAUN;IACD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAHI,MAGJ,EAAE,KAAK,EAFH,OAEG,QAOb;IACD,0BAA0B;IAC1B,MAAM,CAAC,GAAG,EADE,MACF,QAA2B;IACrC,6EAA6E;IAC7E,KAAK,IADS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAGxE;CACF;AAKD,QAAA,MAAM,oBAAoB,QAAc,CAAC;AAIzC,0BAA0B;AAC1B,iBAAS,WAAW,CAAC,GAAG,EADZ,MACY,UAOvB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAMtB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAEtB;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,KAAK,EAHd,OAGc,GAFZ,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAIrC;AAED,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAGD,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAID;;;;;;GAMG;AACH,iBAAe,YAAY,CAAC,GAAG,EALpB,MAKoB,EAAE,KAAK,EAJ3B,MAI2B,EAAE,OAAO,UAAA,GAFlC,OAAO,CAAC,MAAM,CAAC,CAe3B;AAID,qCAAqC;AACrC,iBAAS,WAAW,CAAC,KAAK,EADd,MAAM,GAAG,MACK,sBAUzB;AAyYD;;;;;;;;;GASG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAJd,MAIc,GAHZ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAqDlC;AAED;;;;;;;;;GASG;AACH,iBAAS,WAAW,CAAC,OAAO,EAHjB,MAGiB,GAFf,MAAM,CAOlB;AAGE,YAA6D,MAAM,GAAzD;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAA;CAAC,CAE7D;AAqKD;;;;;GAKG;AACH,iBAAS,sBAAsB,CAAC,OAAO,EAL5B,MAAM,GAAG,MAKmB,GAH1B,MAAM,GAAG,IAAI,CAqBzB;AAED;;;;;;;GAOG;AACH,iBAAS,UAAU,CAAC,IAAI,EALb,MAKa,EAAE,GAAG,EAJlB,MAIkB,EAAE,KAAK,AAHjC,CACA,EADQ,MAGuC,GAFrC,MAAM,CAelB;AAID,OAAO,EACL,eAAe,EACf,UAAU,EACV,GAAG,EACH,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,EACR,sBAAsB,EACvB,CAAC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Whitespace trimming and collapsing
3
+ */
1
4
  /** @param {string} str */
2
5
  declare const trimWhitespace: (str: string) => string;
3
6
  /** @param {string} str */
@@ -1 +1 @@
1
- {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAeA,0BAA0B;AAC1B,QAAA,MAAM,cAAc,QADR,MAAM,WAQjB,CAAC;AAIF,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,UAgBjC;AAID;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EANpB,MAMoB,EAAE,OAAO,EAL7B;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAKxD,EAAE,QAAQ,EAJvC,OAIuC,EAAE,SAAS,EAHlD,OAGkD,EAAE,WAAW,AAFvE,CAA8B,EAAtB,OAEuE,UAqFjF;AAoBD;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EATzB,MASyB,EAAE,OAAO,EARlC,MAQkC,EAAE,OAAO,EAP3C,MAO2C,EAAE,SAAS,EANtD,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAMkB,EAAE,SAAS,EALjE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAK6B,EAAE,OAAO,EAJ1E;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAI1B,EAAE,cAAc,EAH1F,GAAG,CAAC,MAAM,CAGgF,EAAE,aAAa,EAFzG,GAAG,CAAC,MAAM,CAE+F,UA4EnH;AASD,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,WAEjC;AAED,0BAA0B;AAC1B,iBAAS,iBAAiB,CAAC,GAAG,EADlB,MACkB,WAE7B;AAID,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EAClB,CAAC"}
1
+ {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,0BAA0B;AAC1B,QAAA,MAAM,cAAc,QADR,MAAM,WAQjB,CAAC;AAIF,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,UAgBjC;AAID;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EANpB,MAMoB,EAAE,OAAO,EAL7B;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAKxD,EAAE,QAAQ,EAJvC,OAIuC,EAAE,SAAS,EAHlD,OAGkD,EAAE,WAAW,AAFvE,CAA8B,EAAtB,OAEuE,UAqFjF;AAoBD;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EATzB,MASyB,EAAE,OAAO,EARlC,MAQkC,EAAE,OAAO,EAP3C,MAO2C,EAAE,SAAS,EANtD,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAMkB,EAAE,SAAS,EALjE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAK6B,EAAE,OAAO,EAJ1E;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAI1B,EAAE,cAAc,EAH1F,GAAG,CAAC,MAAM,CAGgF,EAAE,aAAa,EAFzG,GAAG,CAAC,MAAM,CAE+F,UA4EnH;AASD,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,WAEjC;AAED,0BAA0B;AAC1B,iBAAS,iBAAiB,CAAC,GAAG,EADlB,MACkB,WAE7B;AAID,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EAClB,CAAC"}
package/package.json CHANGED
@@ -17,9 +17,9 @@
17
17
  "@commitlint/cli": "^21.2.2",
18
18
  "@eslint/js": "^10.0.1",
19
19
  "@swc/core": "^1.16.1",
20
- "@types/node": "^26.4.0",
21
- "eslint": "^10.9.1",
22
- "globals": "^17.11.0",
20
+ "@types/node": "^26.4.1",
21
+ "eslint": "^10.10.0",
22
+ "globals": "^17.12.0",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2"
25
25
  },
@@ -95,5 +95,5 @@
95
95
  },
96
96
  "type": "module",
97
97
  "types": "dist/types/htmlminifier.d.ts",
98
- "version": "8.3.1"
98
+ "version": "8.4.0"
99
99
  }
@@ -58,6 +58,7 @@ import {
58
58
 
59
59
  import {
60
60
  hasJsonScriptType,
61
+ extractScriptBodies,
61
62
  processScript
62
63
  } from './lib/content.js';
63
64
 
@@ -103,7 +104,7 @@ import { toFragment, replaceCustomFragments } from './lib/fragments.js';
103
104
  * improve performance for inputs with repeated CSS (e.g., batch processing).
104
105
  * - Cache is created on first `minify()` call and persists for the process lifetime
105
106
  * - Cache size is locked after first call—subsequent calls reuse the same cache
106
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
107
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
107
108
  *
108
109
  * Default: `500`
109
110
  *
@@ -112,7 +113,7 @@ import { toFragment, replaceCustomFragments } from './lib/fragments.js';
112
113
  * values improve performance for inputs with repeated JavaScript.
113
114
  * - Cache is created on first `minify()` call and persists for the process lifetime
114
115
  * - Cache size is locked after first call—subsequent calls reuse the same cache
115
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
116
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
116
117
  *
117
118
  * Default: `500`
118
119
  *
@@ -121,7 +122,7 @@ import { toFragment, replaceCustomFragments } from './lib/fragments.js';
121
122
  * values improve performance for inputs with repeated SVG content.
122
123
  * - Cache is created on first `minify()` call and persists for the process lifetime
123
124
  * - Cache size is locked after first call—subsequent calls reuse the same cache
124
- * - Explicit `0` values are coerced to `1` (minimum functional cache size)
125
+ * - `0` switches the cache off; negative and non-finite values fall back to the default size
125
126
  *
126
127
  * Default: `500`
127
128
  *
@@ -1526,6 +1527,35 @@ async function minifyHTML(value, options, partialMarkup) {
1526
1527
  buffer.push(comment);
1527
1528
  }
1528
1529
 
1530
+ // Inline scripts are minified one at a time as the parse reaches them, which serializes
1531
+ // work the minifier could overlap. Dispatching them all up front turns that into a single
1532
+ // wave the parse then reads results from. Bodies are matched by exact content, so one the
1533
+ // parse asks for in another form simply misses and takes the original path.
1534
+ /** @type {Map<string, Promise<string>> | null} */
1535
+ let jsPrewarmed = null;
1536
+ if (options.parallelJS && options.minifyJS !== identity && !options.processScripts?.length) {
1537
+ const bodies = extractScriptBodies(value);
1538
+ if (bodies.length > 1) {
1539
+ jsPrewarmed = new Map();
1540
+ // `collapseWhitespace` reaches script bodies through the whole-document pass above,
1541
+ // so the parse sees them trimmed; other whitespace modes leave them as they are
1542
+ const trims = Boolean(options.collapseWhitespace) &&
1543
+ !options.conservativeCollapse && !options.preserveLineBreaks;
1544
+ for (const { code, isModule } of bodies) {
1545
+ const body = trims ? code.trim() : code;
1546
+ const key = (isModule ? 'm|' : '|') + body;
1547
+ if (jsPrewarmed.has(key)) {
1548
+ continue;
1549
+ }
1550
+ const pending = Promise.resolve(options.minifyJS(body, false, isModule));
1551
+ // The awaiting consumer reports the failure; a body the parse never asks for
1552
+ // would not have been minified at all, so its failure is not ours to raise
1553
+ pending.catch(() => {});
1554
+ jsPrewarmed.set(key, pending);
1555
+ }
1556
+ }
1557
+ }
1558
+
1529
1559
  // SVG subtree capture: When SVGO is active, record buffer positions for post-processing
1530
1560
  /** @type {Array<{start: number, end: number}>} */
1531
1561
  const svgBlocks = []; // Array of { start, end } buffer indices
@@ -1876,7 +1906,8 @@ async function minifyHTML(value, options, partialMarkup) {
1876
1906
  text = await processScript(text, options, currentAttrs, minifyHTML);
1877
1907
  }
1878
1908
  if (needsMinifyJS) {
1879
- text = await options.minifyJS(text, false, isModuleScript);
1909
+ const prewarmed = jsPrewarmed?.get((isModuleScript ? 'm|' : '|') + text);
1910
+ text = prewarmed ? await prewarmed : await options.minifyJS(text, false, isModuleScript);
1880
1911
  }
1881
1912
  if (needsMinifyCSS) {
1882
1913
  text = await options.minifyCSS(text, undefined, options.cssContext);
@@ -2023,7 +2054,7 @@ function joinResultSegments(results, options, restoreCustom, restoreIgnore) {
2023
2054
  * - Cache sizes are locked after first initialization—subsequent calls use the same caches
2024
2055
  * even if different `cacheCSS`/`cacheJS`/`cacheSVG` options are provided
2025
2056
  * - The first call’s options determine the cache sizes for subsequent calls
2026
- * - Invalid values (NaN, Infinity) fall back to the default size (500); values below `1` are clamped to `1`
2057
+ * - Invalid values (NaN, Infinity, negative) fall back to the default size (500)
2027
2058
  */
2028
2059
  /** @param {MinifierOptions} options */
2029
2060
  function initCaches(options) {
@@ -2041,8 +2072,9 @@ function initCaches(options) {
2041
2072
  return parsed;
2042
2073
  };
2043
2074
 
2044
- // Sanitize a cache size: Non-finite/NaN falls back to `defaultSize`; otherwise clamped to min 1 and floored
2045
- const sanitizeSize = (/** @type {number} */ size) => Number.isFinite(size) ? Math.max(1, Math.floor(size)) : defaultSize;
2075
+ // Non-finite and negative sizes fall back to `defaultSize`, as they do for the
2076
+ // environment variables above
2077
+ const sanitizeSize = (/** @type {number} */ size) => Number.isFinite(size) && size >= 0 ? Math.floor(size) : defaultSize;
2046
2078
 
2047
2079
  // Get cache sizes with precedence: Options > env > default
2048
2080
  const cssSize = options.cacheCSS !== undefined ? options.cacheCSS
package/src/htmlparser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * HTML Parser By John Resig (ejohn.org)
3
- * Modified by Juriy “kangax” Zaytsev
3
+ * Modified by Juriy “kangax” Zaytsev and Jens Oliver Meiert
4
4
  * Original code by Erik Arvidsson, Mozilla Public License
5
5
  * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
6
6
  */
@@ -1,3 +1,7 @@
1
+ /**
2
+ * HTML attribute parsing, decoding, and minification
3
+ */
4
+
1
5
  import {
2
6
  RE_EVENT_ATTR_DEFAULT,
3
7
  RE_CAN_REMOVE_ATTR_QUOTES,
@@ -1,4 +1,6 @@
1
- // Regex patterns (to avoid repeated allocations in hot paths)
1
+ /**
2
+ * Regex patterns, element sets, and default configuration
3
+ */
2
4
 
3
5
  const RE_WS_START = /^[ \n\r\t\f]+/;
4
6
  const RE_WS_END = /[ \n\r\t\f]+$/;
@@ -1,6 +1,12 @@
1
+ /**
2
+ * CSS and script content wrapping for minification
3
+ */
4
+
1
5
  import {
2
6
  jsonScriptTypes
3
7
  } from './constants.js';
8
+ import { isExecutableScript } from './attributes.js';
9
+ import { findTagEnd } from './utils.js';
4
10
  import { trimWhitespace } from './whitespace.js';
5
11
 
6
12
  /** @import { ProcessedOptions } from './options.js' */
@@ -99,6 +105,76 @@ async function processScript(text, options, currentAttrs, minifyHTML) {
99
105
  return text;
100
106
  }
101
107
 
108
+ // A `script` element is walked in three steps rather than matched by one pattern—
109
+ // a pattern spanning the whole element rescans the same text for every candidate
110
+ // tag, which turns markup repeating `<script` or `</script` into a quadratic scan
111
+ const RE_SCRIPT_START = /<script\b/gi;
112
+ // A tag name ends at whitespace, a slash, or the closing bracket, so `</scriptx>` names a
113
+ // different element and leaves the body running, as it does for the parser
114
+ const RE_SCRIPT_END = /<\/script(?=[\s/>])/gi;
115
+ const RE_TYPE_ATTRIBUTE = /(?:^|\s)type\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
116
+
117
+ /**
118
+ * Collects the bodies of executable inline scripts, in document order, so they can be
119
+ * minified as one batch ahead of the parse. Duplicates are dropped: The minifier is
120
+ * content-keyed, so the same body only needs dispatching once.
121
+ * @param {string} html
122
+ * @returns {Array<{code: string, isModule: boolean}>}
123
+ */
124
+ function extractScriptBodies(html) {
125
+ /** @type {Array<{code: string, isModule: boolean}>} */
126
+ const bodies = [];
127
+ const seen = new Set();
128
+
129
+ RE_SCRIPT_START.lastIndex = 0;
130
+ let startTag;
131
+ while ((startTag = RE_SCRIPT_START.exec(html))) {
132
+ const tagEnd = findTagEnd(html, RE_SCRIPT_START.lastIndex);
133
+ if (tagEnd === -1) {
134
+ break;
135
+ }
136
+ // Script content is raw text, so the body runs to the first `</script`—
137
+ // no nesting to account for
138
+ RE_SCRIPT_END.lastIndex = tagEnd + 1;
139
+ const endTag = RE_SCRIPT_END.exec(html);
140
+ if (!endTag) {
141
+ break;
142
+ }
143
+ const closeEnd = html.indexOf('>', RE_SCRIPT_END.lastIndex);
144
+ if (closeEnd === -1) {
145
+ break;
146
+ }
147
+ // Resuming past the element is what keeps every character visited once
148
+ RE_SCRIPT_START.lastIndex = closeEnd + 1;
149
+
150
+ const code = html.slice(tagEnd + 1, endTag.index);
151
+ // Whitespace-only and external scripts carry no work the minifier would do
152
+ if (!code.trim()) {
153
+ continue;
154
+ }
155
+
156
+ const typeMatch = RE_TYPE_ATTRIBUTE.exec(html.slice(startTag.index + '<script'.length, tagEnd));
157
+ /** @type {Array<{name: string, value: string}>} */
158
+ const attrs = typeMatch
159
+ ? [{ name: 'type', value: typeMatch[1] ?? typeMatch[2] ?? typeMatch[3] ?? '' }]
160
+ : [];
161
+ if (!isExecutableScript('script', attrs) || hasJsonScriptType(attrs)) {
162
+ continue;
163
+ }
164
+
165
+ // Module and classic scripts minify differently, so identical bodies in the two
166
+ // modes stay separate entries
167
+ const isModule = trimWhitespace((attrs[0]?.value ?? '')).toLowerCase() === 'module';
168
+ const key = (isModule ? 'm|' : '|') + code;
169
+ if (!seen.has(key)) {
170
+ seen.add(key);
171
+ bodies.push({ code, isModule });
172
+ }
173
+ }
174
+
175
+ return bodies;
176
+ }
177
+
102
178
  // Exports
103
179
 
104
180
  export {
@@ -109,5 +185,6 @@ export {
109
185
  // Scripts
110
186
  minifyJson,
111
187
  hasJsonScriptType,
188
+ extractScriptBodies,
112
189
  processScript
113
190
  };
@@ -1,3 +1,7 @@
1
+ /**
2
+ * HTML element tag omission rules
3
+ */
4
+
1
5
  import {
2
6
  headerElements,
3
7
  descriptionElements,
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Worker pool for whole files, as the CLI’s directory runs need them
3
+ *
4
+ * This pools one kind of work—read a file, minify it, write it—rather than arbitrary
5
+ * tasks: The worker body, the message contract, and the result are all about files. The
6
+ * spawning and queueing below would generalize, but nothing else asks for it yet.
7
+ *
8
+ * Minifying a document is CPU-bound work on one thread, so a run over a directory
9
+ * serializes no matter how the files are awaited. Whole files are the unit handed to
10
+ * workers, which is what makes threads pay here: A document takes long enough that the
11
+ * thread it crosses costs a fraction of a percent, and files share no state, so nothing
12
+ * travels but paths, options, and the resulting sizes.
13
+ *
14
+ * Scaling is bounded by what each thread has to re-learn rather than by the cores: Every
15
+ * worker runs its own isolate and warms up its own JIT, so the useful worker count tops
16
+ * out well short of the core count.
17
+ *
18
+ * Node-only: cli.js loads this module lazily and minifies in process wherever worker
19
+ * threads are unavailable or the options can’t cross a structured clone.
20
+ */
21
+
22
+ import fs from 'node:fs';
23
+ import { isMainThread, parentPort, workerData, Worker } from 'node:worker_threads';
24
+
25
+ // This module is its own worker entry point: The pool spawns it by URL and the branch
26
+ // below runs in the spawned copy. Keeping both halves in one file keeps the message
27
+ // contract in one place. The minifier is imported dynamically so that loading the
28
+ // pool on the main thread doesn’t drag it in; only workers ever pay for it.
29
+ if (!isMainThread && parentPort) {
30
+ const port = parentPort;
31
+ const { minify } = await import('../htmlminifier.js');
32
+ const { options, wantsLog } = workerData;
33
+
34
+ // The pool hands a worker one file at a time, so the file a diagnostic belongs to is
35
+ // simply the one in hand
36
+ let fileCurrent = '';
37
+
38
+ // `log` cannot cross a structured clone, so it is rebuilt here and forwarded, and only
39
+ // where the CLI has somewhere to put it. Whether the minifier logged an `Error` travels
40
+ // with the message: The CLI words those differently, and an error that crossed as a
41
+ // plain string would lose that wording.
42
+ const taskOptions = wantsLog
43
+ ? {
44
+ ...options,
45
+ log: (/** @type {unknown} */ message) => port.postMessage({
46
+ log: message instanceof Error ? message.message : String(message),
47
+ logIsError: message instanceof Error,
48
+ logFile: fileCurrent
49
+ })
50
+ }
51
+ : options;
52
+
53
+ port.on('message', async (/** @type {{id: number, inputFile: string, outputFile: string, dryRun: boolean}} */ task) => {
54
+ // Which step failed decides how the CLI words the failure, and reading and writing
55
+ // name different files
56
+ let stage = 'read';
57
+ try {
58
+ fileCurrent = task.inputFile;
59
+ const data = await fs.promises.readFile(task.inputFile, 'utf8');
60
+ stage = 'minify';
61
+ const minified = await minify(data, taskOptions);
62
+ if (!task.dryRun) {
63
+ stage = 'write';
64
+ await fs.promises.writeFile(task.outputFile, minified, 'utf8');
65
+ }
66
+ port.postMessage({
67
+ id: task.id,
68
+ originalSize: Buffer.byteLength(data, 'utf8'),
69
+ minifiedSize: Buffer.byteLength(minified, 'utf8')
70
+ });
71
+ } catch (err) {
72
+ port.postMessage({ id: task.id, stage, error: err instanceof Error ? err.message : String(err) });
73
+ }
74
+ });
75
+ }
76
+
77
+ const urlWorker = new URL(import.meta.url);
78
+
79
+ /**
80
+ * @param {object} args
81
+ * @param {import('../htmlminifier.js').MinifierOptions} args.options
82
+ * @param {number} args.size
83
+ * @param {((message: string, isError: boolean, file: string) => void) | undefined} [args.onLog]
84
+ */
85
+ export function createFilePool({ options, size, onLog }) {
86
+ /** @type {Worker[]} */
87
+ const workers = [];
88
+ /** @type {Worker[]} */
89
+ const idle = [];
90
+ /** @type {Map<number, {resolve: (value: {originalSize: number, minifiedSize: number}) => void, reject: (reason: Error) => void}>} */
91
+ const pending = new Map();
92
+ /** @type {{task: object, resolve: Function, reject: Function}[]} */
93
+ const queue = [];
94
+ let idNext = 0;
95
+ /** @type {Error | null} */
96
+ let failure = null;
97
+ let closing = false;
98
+ const wantsLog = Boolean(onLog);
99
+
100
+ // A worker that dies takes its task with it, and any task still queued would wait for a
101
+ // turn that never comes; both are failed at once so the run ends rather than hangs
102
+ const failAll = (/** @type {Error} */ err) => {
103
+ failure = err;
104
+ for (const { reject } of pending.values()) reject(err);
105
+ pending.clear();
106
+ for (const item of queue.splice(0)) item.reject(err);
107
+ };
108
+
109
+ for (let i = 0; i < size; i++) {
110
+ // Workers inherit the parent’s `execArgv`, which can carry flags that are invalid for
111
+ // a module worker and would kill it on startup
112
+ const worker = new Worker(urlWorker, { workerData: { options, wantsLog }, execArgv: [] });
113
+ worker.unref();
114
+ worker.on('message', (/** @type {{id?: number, log?: string, logIsError?: boolean, logFile?: string, error?: string, stage?: string, originalSize?: number, minifiedSize?: number}} */ message) => {
115
+ if (message.log !== undefined) {
116
+ onLog?.(message.log, Boolean(message.logIsError), message.logFile ?? '');
117
+ return;
118
+ }
119
+ const entry = pending.get(/** @type {number} */ (message.id));
120
+ pending.delete(/** @type {number} */ (message.id));
121
+ idle.push(worker);
122
+ if (!pending.size && !queue.length) worker.unref();
123
+ drain();
124
+ if (!entry) return;
125
+ if (message.error !== undefined) {
126
+ const err = new Error(message.error);
127
+ // Which step failed rides along so the CLI can word the failure as it does for a
128
+ // file it minified itself
129
+ if (message.stage) /** @type {any} */ (err).stage = message.stage;
130
+ entry.reject(err);
131
+ } else {
132
+ entry.resolve({ originalSize: message.originalSize ?? 0, minifiedSize: message.minifiedSize ?? 0 });
133
+ }
134
+ });
135
+ worker.on('error', failAll);
136
+ // A worker can also go without an `error`—killed for memory, or exiting on its own.
137
+ // Its tasks would then wait forever, so an exit before `close()` ends the run, too
138
+ worker.on('exit', (/** @type {number} */ code) => {
139
+ if (closing || failure) return;
140
+ const index = idle.indexOf(worker);
141
+ if (index !== -1) idle.splice(index, 1);
142
+ failAll(new Error(`Worker stopped unexpectedly (exit code ${code})`));
143
+ });
144
+ workers.push(worker);
145
+ idle.push(worker);
146
+ }
147
+
148
+ function drain() {
149
+ while (idle.length && queue.length) {
150
+ const worker = /** @type {Worker} */ (idle.pop());
151
+ const item = /** @type {{task: object, resolve: Function, reject: Function}} */ (queue.shift());
152
+ const id = idNext++;
153
+ pending.set(id, /** @type {any} */ ({ resolve: item.resolve, reject: item.reject }));
154
+ // Only a worker with something outstanding may hold the process open
155
+ worker.ref();
156
+ worker.postMessage({ ...item.task, id });
157
+ }
158
+ }
159
+
160
+ return {
161
+ /**
162
+ * @param {{inputFile: string, outputFile: string, dryRun: boolean}} task
163
+ * @returns {Promise<{originalSize: number, minifiedSize: number}>}
164
+ */
165
+ run(task) {
166
+ if (failure) return Promise.reject(failure);
167
+ return new Promise((resolve, reject) => {
168
+ queue.push({ task, resolve, reject });
169
+ drain();
170
+ });
171
+ },
172
+ async close() {
173
+ closing = true;
174
+ await Promise.all(workers.map(worker => worker.terminate()));
175
+ }
176
+ };
177
+ }
@@ -1,4 +1,6 @@
1
- // Single source of truth for minifier option names, descriptions, types, and shared defaults
1
+ /**
2
+ * Single source of truth for minifier option names, descriptions, types, and shared defaults
3
+ */
2
4
 
3
5
  /**
4
6
  * @typedef {object} OptionDefinition
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Options processing and per-document minification state
3
+ */
4
+
1
5
  import { createUrlMinifier } from './urls.js';
2
6
  import { LRU, MAX_CACHE_ENTRY_SIZE, stableStringify, hashContent, identity, lowercase, paramCase, replaceAsync, parseRegExp, describeQuantifierRisk, lostFlag } from './utils.js';
3
7
  import { RE_TRAILING_SEMICOLON } from './constants.js';
@@ -45,6 +49,7 @@ import { optionDefinitions, optionDefaults } from './option-definitions.js';
45
49
  * minifySVG: ((svgContent: string) => string | Promise<string>) | null,
46
50
  * removeUnusedCSS: {safelist: Array<string | RegExp>, scripts: boolean} | null,
47
51
  * cssContext?: CSSContext,
52
+ * parallelJS?: boolean,
48
53
  * nameParent?: (name: string) => string,
49
54
  * nameHTML?: (name: string) => string,
50
55
  * keepClosingSlashHTML?: boolean,
@@ -532,6 +537,13 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
532
537
  return text;
533
538
  }
534
539
  };
540
+
541
+ // Whether dispatching script bodies ahead of the parse pays off. It needs a minifier
542
+ // that leaves the main thread—SWC hands work to its own threadpool, where overlapping
543
+ // calls genuinely run at once, while Terser would only compete with the parse for the
544
+ // one thread both share. A user-supplied `minifyJS` is excluded either way—only this
545
+ // wrapper is content-keyed and free of side effects.
546
+ options.parallelJS = engine === 'swc';
535
547
  } else if (key === 'minifyURLs' && typeof option !== 'function') {
536
548
  if (!option) {
537
549
  return;
@@ -1,4 +1,6 @@
1
- // Unused-CSS removal
1
+ /**
2
+ * Unused-CSS removal
3
+ */
2
4
 
3
5
  import { findTagEnd } from './utils.js';
4
6
 
package/src/lib/utils.js CHANGED
@@ -1,4 +1,6 @@
1
- // Stringify for options signatures (sorted keys, shallow, nested objects)
1
+ /**
2
+ * General utility functions
3
+ */
2
4
 
3
5
  /**
4
6
  * @param {unknown} obj
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Whitespace trimming and collapsing
3
+ */
4
+
1
5
  import {
2
6
  RE_WS_START,
3
7
  RE_WS_END,