feat(core): faster HTML minimizer - siteConfig.future.experimental_faster.swcHtmlMinimizer (#10554)

This commit is contained in:
Sébastien Lorber 2024-10-04 18:26:54 +02:00 committed by GitHub
parent 126d395f2d
commit 912c4954d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 406 additions and 92 deletions

View file

@ -35,6 +35,7 @@
"postcss": "^8.4.26",
"postcss-loader": "^7.3.3",
"file-loader": "^6.2.0",
"html-minifier-terser": "^7.2.0",
"mini-css-extract-plugin": "^2.9.1",
"null-loader": "^4.0.1",
"react-dev-utils": "^12.0.1",

View file

@ -12,11 +12,13 @@ import type {
} from 'terser-webpack-plugin';
import type {MinimizerOptions as CssMinimizerOptions} from 'css-minimizer-webpack-plugin';
async function importFaster() {
type FasterModule = Awaited<typeof import('@docusaurus/faster')>;
async function importFaster(): Promise<FasterModule> {
return import('@docusaurus/faster');
}
async function ensureFaster() {
async function ensureFaster(): Promise<FasterModule> {
try {
return await importFaster();
} catch (error) {
@ -41,6 +43,13 @@ export async function importSwcJsMinimizerOptions(): Promise<
return faster.getSwcJsMinimizerOptions() as JsMinimizerOptions<CustomOptions>;
}
export async function importSwcHtmlMinifier(): Promise<
ReturnType<FasterModule['getSwcHtmlMinifier']>
> {
const faster = await ensureFaster();
return faster.getSwcHtmlMinifier();
}
export async function importLightningCssMinimizerOptions(): Promise<
CssMinimizerOptions<CustomOptions>
> {

View file

@ -15,5 +15,6 @@ export {
} from './currentBundler';
export {getMinimizers} from './minification';
export {getHtmlMinifier, type HtmlMinifier} from './minifyHtml';
export {createJsLoaderFactory} from './loaders/jsLoader';
export {createStyleLoadersFactory} from './loaders/styleLoader';

View file

@ -0,0 +1,148 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import logger from '@docusaurus/logger';
import {minify as terserHtmlMinifier} from 'html-minifier-terser';
import {importSwcHtmlMinifier} from './importFaster';
import type {DocusaurusConfig} from '@docusaurus/types';
// Historical env variable
const SkipHtmlMinification = process.env.SKIP_HTML_MINIFICATION === 'true';
export type HtmlMinifier = {
minify: (html: string) => Promise<string>;
};
const NoopMinifier: HtmlMinifier = {
minify: async (html: string) => html,
};
type SiteConfigSlice = {
future: {
experimental_faster: Pick<
DocusaurusConfig['future']['experimental_faster'],
'swcHtmlMinimizer'
>;
};
};
export async function getHtmlMinifier({
siteConfig,
}: {
siteConfig: SiteConfigSlice;
}): Promise<HtmlMinifier> {
if (SkipHtmlMinification) {
return NoopMinifier;
}
if (siteConfig.future.experimental_faster.swcHtmlMinimizer) {
return getSwcMinifier();
} else {
return getTerserMinifier();
}
}
// Minify html with https://github.com/DanielRuf/html-minifier-terser
async function getTerserMinifier(): Promise<HtmlMinifier> {
return {
minify: async function minifyHtmlWithTerser(html) {
try {
return await terserHtmlMinifier(html, {
removeComments: false,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyJS: true,
});
} catch (err) {
throw new Error(`HTML minification failed (Terser)`, {
cause: err as Error,
});
}
},
};
}
// Minify html with @swc/html
// Not well-documented but fast!
// See https://github.com/swc-project/swc/discussions/9616
async function getSwcMinifier(): Promise<HtmlMinifier> {
const swcHtmlMinifier = await importSwcHtmlMinifier();
return {
minify: async function minifyHtmlWithSwc(html) {
try {
const result = await swcHtmlMinifier(Buffer.from(html), {
// Removing comments can lead to React hydration errors
// See https://x.com/sebastienlorber/status/1841966927440478577
removeComments: false,
// TODO maybe it's fine to only keep <!-- --> React comments?
preserveComments: [],
// Sorting these attributes (class) can lead to React hydration errors
sortSpaceSeparatedAttributeValues: false,
sortAttributes: false,
// @ts-expect-error: bad type https://github.com/swc-project/swc/pull/9615
removeRedundantAttributes: 'all',
removeEmptyAttributes: true,
minifyJs: true,
minifyJson: true,
minifyCss: true,
});
// Escape hatch because SWC is quite aggressive to report errors
// TODO figure out what to do with these errors: throw or swallow?
// See https://github.com/facebook/docusaurus/pull/10554
// See https://github.com/swc-project/swc/discussions/9616#discussioncomment-10846201
const ignoreSwcMinifierErrors =
process.env.DOCUSAURUS_IGNORE_SWC_HTML_MINIFIER_ERRORS === 'true';
if (!ignoreSwcMinifierErrors && result.errors) {
const ignoredErrors: string[] = [
// TODO Docusaurus seems to emit NULL chars, and minifier detects it
// see https://github.com/facebook/docusaurus/issues/9985
'Unexpected null character',
];
result.errors = result.errors.filter(
(diagnostic) => !ignoredErrors.includes(diagnostic.message),
);
if (result.errors.length) {
throw new Error(
`HTML minification diagnostic errors:
- ${result.errors
.map(
(diagnostic) =>
`[${diagnostic.level}] ${
diagnostic.message
} - ${JSON.stringify(diagnostic.span)}`,
)
.join('\n- ')}
Note: please report the problem to the Docusaurus team
In the meantime, you can skip this error with ${logger.code(
'DOCUSAURUS_IGNORE_SWC_HTML_MINIFIER_ERRORS=true',
)}`,
);
}
/*
if (result.errors.length) {
throw new AggregateError(
result.errors.map(
(diagnostic) => new Error(JSON.stringify(diagnostic, null, 2)),
),
);
}
*/
}
return result.code;
} catch (err) {
throw new Error(`HTML minification failed (SWC)`, {
cause: err as Error,
});
}
},
};
}

View file

@ -18,7 +18,8 @@
},
"license": "MIT",
"dependencies": {
"@swc/core": "^1.7.14",
"@swc/core": "^1.7.28",
"@swc/html": "^1.7.28",
"browserslist": "^4.24.0",
"lightningcss": "^1.27.0",
"swc-loader": "^0.2.6",

View file

@ -7,9 +7,14 @@
import * as lightningcss from 'lightningcss';
import browserslist from 'browserslist';
import {minify as swcHtmlMinifier} from '@swc/html';
import type {RuleSetRule} from 'webpack';
import type {JsMinifyOptions} from '@swc/core';
export function getSwcHtmlMinifier(): typeof swcHtmlMinifier {
return swcHtmlMinifier;
}
export function getSwcJsLoaderFactory({
isServer,
}: {

View file

@ -126,6 +126,7 @@ export type StorageConfig = {
export type FasterConfig = {
swcJsLoader: boolean;
swcJsMinimizer: boolean;
swcHtmlMinimizer: boolean;
lightningCssMinimizer: boolean;
mdxCrossCompilerCache: boolean;
rspackBundler: boolean;

View file

@ -53,9 +53,8 @@
"eta": "^2.2.0",
"eval": "^0.1.8",
"fs-extra": "^11.1.1",
"html-minifier-terser": "^7.2.0",
"html-tags": "^3.3.1",
"html-webpack-plugin": "^5.5.3",
"html-webpack-plugin": "^5.6.0",
"leven": "^3.1.0",
"lodash": "^4.17.21",
"p-map": "^4.0.0",

View file

@ -8,7 +8,7 @@
import fs from 'fs-extra';
import path from 'path';
import _ from 'lodash';
import {compile} from '@docusaurus/bundler';
import {compile, getHtmlMinifier} from '@docusaurus/bundler';
import logger, {PerfLogger} from '@docusaurus/logger';
import {DOCUSAURUS_VERSION, mapAsyncSequential} from '@docusaurus/utils';
import {loadSite, loadContext, type LoadContextParams} from '../server/site';
@ -271,17 +271,23 @@ async function executeSSG({
return {collectedData: {}};
}
const renderer = await PerfLogger.async('Load App renderer', () =>
loadAppRenderer({
serverBundlePath,
}),
);
const [renderer, htmlMinifier] = await Promise.all([
PerfLogger.async('Load App renderer', () =>
loadAppRenderer({
serverBundlePath,
}),
),
PerfLogger.async('Load HTML minifier', () =>
getHtmlMinifier({siteConfig: props.siteConfig}),
),
]);
const ssgResult = await PerfLogger.async('Generate static files', () =>
generateStaticFiles({
pathnames: props.routesPaths,
renderer,
params,
htmlMinifier,
}),
);

View file

@ -12,6 +12,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -80,6 +81,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -148,6 +150,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -216,6 +219,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -284,6 +288,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -352,6 +357,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -420,6 +426,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -490,6 +497,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -560,6 +568,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},
@ -633,6 +642,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},

View file

@ -86,6 +86,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
"lightningCssMinimizer": false,
"mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcHtmlMinimizer": false,
"swcJsLoader": false,
"swcJsMinimizer": false,
},

View file

@ -48,6 +48,7 @@ describe('normalizeConfig', () => {
experimental_faster: {
swcJsLoader: true,
swcJsMinimizer: true,
swcHtmlMinimizer: true,
lightningCssMinimizer: true,
mdxCrossCompilerCache: true,
rspackBundler: true,
@ -746,6 +747,7 @@ describe('future', () => {
experimental_faster: {
swcJsLoader: true,
swcJsMinimizer: true,
swcHtmlMinimizer: true,
lightningCssMinimizer: true,
mdxCrossCompilerCache: true,
rspackBundler: true,
@ -1098,6 +1100,7 @@ describe('future', () => {
const faster: FasterConfig = {
swcJsLoader: true,
swcJsMinimizer: true,
swcHtmlMinimizer: true,
lightningCssMinimizer: true,
mdxCrossCompilerCache: true,
rspackBundler: true,
@ -1284,6 +1287,77 @@ describe('future', () => {
});
});
describe('swcHtmlMinimizer', () => {
it('accepts - undefined', () => {
const faster: Partial<FasterConfig> = {
swcHtmlMinimizer: undefined,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({swcHtmlMinimizer: false}));
});
it('accepts - true', () => {
const faster: Partial<FasterConfig> = {
swcHtmlMinimizer: true,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({swcHtmlMinimizer: true}));
});
it('accepts - false', () => {
const faster: Partial<FasterConfig> = {
swcHtmlMinimizer: false,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({swcHtmlMinimizer: false}));
});
it('rejects - null', () => {
// @ts-expect-error: invalid
const faster: Partial<FasterConfig> = {swcHtmlMinimizer: 42};
expect(() =>
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toThrowErrorMatchingInlineSnapshot(`
""future.experimental_faster.swcHtmlMinimizer" must be a boolean
"
`);
});
it('rejects - number', () => {
// @ts-expect-error: invalid
const faster: Partial<FasterConfig> = {swcHtmlMinimizer: 42};
expect(() =>
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toThrowErrorMatchingInlineSnapshot(`
""future.experimental_faster.swcHtmlMinimizer" must be a boolean
"
`);
});
});
describe('lightningCssMinimizer', () => {
it('accepts - undefined', () => {
const faster: Partial<FasterConfig> = {

View file

@ -44,6 +44,7 @@ export const DEFAULT_STORAGE_CONFIG: StorageConfig = {
export const DEFAULT_FASTER_CONFIG: FasterConfig = {
swcJsLoader: false,
swcJsMinimizer: false,
swcHtmlMinimizer: false,
lightningCssMinimizer: false,
mdxCrossCompilerCache: false,
rspackBundler: false,
@ -53,6 +54,7 @@ export const DEFAULT_FASTER_CONFIG: FasterConfig = {
export const DEFAULT_FASTER_CONFIG_TRUE: FasterConfig = {
swcJsLoader: true,
swcJsMinimizer: true,
swcHtmlMinimizer: true,
lightningCssMinimizer: true,
mdxCrossCompilerCache: true,
rspackBundler: true,
@ -223,6 +225,9 @@ const FASTER_CONFIG_SCHEMA = Joi.alternatives()
swcJsMinimizer: Joi.boolean().default(
DEFAULT_FASTER_CONFIG.swcJsMinimizer,
),
swcHtmlMinimizer: Joi.boolean().default(
DEFAULT_FASTER_CONFIG.swcHtmlMinimizer,
),
lightningCssMinimizer: Joi.boolean().default(
DEFAULT_FASTER_CONFIG.lightningCssMinimizer,
),

View file

@ -11,10 +11,10 @@ import path from 'path';
import _ from 'lodash';
import evaluate from 'eval';
import pMap from 'p-map';
import {minify} from 'html-minifier-terser';
import logger, {PerfLogger} from '@docusaurus/logger';
import {renderSSRTemplate} from './templates/templates';
import type {AppRenderer, AppRenderResult, SiteCollectedData} from './common';
import type {HtmlMinifier} from '@docusaurus/bundler';
import type {Manifest} from 'react-loadable-ssr-addon-v5-slorber';
import type {SSRTemplateCompiled} from './templates/templates';
@ -114,10 +114,12 @@ export async function generateStaticFiles({
pathnames,
renderer,
params,
htmlMinifier,
}: {
pathnames: string[];
renderer: AppRenderer;
params: SSGParams;
htmlMinifier: HtmlMinifier;
}): Promise<{collectedData: SiteCollectedData}> {
type SSGSuccess = {pathname: string; error: null; result: AppRenderResult};
type SSGError = {pathname: string; error: Error; result: null};
@ -132,6 +134,7 @@ export async function generateStaticFiles({
pathname,
renderer,
params,
htmlMinifier,
}).then(
(result) => ({pathname, result, error: null}),
(error) => ({pathname, result: null, error: error as Error}),
@ -170,10 +173,12 @@ async function generateStaticFile({
pathname,
renderer,
params,
htmlMinifier,
}: {
pathname: string;
renderer: AppRenderer;
params: SSGParams;
htmlMinifier: HtmlMinifier;
}) {
try {
// This only renders the app HTML
@ -185,7 +190,7 @@ async function generateStaticFile({
params,
result,
});
const content = await minifyHtml(fullPageHtml);
const content = await htmlMinifier.minify(fullPageHtml);
await writeStaticFile({
pathname,
content,
@ -262,23 +267,3 @@ async function writeStaticFile({
await fs.ensureDir(path.dirname(filePath));
await fs.writeFile(filePath, content);
}
async function minifyHtml(html: string): Promise<string> {
try {
if (process.env.SKIP_HTML_MINIFICATION === 'true') {
return html;
}
// Minify html with https://github.com/DanielRuf/html-minifier-terser
return await minify(html, {
removeComments: false,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyJS: true,
});
} catch (err) {
throw new Error('HTML minification failed', {cause: err as Error});
}
}

View file

@ -157,7 +157,7 @@ const sidebars = {
{
type: 'html',
value:
'<span style="border-top: 1px solid var(--ifm-color-gray-500); display: block;margin: 0.5rem 0 0.25rem 1rem;" />',
'<span style="border-top: 1px solid var(--ifm-color-gray-500); display: block;margin: 0.5rem 0 0.25rem 1rem;" ></span>',
},
// Image
{

184
yarn.lock
View file

@ -3042,80 +3042,148 @@
"@svgr/plugin-jsx" "8.1.0"
"@svgr/plugin-svgo" "8.1.0"
"@swc/core-darwin-arm64@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.14.tgz#a4530ec755ea183802cc9dfe4900ab5f6a327fea"
integrity sha512-V0OUXjOH+hdGxDYG8NkQzy25mKOpcNKFpqtZEzLe5V/CpLJPnpg1+pMz70m14s9ZFda9OxsjlvPbg1FLUwhgIQ==
"@swc/core-darwin-arm64@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.28.tgz#f4ff1c09443a0040a29c7e1e7615f5f5642b6945"
integrity sha512-BNkj6enHo2pdzOpCtQGKZbXT2A/qWIr0CVtbTM4WkJ3MCK/glbFsyO6X59p1r8+gfaZG4bWYnTTu+RuUAcsL5g==
"@swc/core-darwin-x64@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.7.14.tgz#2c9c717fd28dd1dde9c21cf58b01f1cda7976b1a"
integrity sha512-9iFvUnxG6FC3An5ogp5jbBfQuUmTTwy8KMB+ZddUoPB3NR1eV+Y9vOh/tfWcenSJbgOKDLgYC5D/b1mHAprsrQ==
"@swc/core-darwin-x64@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.7.28.tgz#ce0a6d559084a794517a81457cdadbf61a55c55d"
integrity sha512-96zQ+X5Fd6P/RNPkOyikTJgEc2M4TzznfYvjRd2hye5h22jhxCLL/csoauDgN7lYfd7mwsZ/sVXwJTMKl+vZSA==
"@swc/core-linux-arm-gnueabihf@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.14.tgz#fed055c9c65347177c8df88720f8a51793a4df06"
integrity sha512-zGJsef9qPivKSH8Vv4F/HiBXBTHZ5Hs3ZjVGo/UIdWPJF8fTL9OVADiRrl34Q7zOZEtGXRwEKLUW1SCQcbDvZA==
"@swc/core-linux-arm-gnueabihf@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.28.tgz#501375ac84c61dc718ed07239c7e44972f6c44e0"
integrity sha512-l2100Wx6LdXMOmOW3+KoHhBhyZrGdz8ylkygcVOC0QHp6YIATfuG+rRHksfyEWCSOdL3anM9MJZJX26KT/s+XQ==
"@swc/core-linux-arm64-gnu@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.14.tgz#ca740c8ea26f041b2dc43ba87facec452052814f"
integrity sha512-AxV3MPsoI7i4B8FXOew3dx3N8y00YoJYvIPfxelw07RegeCEH3aHp2U2DtgbP/NV1ugZMx0TL2Z2DEvocmA51g==
"@swc/core-linux-arm64-gnu@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.28.tgz#75e99da625939627f5b45d3004a6cfd8d6cbf46e"
integrity sha512-03m6iQ5Bv9u2VPnNRyaBmE8eHi056eE39L0gXcqGoo46GAGuoqYHt9pDz8wS6EgoN4t85iBMUZrkCNqFKkN6ZQ==
"@swc/core-linux-arm64-musl@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.14.tgz#fbc6fed24f5ad58b948e5b7abe6cd1f07112bef1"
integrity sha512-JDLdNjUj3zPehd4+DrQD8Ltb3B5lD8D05IwePyDWw+uR/YPc7w/TX1FUVci5h3giJnlMCJRvi1IQYV7K1n7KtQ==
"@swc/core-linux-arm64-musl@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.28.tgz#c737def355c0bf8db7d8e7bd87a3ae8bb3f9f8fc"
integrity sha512-vqVOpG/jc8mvTKQjaPBLhr7tnWyzuztOHsPnJqMWmg7zGcMeQC/2c5pU4uzRAfXMTp25iId6s4Y4wWfPS1EeDw==
"@swc/core-linux-x64-gnu@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.14.tgz#509a37833e4fbf89506b9291d9bd131fa2017fca"
integrity sha512-Siy5OvPCLLWmMdx4msnEs8HvEVUEigSn0+3pbLjv78iwzXd0qSBNHUPZyC1xeurVaUbpNDxZTpPRIwpqNE2+Og==
"@swc/core-linux-x64-gnu@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.28.tgz#eb612272ceb1331310eb79ef6094c5a6cc085d23"
integrity sha512-HGwpWuB83Kr+V0E+zT5UwIIY9OxiS8aLd0UVMRVWuO8SrQyKm9HKJ46+zoAb8tfJrpZftfxvbn2ayZWR7gqosA==
"@swc/core-linux-x64-musl@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.14.tgz#81156cc6ff814ad4b8fcf6eb6658d3f247db0b57"
integrity sha512-FtEGm9mwtRYQNK43WMtUIadxHs/ja2rnDurB99os0ZoFTGG2IHuht2zD97W0wB8JbqEabT1XwSG9Y5wmN+ciEQ==
"@swc/core-linux-x64-musl@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.28.tgz#a39749a71e690685aabeb7fd60141ccca2e62411"
integrity sha512-q2Y2T8y8EgFtIiRyInnAXNe94aaHX74F0ha1Bl9VdRxE0u1/So+3VLbPvtp4V3Z6pj5pOePfCQJKifnllgAQ9A==
"@swc/core-win32-arm64-msvc@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.14.tgz#c605fa783b5fbe1fff784ace4c4bb074b8d6026d"
integrity sha512-Jp8KDlfq7Ntt2/BXr0y344cYgB1zf0DaLzDZ1ZJR6rYlAzWYSccLYcxHa97VGnsYhhPspMpmCvHid97oe2hl4A==
"@swc/core-win32-arm64-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.28.tgz#93b22667b027e0a5060c91df7e0cc7406d27b01f"
integrity sha512-bCqh4uBT/59h3dWK1v91In6qzz8rKoWoFRxCtNQLIK4jP55K0U231ZK9oN7neZD6bzcOUeFvOGgcyMAgDfFWfA==
"@swc/core-win32-ia32-msvc@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.14.tgz#3e15dc3b662c9fab851a38b3e271c8e2da4ba03a"
integrity sha512-I+cFsXF0OU0J9J4zdWiQKKLURO5dvCujH9Jr8N0cErdy54l9d4gfIxdctfTF+7FyXtWKLTCkp+oby9BQhkFGWA==
"@swc/core-win32-ia32-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.28.tgz#4d7dbc43a1de79ac0c7cccf35bebf9fe887b2e24"
integrity sha512-XTHbHrksnrqK3JSJ2sbuMWvdJ6/G0roRpgyVTmNDfhTYPOwcVaL/mSrPGLwbksYUbq7ckwoKzrobhdxvQzPsDA==
"@swc/core-win32-x64-msvc@1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.14.tgz#83958d92e9f07865ec9365212111fbc295660f0d"
integrity sha512-NNrprQCK6d28mG436jVo2TD+vACHseUECacEBGZ9Ef0qfOIWS1XIt2MisQKG0Oea2VvLFl6tF/V4Lnx/H0Sn3Q==
"@swc/core-win32-x64-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.28.tgz#d00acea3339a90768279096e6e5f1540c599e6ce"
integrity sha512-jyXeoq6nX8abiCy2EpporsC5ywNENs4ocYuvxo1LSxDktWN1E2MTXq3cdJcEWB2Vydxq0rDcsGyzkRPMzFhkZw==
"@swc/core@^1.7.14":
version "1.7.14"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.7.14.tgz#d10492b5a4168cb1e73cf561a315e8b0f62255ed"
integrity sha512-9aeXeifnyuvc2pcuuhPQgVUwdpGEzZ+9nJu0W8/hNl/aESFsJGR5i9uQJRGu0atoNr01gK092fvmqMmQAPcKow==
"@swc/core@^1.7.14", "@swc/core@^1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.7.28.tgz#74aec7a31344da7cfd305a09f14f22420351d495"
integrity sha512-XapcMgsOS0cKh01AFEj+qXOk6KM4NZhp7a5vPicdhkRR8RzvjrCa7DTtijMxfotU8bqaEHguxmiIag2HUlT8QQ==
dependencies:
"@swc/counter" "^0.1.3"
"@swc/types" "^0.1.12"
optionalDependencies:
"@swc/core-darwin-arm64" "1.7.14"
"@swc/core-darwin-x64" "1.7.14"
"@swc/core-linux-arm-gnueabihf" "1.7.14"
"@swc/core-linux-arm64-gnu" "1.7.14"
"@swc/core-linux-arm64-musl" "1.7.14"
"@swc/core-linux-x64-gnu" "1.7.14"
"@swc/core-linux-x64-musl" "1.7.14"
"@swc/core-win32-arm64-msvc" "1.7.14"
"@swc/core-win32-ia32-msvc" "1.7.14"
"@swc/core-win32-x64-msvc" "1.7.14"
"@swc/core-darwin-arm64" "1.7.28"
"@swc/core-darwin-x64" "1.7.28"
"@swc/core-linux-arm-gnueabihf" "1.7.28"
"@swc/core-linux-arm64-gnu" "1.7.28"
"@swc/core-linux-arm64-musl" "1.7.28"
"@swc/core-linux-x64-gnu" "1.7.28"
"@swc/core-linux-x64-musl" "1.7.28"
"@swc/core-win32-arm64-msvc" "1.7.28"
"@swc/core-win32-ia32-msvc" "1.7.28"
"@swc/core-win32-x64-msvc" "1.7.28"
"@swc/counter@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
"@swc/html-darwin-arm64@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-darwin-arm64/-/html-darwin-arm64-1.7.28.tgz#19a6b8d50620bccd75e357b3409c17dacb951a27"
integrity sha512-vWxqVn8pUW/TG6NCnqNTGblJ70Rvet93rCIklo7AqAmEYnuSEyxmCo40CgAYLmpQS9Ql9OlEalH36ymPaQBiIA==
"@swc/html-darwin-x64@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-darwin-x64/-/html-darwin-x64-1.7.28.tgz#babe74ab7427bce9f09bf4c2f85a170a5c2b9fac"
integrity sha512-p+4vsRWUqSkvpqil9YItYRWwQ+DAD1553t6LMbyYPzT02LOw8pHxdvt7ZMIfoGn7mjgWhkl07/VeMsXfUtiWaA==
"@swc/html-linux-arm-gnueabihf@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.7.28.tgz#3369d6f905c44a721a71bfde271c393308a2d770"
integrity sha512-267layBwsXW0MsAiO085dckbLki2e4ZHlDsrPnCX4qLyzw6JykKplWeqWkg+Py2jNKw+YafYlHhlsKR/hN+olQ==
"@swc/html-linux-arm64-gnu@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.7.28.tgz#84eaefe7460169228f7f28b6f967beadb9e5ae04"
integrity sha512-3xEEepFXOZ7ZPcAbFzWhUqkYK3qUIhKjdr+VUut0fXeKRY8Y1qc79CvAAWxT1rQKuK4LLTUYCOJUskUbYWHAXg==
"@swc/html-linux-arm64-musl@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.7.28.tgz#e2ef51295f761074153ce5a32c1e754aa0eb97f8"
integrity sha512-P3wraHA2/vU8aXreNtIyYcqn0dj4o4gpT60s3Kj79L0G8dUdnTaXxiqX/7WRyB25asuGn608iwrzlMXQnX5c8A==
"@swc/html-linux-x64-gnu@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.7.28.tgz#96c72c5f76df444b46d6a4587d3e81f5c117ee70"
integrity sha512-VW98fYTgU6Bz6++paBMe4gaNbxKjN+hO/Jb+8Cfh1ln8fvjMTk/FxzqU1gHJMh4R2xJo4NbUxSkzBFiKN0Dq6w==
"@swc/html-linux-x64-musl@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.7.28.tgz#dbae82d638b656d916c2af25c653729e5ca78063"
integrity sha512-/GHYvo6SJr6vfkvhreXc+9va20isZle252GtrcyWGxKz+9t20T6fsbtX07U2XYTIVS1KXMCwaFooHBVu1zT7Pg==
"@swc/html-win32-arm64-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.7.28.tgz#4dab56c4671ef18b91620baf2cad360cd50de834"
integrity sha512-WZu4xje+tSZvDu09jwdmuwP78GmNhWBUzFUV/xulmJtcWRZOAHZyByPNV7Sp4fpcewSPiPoHjFdyhVR1MvGl1A==
"@swc/html-win32-ia32-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.7.28.tgz#9520d1d50d422a833c685afa9b9a2812d82e7216"
integrity sha512-qzBNJUZ5zBOJGmcsejJyNi4WBcYFPGnmtDCMzRP5uF1eMbQC+ye3nL8AP5BKCV8+i7kq8y+IGh6l6ieRnxwx0w==
"@swc/html-win32-x64-msvc@1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.7.28.tgz#0e9234614e883209e2513be94ae3114d14ee813d"
integrity sha512-9/wQWVwYJLPmeztj6Pg5Q7/Man96hwDTh5mRcSGNpAdaXyWMDYJWk0JTbZvPJUSrTBX0lKv9F7jhHcsOBKGErQ==
"@swc/html@^1.7.28":
version "1.7.28"
resolved "https://registry.yarnpkg.com/@swc/html/-/html-1.7.28.tgz#413a14c1351da81a99903beac8cb6f461e3c7607"
integrity sha512-eVPIz/goSyoNjDobwoB16dxX8RDu4gE1sNjFCpR/ZwrmqUTDvGhnLkQ7tz7rAdLdCIEW/iIO2hlrMyUHZzJW+A==
dependencies:
"@swc/counter" "^0.1.3"
optionalDependencies:
"@swc/html-darwin-arm64" "1.7.28"
"@swc/html-darwin-x64" "1.7.28"
"@swc/html-linux-arm-gnueabihf" "1.7.28"
"@swc/html-linux-arm64-gnu" "1.7.28"
"@swc/html-linux-arm64-musl" "1.7.28"
"@swc/html-linux-x64-gnu" "1.7.28"
"@swc/html-linux-x64-musl" "1.7.28"
"@swc/html-win32-arm64-msvc" "1.7.28"
"@swc/html-win32-ia32-msvc" "1.7.28"
"@swc/html-win32-x64-msvc" "1.7.28"
"@swc/jest@^0.2.36":
version "0.2.36"
resolved "https://registry.yarnpkg.com/@swc/jest/-/jest-0.2.36.tgz#2797450a30d28b471997a17e901ccad946fe693e"
@ -9064,10 +9132,10 @@ html-void-elements@^3.0.0:
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7"
integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==
html-webpack-plugin@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e"
integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==
html-webpack-plugin@^5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0"
integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==
dependencies:
"@types/html-minifier-terser" "^6.0.0"
html-minifier-terser "^6.0.2"