mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
feat(core): faster HTML minimizer - siteConfig.future.experimental_faster.swcHtmlMinimizer
(#10554)
This commit is contained in:
parent
126d395f2d
commit
912c4954d9
16 changed files with 406 additions and 92 deletions
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
> {
|
||||
|
|
|
@ -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';
|
||||
|
|
148
packages/docusaurus-bundler/src/minifyHtml.ts
Normal file
148
packages/docusaurus-bundler/src/minifyHtml.ts
Normal 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,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
}: {
|
||||
|
|
1
packages/docusaurus-types/src/config.d.ts
vendored
1
packages/docusaurus-types/src/config.d.ts
vendored
|
@ -126,6 +126,7 @@ export type StorageConfig = {
|
|||
export type FasterConfig = {
|
||||
swcJsLoader: boolean;
|
||||
swcJsMinimizer: boolean;
|
||||
swcHtmlMinimizer: boolean;
|
||||
lightningCssMinimizer: boolean;
|
||||
mdxCrossCompilerCache: boolean;
|
||||
rspackBundler: boolean;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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', () =>
|
||||
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,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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> = {
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
184
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue