Files
geo/apps/admin-web/vite.config.ts
T
root 162abdc97c
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Failing after 1m39s
chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports)
- Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier
- Add root scripts: format, format:check, lint, lint:fix
- Reformat 257 files across admin-web, ops-web, desktop-client, packages
- Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters
- Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex
- Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:39:09 +08:00

191 lines
6.0 KiB
TypeScript

import { createRequire } from 'node:module'
import { fileURLToPath, URL } from 'node:url'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer'
import { defineConfig, loadEnv, type PluginOption } from 'vite'
import { compression } from 'vite-plugin-compression2'
const r = (path: string) => fileURLToPath(new URL(path, import.meta.url))
const nodeRequire = createRequire(import.meta.url)
const resolveNodeModule = (specifier: string) => nodeRequire.resolve(specifier)
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, '.', '')
const isProd = mode === 'production'
const analyze = env.ANALYZE === 'true'
const plugins: PluginOption[] = [vue()]
if (isProd) {
plugins.push(
compression({
algorithms: ['gzip', 'brotliCompress'],
threshold: 1024,
}),
)
}
if (analyze) {
plugins.push(
visualizer({
filename: 'stats.html',
template: 'treemap',
gzipSize: true,
brotliSize: true,
open: true,
}) as PluginOption,
)
}
return {
plugins,
resolve: {
alias: {
'@': r('./src'),
'@geo/shared-types': r('../../packages/shared-types/src/index.ts'),
'@geo/http-client': r('../../packages/http-client/src/index.ts'),
'@jsquash/webp/encode.js': resolveNodeModule('@jsquash/webp/encode.js'),
'@jsquash/webp/codec/enc/webp_enc.wasm': resolveNodeModule(
'@jsquash/webp/codec/enc/webp_enc.wasm',
),
'@jsquash/webp/codec/enc/webp_enc_simd.wasm': resolveNodeModule(
'@jsquash/webp/codec/enc/webp_enc_simd.wasm',
),
},
},
server: {
host: '0.0.0.0',
port: 5173,
proxy: {
'/api': {
target: env.VITE_API_PROXY_TARGET || 'http://localhost:8080',
changeOrigin: true,
},
'/swagger': {
target: env.VITE_API_PROXY_TARGET || 'http://localhost:8080',
changeOrigin: true,
},
},
},
esbuild: isProd ? { drop: ['console', 'debugger'] } : undefined,
build: {
target: 'es2022',
sourcemap: 'hidden',
cssCodeSplit: true,
assetsInlineLimit: 4096,
chunkSizeWarningLimit: 800,
reportCompressedSize: false,
modulePreload: { polyfill: false },
rollupOptions: {
output: {
entryFileNames: 'assets/js/[name]-[hash].js',
chunkFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: (info) => {
const name = info.names?.[0] ?? ''
if (/\.(png|jpe?g|gif|svg|webp|avif|ico)$/i.test(name)) {
return 'assets/img/[name]-[hash][extname]'
}
if (/\.(woff2?|eot|ttf|otf)$/i.test(name)) {
return 'assets/fonts/[name]-[hash][extname]'
}
if (/\.css$/i.test(name)) {
return 'assets/css/[name]-[hash][extname]'
}
return 'assets/[name]-[hash][extname]'
},
manualChunks(id) {
if (!id.includes('node_modules')) return undefined
// Milkdown editor and its heavy companion deps (only the editor route
// imports them, so this chunk stays lazy-loaded).
if (
id.includes('/@milkdown/') ||
id.includes('/prosemirror-') ||
id.includes('/codemirror/') ||
id.includes('/@codemirror/') ||
id.includes('/@lezer/') ||
id.includes('/katex/') ||
id.includes('/micromark') ||
id.includes('/mdast-util') ||
id.includes('/unist-util') ||
id.includes('/hast-util') ||
id.includes('/unified/') ||
id.includes('/remark') ||
id.includes('/rehype') ||
id.includes('/decode-named-character-reference/') ||
id.includes('/vfile') ||
id.includes('/zwitch/') ||
id.includes('/longest-streak/') ||
id.includes('/bail/') ||
id.includes('/extend/') ||
id.includes('/devlop/') ||
id.includes('/is-plain-obj/') ||
id.includes('/trough/') ||
id.includes('/ccount/') ||
id.includes('/escape-string-regexp/') ||
id.includes('/markdown-table/') ||
id.includes('/@marijn/') ||
id.includes('/orderedmap/') ||
id.includes('/w3c-keyname/') ||
id.includes('/rope-sequence/') ||
id.includes('/style-mod/') ||
id.includes('/crelt/') ||
id.includes('/@floating-ui/') ||
id.includes('/clsx/') ||
id.includes('/@ocavue/')
) {
return 'milkdown'
}
if (id.includes('/nanoid/')) {
return 'nanoid'
}
if (id.includes('/ant-design-vue/') || id.includes('/@ant-design/')) {
return 'antd'
}
if (id.includes('/@tanstack/') || id.includes('/@vueuse/')) {
return 'query'
}
if (id.includes('/@jsquash/')) {
return 'imaging'
}
if (id.includes('/lodash') || id.includes('/dayjs')) {
return 'utils'
}
if (
id.includes('/markdown-it') ||
id.includes('/dompurify') ||
id.includes('/entities/') ||
id.includes('/mdurl/') ||
id.includes('/uc.micro/') ||
id.includes('/linkify-it/') ||
id.includes('/punycode.js/')
) {
return 'editor-utils'
}
if (
id.includes('/vue/') ||
id.includes('/@vue/') ||
id.includes('/vue-router/') ||
id.includes('/vue-i18n/') ||
id.includes('/@intlify/') ||
id.includes('/pinia/')
) {
return 'vue-vendor'
}
return 'vendor'
},
},
},
},
}
})