kv-music/vite.config.ts
Admin 431af4bb09
Some checks failed
Lighthouse / lighthouse (push) Failing after 2s
Lint Codebase / lint (push) Failing after 4s
Run Tests / test (push) Failing after 3s
fix: route stream segments through Go proxy in dev mode, reject Tidal PREVIEW (30s demo)
2026-05-18 15:31:47 +07:00

165 lines
5.8 KiB
TypeScript

import path from 'path';
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';
import authGatePlugin from './vite-plugin-auth-gate.js';
import blobAssetPlugin from './vite-plugin-blob.js';
import svgUse from './vite-plugin-svg-use.js';
import uploadPlugin from './vite-plugin-upload.js';
// import purgecss from 'vite-plugin-purgecss';
import { playwright } from '@vitest/browser-playwright';
import { execSync } from 'child_process';
import purgecss from 'vite-plugin-purgecss';
function proxyAudioPlugin() {
return {
name: 'proxy-audio-dev',
configureServer(server) {
// No longer needed: local proxy-audio middleware replaced by remote proxy
},
};
}
function getGitCommitHash() {
try {
return execSync('git rev-parse --short HEAD').toString().trim();
} catch {
return 'unknown';
}
}
export default defineConfig((_options) => {
const commitHash = getGitCommitHash();
return {
test: {
// https://vitest.dev/guide/browser/
browser: {
enabled: true,
provider: playwright(),
headless: !!process.env.HEADLESS,
instances: [{ browser: 'chromium' }],
},
},
base: './',
define: {
__COMMIT_HASH__: JSON.stringify(commitHash),
__VITEST__: !!process.env.VITEST,
},
worker: {
format: 'es',
},
resolve: {
alias: {
'!lucide': '/node_modules/lucide-static/icons',
'!simpleicons': '/node_modules/simple-icons/icons',
'!': '/node_modules',
events: '/node_modules/events/events.js',
pocketbase: '/node_modules/pocketbase/dist/pocketbase.es.js',
stream: path.resolve(__dirname, 'stream-stub.js'), // Stub for stream module
},
},
optimizeDeps: {
exclude: ['pocketbase', '@ffmpeg/ffmpeg', '@ffmpeg/util'],
},
server: {
fs: {
allow: ['.', 'node_modules'],
// host: true,
// allowedHosts: ['<your_tailscale_hostname>'], // e.g. pi5.tailf5f622.ts.net
},
proxy: {
'/tidal-proxy': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/tidal-proxy/, ''),
configure: (proxy) => {
proxy.on('proxyReq', (proxyReq) => {
proxyReq.setHeader('User-Agent', 'SpotiFLAC-Mobile/4.5.5');
});
},
},
},
},
// preview: {
// host: true,
// allowedHosts: ['<your_tailscale_hostname>'], // e.g. pi5.tailf5f622.ts.net
// },
build: {
outDir: 'dist',
emptyOutDir: true,
sourcemap: true,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
rollupOptions: {
treeshake: true,
},
},
plugins: [
proxyAudioPlugin(),
purgecss({
variables: false, // DO NOT REMOVE UNUSED VARIABLES (breaks web components like am-lyrics)
safelist: {
standard: [
/^am-lyrics/,
/^lyplus-/,
'sidepanel',
'side-panel',
'active',
'show',
/^data-/,
/^modal-/,
],
deep: [/^am-lyrics/],
greedy: [/^lyplus-/, /sidepanel/, /side-panel/],
},
}),
authGatePlugin(),
uploadPlugin(),
blobAssetPlugin(),
svgUse(),
VitePWA({
registerType: 'prompt',
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,json}'],
cleanupOutdatedCaches: true,
maximumFileSizeToCacheInBytes: 3 * 1024 * 1024, // 3 MiB limit
// Define runtime caching strategies
runtimeCaching: [
{
urlPattern: ({ request }) => request.destination === 'image',
handler: 'CacheFirst',
options: {
cacheName: 'images',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
},
},
},
{
urlPattern: ({ request }) =>
request.destination === 'audio' || request.destination === 'video',
handler: 'CacheFirst',
options: {
cacheName: 'media',
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
},
rangeRequests: true, // Support scrubbing
},
},
],
},
includeAssets: ['discord.html'],
manifest: false, // Use existing public/manifest.json
}),
],
};
});