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 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, }), ], 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, "") ); }, }, }, }, }; });