All files / core/blong-browser/src vite.ts

0% Statements 0/5
0% Branches 0/4
0% Functions 0/3
0% Lines 0/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                                                                                                                                                                                                     
/**
 * Reusable Vite configuration factory for blong browser applications.
 *
 * Provides sensible defaults (React plugin, RPC proxy, primeicons fs allow,
 * keepNames for Storybook debugging) so suite-level `vite.config.ts` files
 * stay minimal.
 *
 * Usage:
 * ```ts
 * // vite.config.ts
 * import {defineBlongViteConfig} from '@feasibleone/blong-browser/vite';
 * export default defineBlongViteConfig({importMetaUrl: import.meta.url});
 * ```
 *
 * Override any setting via the options parameter:
 * ```ts
 * export default defineBlongViteConfig({
 *     importMetaUrl: import.meta.url,
 *     server: {proxy: {'/rpc': 'http://localhost:9090'}},
 *     resolve: {alias: {'@feasibleone/blong': new URL('../blong/types.ts', import.meta.url).pathname}},
 * });
 * ```
 */
import react from '@vitejs/plugin-react';
import {dirname} from 'node:path';
import gzipPlugin from 'rollup-plugin-gzip';
import {type UserConfig, defineConfig, mergeConfig} from 'vite';
import {brotliCompressSync} from 'zlib';
 
const dir = (url: string) => dirname(url.replace(/file:\//g, ''));
 
export interface IBlongViteOptions {
    /**
     * `import.meta.url` from the caller's vite.config.ts.
     * Used to derive the correct `server.fs.allow` path for primeicons assets.
     */
    importMetaUrl: string;
    /** Any Vite UserConfig overrides merged on top of the defaults. */
    overrides?: UserConfig;
    /** Override the RPC proxy target (defaults to 'http://localhost:8080'). */
    rpcTarget?: string;
}
 
export function defineBlongViteConfig({
    importMetaUrl,
    overrides = {},
    rpcTarget = `http://localhost:${process.env['PLAYWRIGHT_BACKEND_PORT'] || 8080}`,
}: IBlongViteOptions): ReturnType<typeof defineConfig> {
    const base: UserConfig = {
        base: '/s/',
        plugins: [react()],
        build: {
            minify: false,
            assetsInlineLimit: 0,
            cssCodeSplit: true,
            rollupOptions: {
                output: {
                    // Keep function names for better debugging in Storybook
                    keepNames: true,
                },
                plugins: [
                    gzipPlugin(), // Generates .gz files
                    gzipPlugin({
                        customCompression: content => brotliCompressSync(Buffer.from(content)),
                        fileName: '.br', // Generates .br files
                    }),
                ],
            },
        },
        server: {
            proxy: {
                '/rpc': rpcTarget,
            },
            fs: {
                // Allow Vite to serve files from the Rush pnpm virtual store.
                //
                // Needed for:
                //  - fonts/assets in packages like primeicons;
                //  - `primereact` theme CSS, loaded at runtime as `?inline`
                //    dynamic imports by the theme switcher (`themeRegistry.ts`).
                //    Vite's dev-server fs guard runs the allow-list check on
                //    query-bearing requests (`?inline`/`?url`/`?raw`), so a
                //    package that is only reachable through the module graph is
                //    served as raw CSS instead of being transformed to a JS
                //    module — the browser then rejects it with a
                //    `text/css` MIME type error and no theme is applied.
                allow: [
                    dir(importMetaUrl),
                    dir(new URL(import.meta.resolve('primeicons/package.json')).pathname),
                    dir(new URL(import.meta.resolve('primereact/package.json')).pathname),
                ],
            },
        },
        resolve: {
            alias: {
                // In the monorepo, point @feasibleone/blong directly at source
                // so Vite picks up TypeScript changes without a build step.
                '@feasibleone/blong/types': new URL(import.meta.resolve('@feasibleone/blong/types'))
                    .href,
                '@feasibleone/blong': new URL(import.meta.resolve('@feasibleone/blong')).pathname,
            },
        },
    };
 
    return defineConfig(mergeConfig(base, overrides));
}