diff --git a/web/package.json b/web/package.json index 806ee45..f548406 100644 --- a/web/package.json +++ b/web/package.json @@ -39,7 +39,6 @@ "spark-md5": "^3.0.2", "tailwind-merge": "^3.6.0", "universal-cookie": "^7", - "vite-auto-import-svg": "^2.9.8", "vue": "^3.5.31", "vue-cropper": "^1.1.4", "vue-qr": "^4.0.9", @@ -65,7 +64,6 @@ "globals": "^16.3.0", "sass": "^1.78.0", "vite": "^8.0.10", - "vite-check-multiple-dom": "0.2.1", "vite-plugin-vue-devtools": "^8.1.1", "vue-eslint-parser": "^9.4.3" } diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 59a8d08..431ed3c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -89,9 +89,6 @@ importers: universal-cookie: specifier: ^7 version: 7.2.2 - vite-auto-import-svg: - specifier: ^2.9.8 - version: 2.9.8 vue: specifier: ^3.5.31 version: 3.5.41 @@ -162,9 +159,6 @@ importers: vite: specifier: ^8.0.10 version: 8.2.1(jiti@2.7.0)(sass@1.102.0) - vite-check-multiple-dom: - specifier: 0.2.1 - version: 0.2.1(vite@8.2.1(jiti@2.7.0)(sass@1.102.0))(vue@3.5.41) vite-plugin-vue-devtools: specifier: ^8.1.1 version: 8.2.1(supports-color@7.2.0)(vite@8.2.1(jiti@2.7.0)(sass@1.102.0))(vue@3.5.41) @@ -2519,15 +2513,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-auto-import-svg@2.9.8: - resolution: {integrity: sha512-oL67VbbfBnU7iThG3lRYdCTXJ02QMn0s6acQKpjvgZkasbQicquFYvZTRUZ6wVQ62w6RdWyqv2f7xWRV1V9l1w==} - - vite-check-multiple-dom@0.2.1: - resolution: {integrity: sha512-3UbOgHB7MKEHkxtrDKM0vamvW6155U1QvADbhc+l+AtrKdvyK8Dmx4/TFKkXu5d4lz5hgyacQqtjO9f9mteLqw==} - peerDependencies: - vite: '>=4.0.0' - vue: '>=3.0.0' - vite-dev-rpc@2.0.0: resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==} peerDependencies: @@ -5140,13 +5125,6 @@ snapshots: util-deprecate@1.0.2: {} - vite-auto-import-svg@2.9.8: {} - - vite-check-multiple-dom@0.2.1(vite@8.2.1(jiti@2.7.0)(sass@1.102.0))(vue@3.5.41): - dependencies: - vite: 8.2.1(jiti@2.7.0)(sass@1.102.0) - vue: 3.5.41 - vite-dev-rpc@2.0.0(vite@8.2.1(jiti@2.7.0)(sass@1.102.0)): dependencies: birpc: 4.1.0 diff --git a/web/src/main.js b/web/src/main.js index 5e2d099..710de89 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -3,7 +3,6 @@ import 'element-plus/theme-chalk/dark/css-vars.css' import 'uno.css' import { createApp } from 'vue' import ElementPlus from 'element-plus' -import { setupVueRootValidator } from 'vite-check-multiple-dom/client'; import 'element-plus/dist/index.css' // 主题扩展样式(菜单风格/卡片盒子模式/圆角),置于 EP 基础样式之后以便覆盖 @@ -24,10 +23,6 @@ const app = createApp(App) app.config.productionTip = false -setupVueRootValidator(app, { - lang: 'zh' - }) - app .use(run) .use(ElementPlus) diff --git a/web/vite.config.js b/web/vite.config.js index fe4b8b1..4420bb9 100644 --- a/web/vite.config.js +++ b/web/vite.config.js @@ -4,10 +4,57 @@ import * as path from 'path' import { loadEnv } from 'vite' import vuePlugin from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' -import { svgBuilder } from 'vite-auto-import-svg' -import vueRootValidator from 'vite-check-multiple-dom' import UnoCSS from '@unocss/vite' +const svgSpritePlugin = (roots) => ({ + name: 'kra-svg-sprite', + transformIndexHtml(html) { + const symbols = [] + const visit = (directory, modulePrefix = '') => { + if (!fs.existsSync(directory)) return + const entries = fs.readdirSync(directory, { withFileTypes: true }) + .sort((a, b) => a.name.localeCompare(b.name)) + + for (const entry of entries) { + const filename = path.join(directory, entry.name) + if (entry.isDirectory()) { + visit(filename, modulePrefix || entry.name + '-') + continue + } + if (!entry.name.endsWith('.svg')) continue + + const source = fs.readFileSync(filename, 'utf8') + const openingTag = source.match(/]*)>/i) + if (!openingTag) continue + + const attrs = openingTag[1] + .replace(/\s(?:width|height)=(['"]).*?\1/gi, '') + .trim() + const body = source + .slice(openingTag[0].length) + .replace(/<\/svg>\s*$/i, '') + const iconName = entry.name.replace(/\.svg$/i, '') + symbols.push(`${body}`) + } + } + + for (const root of roots) { + const directory = path.resolve(root) + const moduleRoot = path.basename(path.dirname(directory)) === 'src' && path.basename(directory) === 'modules' + if (!moduleRoot) { + visit(directory) + continue + } + for (const entry of fs.readdirSync(directory, { withFileTypes: true })) { + if (entry.isDirectory()) visit(path.join(directory, entry.name), entry.name + '-') + } + } + + const sprite = `${symbols.join('')}` + return html.replace('', `\n${sprite}`) + } +}) + const pathMapPlugin = () => ({ name: 'kra-vue-path-map', buildStart() { @@ -97,10 +144,9 @@ export default ({ mode }) => { env.VITE_POSITION === 'open' && vueDevTools({ launchEditor: env.VITE_EDITOR }), vuePlugin(), - svgBuilder(['./src/modules/', './src/assets/icons/'], base, outDir, 'assets', mode), + svgSpritePlugin(['./src/modules/', './src/assets/icons/']), pathMapPlugin(), - UnoCSS(), - vueRootValidator() + UnoCSS() ] } return config