From 3c713539e2e83bd17b9cf6c694a8e871c3e8b5c7 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sat, 28 Feb 2026 19:37:53 -0500 Subject: [PATCH 1/4] feat(minify): use SWC --- .github/dependabot.yml | 2 +- npm-shrinkwrap.json | 8 ++++++ package.json | 1 + src/generators/legacy-html-all/generate.mjs | 2 +- src/generators/legacy-html/generate.mjs | 2 +- src/generators/web/utils/processing.mjs | 5 +--- src/utils/html-minifier.mjs | 30 +++++++++------------ 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ce3bf491..ff2fcd54 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -62,7 +62,7 @@ updates: - 'recma-*' compiling: patterns: - - '@minify-html/wasm' + - '@swc/html-wasm' - '@rollup/*' - 'rolldown' - 'lightningcss-wasm' diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e8424bd4..89a70bc3 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -14,6 +14,7 @@ "@orama/orama": "^3.1.18", "@orama/ui": "^1.5.4", "@rollup/plugin-virtual": "^3.0.2", + "@swc/html-wasm": "^1.15.17", "acorn": "^8.16.0", "commander": "^14.0.3", "dedent": "^1.7.1", @@ -2464,6 +2465,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@swc/html-wasm": { + "version": "1.15.18", + "resolved": "https://registry.npmjs.org/@swc/html-wasm/-/html-wasm-1.15.18.tgz", + "integrity": "sha512-nABVlYRZjfTJA3bTEf7w6Gu8GgRfFJZqTAJ+ehJzwKtCreMy4QFBGiv3KkCjIjxXg+U8qrpnqgo9SjVOq3lPEw==", + "license": "Apache-2.0" + }, "node_modules/@tailwindcss/node": { "version": "4.1.18", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", @@ -8334,6 +8341,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 3967317b..092a39f1 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@orama/orama": "^3.1.18", "@orama/ui": "^1.5.4", "@rollup/plugin-virtual": "^3.0.2", + "@swc/html-wasm": "^1.15.17", "acorn": "^8.16.0", "commander": "^14.0.3", "dedent": "^1.7.1", diff --git a/src/generators/legacy-html-all/generate.mjs b/src/generators/legacy-html-all/generate.mjs index b9cc3a88..a322445e 100644 --- a/src/generators/legacy-html-all/generate.mjs +++ b/src/generators/legacy-html-all/generate.mjs @@ -63,7 +63,7 @@ export async function generate(input) { }); if (config.minify) { - result = Buffer.from(await minifyHTML(result)); + result = await minifyHTML(result); } if (config.output) { diff --git a/src/generators/legacy-html/generate.mjs b/src/generators/legacy-html/generate.mjs index 6888612d..4126c13c 100644 --- a/src/generators/legacy-html/generate.mjs +++ b/src/generators/legacy-html/generate.mjs @@ -130,7 +130,7 @@ export async function* generate(input, worker) { let result = replaceTemplateValues(apiTemplate, template, config); if (config.minify) { - result = Buffer.from(await minifyHTML(result)); + result = await minifyHTML(result); } await writeFile(join(config.output, `${template.api}.html`), result); diff --git a/src/generators/web/utils/processing.mjs b/src/generators/web/utils/processing.mjs index 902f1c22..14931700 100644 --- a/src/generators/web/utils/processing.mjs +++ b/src/generators/web/utils/processing.mjs @@ -123,10 +123,7 @@ export async function processJSXEntries( .replace('{{speculationRules}}', SPECULATION_RULES) .replace('{{ogTitle}}', title); - const minifiedHtml = await minifyHTML(renderedHtml); - const html = Buffer.from(minifiedHtml); - - return { html, api }; + return { html: await minifyHTML(renderedHtml), api }; }) ); diff --git a/src/utils/html-minifier.mjs b/src/utils/html-minifier.mjs index e3921288..df9729cd 100644 --- a/src/utils/html-minifier.mjs +++ b/src/utils/html-minifier.mjs @@ -1,24 +1,20 @@ -import { minify } from '@minify-html/wasm'; +import { readFile } from 'node:fs/promises'; -const DEFAULT_HTML_MINIFIER_OPTIONS = { - minify_css: true, - minify_js: true, -}; +import { minify, default as initSync } from '@swc/html-wasm'; -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); +// See https://github.com/swc-project/swc/issues/11599 for why we need to load +// the WASM file in this way +await initSync( + readFile(new URL(import.meta.resolve('@swc/html-wasm/wasm_bg.wasm'))) +); /** - * Minifies HTML with project defaults and optional overrides. + * Minifies HTML with project defaults and optional overrides. At the moment, + * swc's defaults are suitable for our needs, but in the event that this changes, + * allowing project defaults is beneficial. * * @param {string} html - * @param {Record} [overrides] + * @param {import('@swc/html-wasm').Options} [options] */ -export const minifyHTML = async (html, overrides = {}) => { - const minified = minify(textEncoder.encode(html), { - ...DEFAULT_HTML_MINIFIER_OPTIONS, - ...overrides, - }); - - return textDecoder.decode(minified); -}; +export const minifyHTML = async (html, options = {}) => + (await minify(html, options)).code; From c42e1928fea34bbf23e9dad0db4d570eb3292416 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Tue, 3 Mar 2026 10:22:26 -0500 Subject: [PATCH 2/4] fixup! --- npm-shrinkwrap.json | 2 +- package.json | 2 +- src/utils/html-minifier.mjs | 10 +--------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 89a70bc3..7469cffe 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -14,7 +14,7 @@ "@orama/orama": "^3.1.18", "@orama/ui": "^1.5.4", "@rollup/plugin-virtual": "^3.0.2", - "@swc/html-wasm": "^1.15.17", + "@swc/html-wasm": "^1.15.18", "acorn": "^8.16.0", "commander": "^14.0.3", "dedent": "^1.7.1", diff --git a/package.json b/package.json index 092a39f1..ccb9b753 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@orama/orama": "^3.1.18", "@orama/ui": "^1.5.4", "@rollup/plugin-virtual": "^3.0.2", - "@swc/html-wasm": "^1.15.17", + "@swc/html-wasm": "^1.15.18", "acorn": "^8.16.0", "commander": "^14.0.3", "dedent": "^1.7.1", diff --git a/src/utils/html-minifier.mjs b/src/utils/html-minifier.mjs index df9729cd..cfc4f0ce 100644 --- a/src/utils/html-minifier.mjs +++ b/src/utils/html-minifier.mjs @@ -1,12 +1,4 @@ -import { readFile } from 'node:fs/promises'; - -import { minify, default as initSync } from '@swc/html-wasm'; - -// See https://github.com/swc-project/swc/issues/11599 for why we need to load -// the WASM file in this way -await initSync( - readFile(new URL(import.meta.resolve('@swc/html-wasm/wasm_bg.wasm'))) -); +import { minify } from '@swc/html-wasm'; /** * Minifies HTML with project defaults and optional overrides. At the moment, From 9aa6204949dc1d986b7b6a45cdae9d533c1dbd6a Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Tue, 3 Mar 2026 12:46:08 -0500 Subject: [PATCH 3/4] Update html-minifier.mjs Co-authored-by: Claudio Wunder --- src/utils/html-minifier.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/html-minifier.mjs b/src/utils/html-minifier.mjs index cfc4f0ce..d0a38adc 100644 --- a/src/utils/html-minifier.mjs +++ b/src/utils/html-minifier.mjs @@ -9,4 +9,4 @@ import { minify } from '@swc/html-wasm'; * @param {import('@swc/html-wasm').Options} [options] */ export const minifyHTML = async (html, options = {}) => - (await minify(html, options)).code; + minify(html, options).then(({ code }) => code) From 73870bbcf3b7ece618bc313148f680704e6162c2 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Tue, 3 Mar 2026 15:13:54 -0500 Subject: [PATCH 4/4] fixup! --- src/utils/html-minifier.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/html-minifier.mjs b/src/utils/html-minifier.mjs index d0a38adc..a32b9d58 100644 --- a/src/utils/html-minifier.mjs +++ b/src/utils/html-minifier.mjs @@ -9,4 +9,4 @@ import { minify } from '@swc/html-wasm'; * @param {import('@swc/html-wasm').Options} [options] */ export const minifyHTML = async (html, options = {}) => - minify(html, options).then(({ code }) => code) + minify(html, options).then(({ code }) => code);