mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-11-12 01:00:54 +00:00
fontLigatures already defaulted to on, but the terminal never loaded the ligatures addon, so Fira Code and Maple Mono kept drawing != as two cells. Activate the addon after open and before WebGL, and rebuild the WebGL atlas when the setting changes so glyphs are not rasterized without the calt feature. The addon bundles lru-cache's node:diagnostics_channel import. Alias that builtin to a no-op channel in the Vite renderer build and in the Electron live-test bundles. Closes #3543
148 lines
5.2 KiB
TypeScript
Executable File
148 lines
5.2 KiB
TypeScript
Executable File
import tailwindcss from '@tailwindcss/vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import path from 'path';
|
|
import { defineConfig, type Plugin } from 'vite';
|
|
|
|
// Custom plugin to suppress monaco-editor source map warnings
|
|
const suppressMonacoSourcemapWarning = () => ({
|
|
name: 'suppress-monaco-sourcemap-warning',
|
|
apply: 'serve' as const,
|
|
configResolved(config: { logger: { warn: (msg: string, options?: { timestamp?: boolean }) => void } }) {
|
|
const originalWarn = config.logger.warn;
|
|
config.logger.warn = (msg: string, options?: { timestamp?: boolean }) => {
|
|
// Suppress monaco-editor source map warnings
|
|
if (msg.includes('monaco-editor') && msg.includes('source map')) return;
|
|
if (msg.includes('loader.js.map')) return;
|
|
originalWarn(msg, options);
|
|
};
|
|
},
|
|
});
|
|
|
|
const devContentSecurityPolicy = [
|
|
"default-src 'self'",
|
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'",
|
|
"worker-src 'self' blob:",
|
|
"style-src 'self' 'unsafe-inline'",
|
|
"font-src 'self' data:",
|
|
"connect-src 'self' data: blob: ws: wss: https: http://localhost:5173",
|
|
"img-src 'self' data: https:",
|
|
].join("; ");
|
|
|
|
const devContentSecurityPolicyPlugin = () => ({
|
|
name: 'dev-content-security-policy',
|
|
apply: 'serve' as const,
|
|
transformIndexHtml(html: string) {
|
|
return html.replace(
|
|
/content="default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; worker-src 'self' blob:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self' data: blob: ws: wss: https:; img-src 'self' data: https:;"/,
|
|
`content="${devContentSecurityPolicy}"`,
|
|
);
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Stale pre-bundles return 504 after git pull / npm install. Vite retries the
|
|
* module once optimize finishes — do not full-reload the Electron window.
|
|
* Opening the lazy AI panel pulls `ai` / streamdown; a 504 there used to flash
|
|
* the boot splash and wipe renderer state.
|
|
*/
|
|
const warnOnOutdatedOptimizeDep = (): Plugin => ({
|
|
name: 'warn-on-outdated-optimize-dep',
|
|
apply: 'serve',
|
|
configureServer(server) {
|
|
server.middlewares.use((req, res, next) => {
|
|
res.on('finish', () => {
|
|
if (
|
|
res.statusCode === 504
|
|
&& req.url?.includes('/node_modules/.vite/deps/')
|
|
) {
|
|
server.config.logger.warn(
|
|
`[vite] stale optimize dep 504 for ${req.url} (not reloading the app)`,
|
|
);
|
|
}
|
|
});
|
|
next();
|
|
});
|
|
},
|
|
});
|
|
|
|
export default defineConfig(() => {
|
|
return {
|
|
base: "./",
|
|
server: {
|
|
port: 5173,
|
|
host: 'localhost',
|
|
headers: {
|
|
// Required for SharedArrayBuffer and WASM in some browsers
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
// Use credentialless to allow loading cross-origin images (e.g. Google avatars)
|
|
// while still enabling crossOriginIsolated.
|
|
'Cross-Origin-Embedder-Policy': 'credentialless',
|
|
},
|
|
hmr: {
|
|
overlay: true,
|
|
},
|
|
},
|
|
build: {
|
|
chunkSizeWarningLimit: 3000,
|
|
target: 'esnext', // Required for top-level await in WASM modules
|
|
sourcemap: false, // Disable source maps to avoid missing map file warnings
|
|
// Optimize chunk splitting for faster initial load
|
|
rollupOptions: {
|
|
output: {
|
|
manualChunks: {
|
|
// Vendor chunks - rarely change, can be cached aggressively
|
|
'vendor-radix': [
|
|
'@radix-ui/react-collapsible',
|
|
'@radix-ui/react-context-menu',
|
|
'@radix-ui/react-dialog',
|
|
'@radix-ui/react-popover',
|
|
'@radix-ui/react-scroll-area',
|
|
'@radix-ui/react-select',
|
|
'@radix-ui/react-tabs',
|
|
],
|
|
'vendor-xterm': [
|
|
'@xterm/xterm',
|
|
'@xterm/addon-fit',
|
|
'@xterm/addon-image',
|
|
'@xterm/addon-ligatures',
|
|
'@xterm/addon-search',
|
|
'@xterm/addon-serialize',
|
|
'@xterm/addon-web-links',
|
|
'@xterm/addon-webgl',
|
|
],
|
|
'vendor-ai': [
|
|
'ai',
|
|
'@ai-sdk/openai',
|
|
'@ai-sdk/anthropic',
|
|
'@ai-sdk/google',
|
|
'zod',
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
plugins: [suppressMonacoSourcemapWarning(), devContentSecurityPolicyPlugin(), warnOnOutdatedOptimizeDep(), tailwindcss(), react()],
|
|
optimizeDeps: {
|
|
include: [
|
|
'ai',
|
|
'@ai-sdk/openai',
|
|
'@ai-sdk/anthropic',
|
|
'@ai-sdk/google',
|
|
'streamdown',
|
|
'@streamdown/cjk',
|
|
'@streamdown/code',
|
|
'zod',
|
|
],
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, '.'),
|
|
// The ligatures addon pulls lru-cache's node:diagnostics_channel import
|
|
// into the renderer bundle. Stub it; the cache never publishes metrics.
|
|
'node:diagnostics_channel': path.resolve(__dirname, 'infrastructure/shims/nodeDiagnosticsChannel.ts'),
|
|
'diagnostics_channel': path.resolve(__dirname, 'infrastructure/shims/nodeDiagnosticsChannel.ts'),
|
|
}
|
|
}
|
|
};
|
|
});
|