import { fileURLToPath, URL } from 'node:url' import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' import Components from 'unplugin-vue-components/vite' import { PrimeVueResolver } from '@primevue/auto-import-resolver' import Info from 'unplugin-info/vite' import AutoImport from 'unplugin-auto-import/vite' import { unheadComposablesImports } from 'unhead' import mockData, { type RouteConfig } from 'vite-plugin-mock-data' import manifestJSON from 'rollup-plugin-manifest-json' import { type ManifestOptions } from 'rollup-plugin-manifest-json/lib/types' // https://vite.dev/config/ export default defineConfig(({ mode }) => { console.log('Building in mode', mode) process.env = { ...loadEnv(mode, process.cwd()), ...process.env } const manifest: ManifestOptions & { id?: string } = Object.fromEntries( Object.entries({ name: process.env.VITE_MANIFEST_NAME, short_name: process.env.VITE_MANIFEST_SHORT_NAME, id: process.env.VITE_MANIFEST_ID, start_url: process.env.VITE_MANIFEST_START_URL, scope: process.env.VITE_MANIFEST_SCOPE, }).filter((entry) => entry[1] !== undefined), ) return { build: { sourcemap: mode === 'development', reportCompressedSize: false, rollupOptions: { output: { manualChunks(id) { if (id.includes('node_modules')) { // PouchDB и его плагины if (id.includes('pouchdb')) { return 'vendor_pouchdb' } // QR-коды и библиотеки для работы с ними if (id.includes('qr-code-styling')) { return 'vendor_qr-code-styling' } // PrimeVue и связанные модули if (id.includes('primevue')) { return 'vendor_primevue' } // SVGO и зависимости if (id.includes('svgo') || id.includes('@trysound')) { return 'vendor_svgo' } // Танстэк Vue Query и ядро if (id.includes('@tanstack')) { return 'vendor_tanstack-query' } // Vue и связанные библиотеки if (id.includes('vue')) { return 'vendor_vue' } if (id.includes('css-tree')) { return 'vendor_css-tree' } if (id.includes('css-what')) { return 'vendor_css-what' } if (id.includes('domutils')) { return 'vendor_domutils' } if (id.includes('source-map-js')) { return 'vendor_source-map-js' } if (id.includes('csso')) { return 'vendor_csso' } if (id.includes('entities')) { return 'vendor_entities' } // Остальные модули из node_modules в vendor return 'vendor' } if (id.includes('src/api/')) { return 'api' } if (id.includes('src/utils/')) { return 'utils' } // По умолчанию ничего не делим return null }, }, }, }, plugins: [ vue(), Info(), AutoImport({ imports: ['vue', 'vue-router', unheadComposablesImports[0]], }), Components({ resolvers: [PrimeVueResolver()], }), vueDevTools(), mockData({ mockRoutes: { '/manifest.json': { async handler(req, res) { const { default: manifestJSON } = await import('./src/manifest.json') res.statusCode = 200 res.setHeader('Content-Type', 'text/html') res.end(JSON.stringify({ ...manifestJSON, ...manifest }, null, 2)) }, } satisfies RouteConfig, }, }), { ...manifestJSON({ input: 'src/manifest.json', // Required output: './manifest.json', minify: mode === 'production', manifest, }), apply: 'build', }, ], define: { global: 'window', // it is needed for PouchDB }, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, } })