Files
HY2XS_flamy/apps/frontend/vite.config.ts
T
founder ddd1020a3a build(frontend): Vite 4.3.1 -> 7.3.6 и уборка мёртвых редакторов конфига
Решение «Vite не трогать» пересмотрено по данным, а не по желанию обновиться.
`pnpm audit --prod` (то, на что смотрит gate сборки) был чист, но полный audit
показывал в build-цепочке два critical и rollup GHSA DOM clobbering — а он
затрагивает ГЕНЕРИРУЕМЫЙ bundle, то есть уезжает в production. Vite 4.3.1 тянул
rollup 3 без исправления.

Взята 7.3.6 — последняя линия до Rolldown. Vite 8 по-прежнему не берётся: это
смена бандлера, отдельная работа с собственной приёмкой.

Вместе с Vite обновлена цепочка плагинов (@vitejs/plugin-vue 4 -> 6,
unplugin-* и unocss с версий 2022-2023 годов) и линтеры (@typescript-eslint
5 -> 8, prettier 2 -> 3, stylelint 15 -> 17). Новый @typescript-eslint нашёл 7
настоящих замечаний — исправлены по существу, а не подавлением правил; среди
них подавление несуществующего правила ban-types и `{}` вместо `object`.

Отдельно — три мёртвых редактора. Outbounds уже был разобран, здесь то же
самое для ImputMultiple (ACME-домены, inline ACL) и MapAdd (параметры ACME DNS,
заголовки masquerade): оба редактировали конфиг Hysteria в форме с
:disabled="true", получали значения без v-model и эмитили события, которых
никто не слушает, на странице без единого маршрута записи.

Цена ImputMultiple была измеримой. vuedraggable поставляется UMD-сборкой,
поэтому её require("vue") разрешался в vue/dist/vue.cjs.prod.js — полную сборку
Vue с рантайм-компилятором шаблонов. В бандл уезжало ~500 КБ исходников
(vuedraggable + sortablejs + compiler-core + compiler-dom) ради перетаскивания
тегов в недоступной для редактирования форме.

Разбор bundle через sourcemap нашёл и вторую потерю: @vueuse/core собирался
дважды — наш 13.9.0 и 14.4.0 из element-plus. Версии сведены.

bundle: 2 813 525 против 2 404 202 на исходной базовой линии (+17% за Vue 3.5,
Element Plus 2.14, echarts 6 и rollup 4). Промежуточное состояние без этих двух
исправлений было 3 046 172.

pnpm audit --prod: чисто. typecheck/eslint/stylelint: 0. go build с dist: OK.
2026-08-30 07:29:53 +05:00

171 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import vue from "@vitejs/plugin-vue";
import { defineConfig, UserConfig } from "vite";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import UnoCSS from "unocss/vite";
import path from "path";
const pathSrc = path.resolve(__dirname, "src");
// eslint-disable-next-line no-control-regex
const INVALID_CHAR_REGEX = /[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g;
const DRIVE_LETTER_REGEX = /^[a-z]:/i;
const DEV_SERVER_PORT = 8080;
// Синхронизировано с src/utils/request.ts и constant.AdminAPIBase.
const API_BASE = "/api";
export default defineConfig((): UserConfig => {
return {
base: "/",
resolve: {
alias: {
"@": pathSrc,
},
},
css: {
// CSS preprocessor
preprocessorOptions: {
//define global scss variable
scss: {
javascriptEnabled: true,
additionalData: `
@use "@/styles/variables.scss" as *;
`,
},
},
},
server: {
host: "0.0.0.0",
port: DEV_SERVER_PORT,
open: true, // Automatically open browser on start
proxy: {
// Reverse proxy for CORS in development
[API_BASE]: {
target: "http://127.0.0.1:8081",
changeOrigin: true,
},
},
},
plugins: [
vue(),
UnoCSS({/* options */}),
AutoImport({
// Auto import Vue helpers: ref, reactive, toRef, etc.
//
// Из @vueuse/core берутся ПОИМЁННО только те функции, которые
// действительно используются без явного импорта, а не весь пакет.
//
// Причина не стилистическая. С `"@vueuse/core"` целиком в список
// авто-импорта попадает вся его публичная поверхность — более пятисот
// имён, — и на VueUse 13 сборка падает:
//
// [auto-import] identifier toRef already defined with vue
//
// VueUse реэкспортирует `toRef` и `toValue`, и они конфликтуют с
// одноимёнными функциями Vue. Разрешать конфликт порядком записей в
// массиве значило бы решать вопрос «какой из двух toRef здесь имеется в
// виду» невидимо для читателя файла.
//
// Побочный эффект — src/types/auto-imports.d.ts сокращается с 526 строк
// до размера, который можно прочитать глазами.
imports: [
"vue",
{
"@vueuse/core": ["useVModel", "useFullscreen"],
},
],
eslintrc: {
// Включено намеренно. Файл перечисляет глобальные имена для eslint и
// подключается через `extends` в .eslintrc.cjs, но генерация была
// выключена — то есть список жил своей жизнью и расходился со
// списком авто-импортов при каждом его изменении.
//
// Устаревшие записи здесь не безобидны: eslint перестаёт сообщать об
// обращении к имени, которого больше нет в авто-импорте, и ошибка
// доезжает до typecheck или до рантайма вместо линтера.
enabled: true,
filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json`
globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
},
resolvers: [
// Auto import Element Plus helpers with styles: ElMessage, ElMessageBox, etc.
ElementPlusResolver(),
// Auto import icon components
IconsResolver({}),
],
vueTemplate: true, // Auto import in Vue templates
dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // Type declarations for auto imports; false disables generation
}),
Components({
resolvers: [
// Auto register icon components
IconsResolver({
enabledCollections: ["ep"], // @iconify-json/ep is the Element Plus icon collection
}),
// Auto import Element Plus components
ElementPlusResolver(),
],
dts: path.resolve(pathSrc, "types", "components.d.ts"), // Type declarations for auto components; false disables generation
}),
Icons({
// Auto install icon collections
autoInstall: true,
}),
createSvgIconsPlugin({
// Icon folders to cache
iconDirs: [path.resolve(pathSrc, "assets/icons")],
// symbolId format
symbolId: "icon-[dir]-[name]",
}),
],
build: {
rollupOptions: {
output: {
manualChunks(id: string) {
const normalizedId = id.replaceAll("\\", "/");
if (!normalizedId.includes("node_modules")) {
return;
}
if (
normalizedId.includes("echarts") ||
normalizedId.includes("zrender") ||
normalizedId.includes("vue-echarts")
) {
return "charts";
}
return "vendor";
},
sanitizeFileName(name: string): string {
// https://github.com/rollup/rollup/blob/master/src/utils/sanitizeFileName.ts
const match = DRIVE_LETTER_REGEX.exec(name);
const driveLetter = match ? match[0] : "";
// A `:` is only allowed as part of a windows drive letter (ex: C:\foo)
// Otherwise, avoid them because they can refer to NTFS alternate data streams.
return (
driveLetter +
name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX, "")
);
},
},
},
},
};
});