| import { defineConfig, PluginOption } from 'vite'; |
| import react from '@vitejs/plugin-react'; |
| import { viteSingleFile } from 'vite-plugin-singlefile'; |
| import path from 'node:path'; |
| import fs from 'node:fs'; |
| import zlib from 'node:zlib'; |
|
|
| |
|
|
| const MAX_BUNDLE_SIZE = 1.5 * 1024 * 1024; |
|
|
| const GUIDE_FOR_FRONTEND = ` |
| <!-- |
| This is a single file build of the frontend. |
| It is automatically generated by the build process. |
| Do not edit this file directly. |
| To make changes, refer to the "Web UI" section in the README. |
| --> |
| `.trim(); |
|
|
| const FRONTEND_PLUGINS = [react()]; |
|
|
| const BUILD_PLUGINS = [ |
| ...FRONTEND_PLUGINS, |
| viteSingleFile(), |
| (function llamaCppPlugin() { |
| let config: any; |
| return { |
| name: 'llamacpp:build', |
| apply: 'build', |
| async configResolved(_config: any) { |
| config = _config; |
| }, |
| writeBundle() { |
| const outputIndexHtml = path.join(config.build.outDir, 'index.html'); |
| const content = |
| GUIDE_FOR_FRONTEND + '\n' + fs.readFileSync(outputIndexHtml, 'utf-8'); |
| const compressed = zlib.gzipSync(Buffer.from(content, 'utf-8'), { |
| level: 9, |
| }); |
|
|
| |
| |
| compressed[0x4] = 0; |
| compressed[0x5] = 0; |
| compressed[0x6] = 0; |
| compressed[0x7] = 0; |
| |
| compressed[0x9] = 0; |
|
|
| if (compressed.byteLength > MAX_BUNDLE_SIZE) { |
| throw new Error( |
| `Bundle size is too large (${Math.ceil(compressed.byteLength / 1024)} KB).\n` + |
| `Please reduce the size of the frontend or increase MAX_BUNDLE_SIZE in vite.config.js.\n` |
| ); |
| } |
|
|
| const targetOutputFile = path.join( |
| config.build.outDir, |
| '../../public/index.html.gz' |
| ); |
| fs.writeFileSync(targetOutputFile, compressed); |
| }, |
| } satisfies PluginOption; |
| })(), |
| ]; |
|
|
| export default defineConfig({ |
| |
| plugins: process.env.ANALYZE ? FRONTEND_PLUGINS : BUILD_PLUGINS, |
| server: { |
| proxy: { |
| '/v1': 'http://localhost:8080', |
| }, |
| headers: { |
| 'Cross-Origin-Embedder-Policy': 'require-corp', |
| 'Cross-Origin-Opener-Policy': 'same-origin', |
| }, |
| }, |
| }); |
|
|