diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json index ca2049087..a3c48e8e8 100644 --- a/internal/vite-config/package.json +++ b/internal/vite-config/package.json @@ -55,7 +55,6 @@ "unplugin-dts": "catalog:", "vite": "catalog:", "vite-plugin-compression": "catalog:", - "vite-plugin-html": "catalog:", "vite-plugin-lazy-import": "catalog:" } } diff --git a/internal/vite-config/src/plugins/html.ts b/internal/vite-config/src/plugins/html.ts new file mode 100644 index 000000000..657cf872c --- /dev/null +++ b/internal/vite-config/src/plugins/html.ts @@ -0,0 +1,35 @@ +import type { PluginOption } from 'vite'; +import type { Options as HtmlMinifierOptions } from 'html-minifier-terser'; + +import { minify } from 'html-minifier-terser'; + +const HTML_MINIFY_OPTIONS = { + collapseWhitespace: true, + minifyCSS: true, + minifyJS: true, + removeComments: true, + removeRedundantAttributes: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + useShortDoctype: true, +} as const; + +function viteHtmlPlugin(options: HtmlMinifierOptions = {}): PluginOption { + return { + name: 'vben-native-html', + transformIndexHtml: { + order: 'post', + async handler(html, ctx) { + if (!ctx.bundle) { + return html; + } + return await minify(html, { + ...HTML_MINIFY_OPTIONS, + ...options, + }); + }, + }, + }; +} + +export { viteHtmlPlugin }; diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts index 9d3ba3f1c..37cb61fbe 100644 --- a/internal/vite-config/src/plugins/index.ts +++ b/internal/vite-config/src/plugins/index.ts @@ -14,12 +14,12 @@ import viteVueJsx from '@vitejs/plugin-vue-jsx'; import { visualizer as viteVisualizerPlugin } from 'rollup-plugin-visualizer'; import viteDtsPlugin from 'unplugin-dts/vite'; import viteCompressPlugin from 'vite-plugin-compression'; -import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html'; import { VitePWA } from 'vite-plugin-pwa'; import viteVueDevTools from 'vite-plugin-vue-devtools'; import { viteArchiverPlugin } from './archiver'; import { viteExtraAppConfigPlugin } from './extra-app-config'; +import { viteHtmlPlugin } from './html'; import { viteImportMapPlugin } from './importmap'; import { viteInjectAppLoadingPlugin } from './inject-app-loading'; import { viteMetadataPlugin } from './inject-metadata'; @@ -199,7 +199,7 @@ async function loadApplicationPlugins( }, { condition: !!html, - plugins: () => [viteHtmlPlugin({ minify: true })], + plugins: () => [viteHtmlPlugin(typeof html === 'object' ? html : {})], }, { condition: isBuild && importmap, diff --git a/internal/vite-config/src/typing.ts b/internal/vite-config/src/typing.ts index 376b47b8a..bb4272146 100644 --- a/internal/vite-config/src/typing.ts +++ b/internal/vite-config/src/typing.ts @@ -6,6 +6,7 @@ import type { UserConfig, UserConfigFnPromise, } from 'vite'; +import type { Options as HtmlMinifierOptions } from 'html-minifier-terser'; import type { Options as PwaPluginOptions } from 'vite-plugin-pwa'; /** @@ -94,6 +95,12 @@ interface ArchiverPluginOptions { outputDir?: string; } +/** + * HTML 插件配置 + * @description 用于配置基于 transformIndexHtml 的 HTML 压缩行为 + */ +type HtmlPluginOptions = HtmlMinifierOptions; + /** * ImportMap 插件配置 * @description 用于配置模块的 CDN 导入 @@ -217,7 +224,7 @@ interface ApplicationPluginOptions extends CommonPluginOptions { * 是否开启 HTML 插件 * @default true */ - html?: boolean; + html?: boolean | HtmlPluginOptions; /** * 是否开启国际化 * @default false @@ -342,6 +349,7 @@ export type { DefineApplicationOptions, DefineConfig, DefineLibraryOptions, + HtmlPluginOptions, IImportMap, ImportmapPluginOptions, LibraryPluginOptions, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc5379a4f..8560f3377 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -465,9 +465,6 @@ catalogs: vite-plugin-compression: specifier: ^0.5.1 version: 0.5.1 - vite-plugin-html: - specifier: ^3.2.2 - version: 3.2.2 vite-plugin-lazy-import: specifier: ^1.0.7 version: 1.0.7 @@ -1301,9 +1298,6 @@ importers: vite-plugin-compression: specifier: 'catalog:' version: 0.5.1(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) - vite-plugin-html: - specifier: 'catalog:' - version: 3.2.2(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) vite-plugin-lazy-import: specifier: 'catalog:' version: 1.0.7 @@ -4874,10 +4868,6 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 - '@rollup/pluginutils@4.2.1': - resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} - engines: {node: '>= 8.0.0'} - '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -6719,10 +6709,6 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - comment-json@4.6.2: resolution: {integrity: sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==} engines: {node: '>= 6'} @@ -6779,13 +6765,6 @@ packages: resolution: {integrity: sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==} engines: {node: '>=18'} - connect-history-api-fallback@1.6.0: - resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} - engines: {node: '>=0.8'} - - consola@2.15.3: - resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -6936,9 +6915,6 @@ packages: css-render@0.15.14: resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} - css-select@4.3.0: - resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} - css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} @@ -7140,9 +7116,6 @@ packages: dom-scroll-into-view@2.0.1: resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==} - dom-serializer@1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -7152,17 +7125,10 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domhandler@4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} - domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domutils@2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -7181,14 +7147,6 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} - dotenv-expand@8.0.3: - resolution: {integrity: sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==} - engines: {node: '>=12'} - - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} - dotenv@17.4.1: resolution: {integrity: sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==} engines: {node: '>=12'} @@ -7274,9 +7232,6 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} - entities@2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -7982,10 +7937,6 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} @@ -8009,11 +7960,6 @@ packages: hookified@2.1.1: resolution: {integrity: sha512-AHb76R16GB5EsPBE2J7Ko5kiEyXwviB9P5SMrAKcuAu4vJPZttViAbj9+tZeaQE5zjDme+1vcHP78Yj/WoAveA==} - html-minifier-terser@6.1.0: - resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} - engines: {node: '>=12'} - hasBin: true - html-minifier-terser@7.2.0: resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} engines: {node: ^14.13.1 || >=16.0.0} @@ -9059,9 +9005,6 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-html-parser@5.4.2: - resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==} - node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -9301,9 +9244,6 @@ packages: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} - pathe@0.2.0: - resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} - pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -10954,11 +10894,6 @@ packages: peerDependencies: vite: '>=2.0.0' - vite-plugin-html@3.2.2: - resolution: {integrity: sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==} - peerDependencies: - vite: '>=2.0.0' - vite-plugin-inspect@11.3.3: resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} engines: {node: '>=14'} @@ -14206,11 +14141,6 @@ snapshots: picomatch: 2.3.2 rollup: 2.80.0 - '@rollup/pluginutils@4.2.1': - dependencies: - estree-walker: 2.0.2 - picomatch: 2.3.2 - '@rollup/pluginutils@5.3.0(rollup@2.80.0)': dependencies: '@types/estree': 1.0.8 @@ -16219,8 +16149,6 @@ snapshots: commander@2.20.3: {} - commander@8.3.0: {} - comment-json@4.6.2: dependencies: array-timsort: 1.0.3 @@ -16275,10 +16203,6 @@ snapshots: graceful-fs: 4.2.11 xdg-basedir: 5.1.0 - connect-history-api-fallback@1.6.0: {} - - consola@2.15.3: {} - consola@3.4.2: {} conventional-changelog-angular@8.3.1: @@ -16469,14 +16393,6 @@ snapshots: '@emotion/hash': 0.8.0 csstype: 3.0.11 - css-select@4.3.0: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 4.3.1 - domutils: 2.8.0 - nth-check: 2.1.1 - css-select@5.2.2: dependencies: boolbase: 1.0.0 @@ -16642,12 +16558,6 @@ snapshots: dom-scroll-into-view@2.0.1: {} - dom-serializer@1.4.1: - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -16658,20 +16568,10 @@ snapshots: domelementtype@2.3.0: {} - domhandler@4.3.1: - dependencies: - domelementtype: 2.3.0 - domhandler@5.0.3: dependencies: domelementtype: 2.3.0 - domutils@2.8.0: - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -16695,10 +16595,6 @@ snapshots: dependencies: type-fest: 4.41.0 - dotenv-expand@8.0.3: {} - - dotenv@16.6.1: {} - dotenv@17.4.1: {} dotenv@8.6.0: {} @@ -16787,8 +16683,6 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 - entities@2.2.0: {} - entities@4.5.0: {} entities@6.0.1: {} @@ -17721,8 +17615,6 @@ snapshots: dependencies: '@types/hast': 3.0.4 - he@1.2.0: {} - hey-listen@1.0.8: {} highlight.js@11.11.1: {} @@ -17739,16 +17631,6 @@ snapshots: hookified@2.1.1: {} - html-minifier-terser@6.1.0: - dependencies: - camel-case: 4.1.2 - clean-css: 5.3.3 - commander: 8.3.0 - he: 1.2.0 - param-case: 3.0.4 - relateurl: 0.2.7 - terser: 5.46.1 - html-minifier-terser@7.2.0: dependencies: camel-case: 4.1.2 @@ -18810,11 +18692,6 @@ snapshots: node-gyp-build@4.8.4: {} - node-html-parser@5.4.2: - dependencies: - css-select: 4.3.0 - he: 1.2.0 - node-mock-http@1.0.4: {} node-releases@2.0.37: {} @@ -19098,8 +18975,6 @@ snapshots: path-type@6.0.0: {} - pathe@0.2.0: {} - pathe@1.1.2: {} pathe@2.0.3: {} @@ -20885,22 +20760,6 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-html@3.2.2(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): - dependencies: - '@rollup/pluginutils': 4.2.1 - colorette: 2.0.20 - connect-history-api-fallback: 1.6.0 - consola: 2.15.3 - dotenv: 16.6.1 - dotenv-expand: 8.0.3 - ejs: 3.1.10 - fast-glob: 3.3.3 - fs-extra: 10.1.0 - html-minifier-terser: 6.1.0 - node-html-parser: 5.4.2 - pathe: 0.2.0 - vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3) - vite-plugin-inspect@11.3.3(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)): dependencies: ansis: 4.2.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dbc402c9e..baa472cad 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -178,7 +178,6 @@ catalog: vee-validate: ^4.15.1 vite: ^8.0.8 vite-plugin-compression: ^0.5.1 - vite-plugin-html: ^3.2.2 vite-plugin-lazy-import: ^1.0.7 vite-plugin-pwa: ^1.2.0 vite-plugin-vue-devtools: ^8.1.1