mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
Vite 8 changed CJS default-import interop: with "type": "module" set, a default import of a CJS dependency now resolves to the whole module.exports object instead of its .default export. react-lottie is CJS-only, so <Lottie> received an object as the element type and crashed LottieLoading/LottieSuccess with "Element type is invalid". Swap to the maintained, ESM-built lottie-react, aliasing it to its ES build since its browser field points at a UMD build with the same interop hazard. No other dependency is affected by the interop change. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
130 lines
4 KiB
TypeScript
130 lines
4 KiB
TypeScript
import tailwindcss from "@tailwindcss/vite";
|
|
import react from "@vitejs/plugin-react-swc";
|
|
import path from "path";
|
|
import { defineConfig, Plugin } from "vite";
|
|
import { VitePWA } from "vite-plugin-pwa";
|
|
|
|
export default defineConfig(({ command }) => ({
|
|
plugins: [
|
|
react(),
|
|
tailwindcss(),
|
|
VitePWA({
|
|
registerType: "autoUpdate",
|
|
// disable service worker - Alby Hub cannot be used offline (and also breaks oauth callback)
|
|
injectRegister: false,
|
|
includeAssets: [
|
|
"favicon.ico",
|
|
"robots.txt",
|
|
"icon-192.png",
|
|
"icon-512.png",
|
|
],
|
|
useCredentials: true, // because the manifest might sit behind authentication
|
|
manifest: {
|
|
short_name: "Alby Hub",
|
|
name: "Alby Hub",
|
|
icons: [
|
|
{
|
|
src: "icon-192.png",
|
|
sizes: "192x192",
|
|
type: "image/png",
|
|
},
|
|
{
|
|
src: "icon-512.png",
|
|
sizes: "512x512",
|
|
type: "image/png",
|
|
},
|
|
{
|
|
src: "icon-1024.png",
|
|
sizes: "1024x1024",
|
|
type: "image/png",
|
|
},
|
|
],
|
|
start_url: ".",
|
|
display: "standalone",
|
|
theme_color: "#000000",
|
|
background_color: "#ffffff",
|
|
},
|
|
workbox: {
|
|
maximumFileSizeToCacheInBytes: 3000000, // 3MB
|
|
},
|
|
}),
|
|
...(command === "serve" ? [insertDevCSPPlugin] : [insertProdCSPPlugin]),
|
|
],
|
|
server: {
|
|
port: process.env.VITE_PORT ? parseInt(process.env.VITE_PORT) : undefined,
|
|
proxy: {
|
|
"/api": {
|
|
target: process.env.VITE_API_URL || "http://localhost:8080",
|
|
secure: false,
|
|
},
|
|
"/logout": {
|
|
target: process.env.VITE_API_URL || "http://localhost:8080",
|
|
secure: false,
|
|
},
|
|
},
|
|
},
|
|
resolve: {
|
|
tsconfigPaths: true,
|
|
alias: {
|
|
src: path.resolve(import.meta.dirname, "./src"),
|
|
wailsjs: path.resolve(import.meta.dirname, "./wailsjs"),
|
|
// used to refrence public assets when importing images or other
|
|
// assets from the public folder
|
|
// this is necessary to inject the base path during build
|
|
public: "",
|
|
// lottie-react's `browser` field points to a UMD build, which breaks
|
|
// under Vite 8's Node-style CJS interop (default import resolves to the
|
|
// whole exports object); force the ESM build instead
|
|
"lottie-react": "lottie-react/build/index.es.js",
|
|
},
|
|
},
|
|
build: {
|
|
assetsInlineLimit: 0,
|
|
},
|
|
html:
|
|
command === "serve"
|
|
? {
|
|
cspNonce: "DEVELOPMENT",
|
|
}
|
|
: undefined,
|
|
base: process.env.BASE_PATH || "/",
|
|
}));
|
|
|
|
const DEVELOPMENT_NONCE = "'nonce-DEVELOPMENT'";
|
|
|
|
// when making changes here, also update the CSP header in http_service.go
|
|
const buildCSP = (nonce?: string) =>
|
|
`default-src 'self'${nonce ? " " + nonce : ""}; img-src 'self' https://uploads.getalby-assets.com https://cdn.getalby-assets.com https://getalby.com; connect-src 'self' https://api.getalby.com https://getalby.com https://zapplanner.albylabs.com wss://relay.getalby.com wss://relay2.getalby.com; frame-src https://www.youtube-nocookie.com`;
|
|
|
|
const insertCSPMetaTag = (comment: string, csp: string) => (html: string) =>
|
|
html.replace(
|
|
"<head>",
|
|
`<head>
|
|
<!-- ${comment} -->
|
|
<meta http-equiv="Content-Security-Policy" content="${csp}" />`
|
|
);
|
|
|
|
const insertDevCSPPlugin: Plugin = {
|
|
name: "dev-csp",
|
|
transformIndexHtml: {
|
|
order: "pre",
|
|
handler: insertCSPMetaTag(
|
|
"DEV-ONLY CSP - when making changes here, also update the CSP header in http_service.go (without the nonce!)",
|
|
buildCSP(DEVELOPMENT_NONCE)
|
|
),
|
|
},
|
|
};
|
|
|
|
// the same CSP is served as a HTTP header in http mode (see http_service.go).
|
|
// The meta tag ensures the policy also applies where no HTTP headers are set,
|
|
// e.g. in the desktop app.
|
|
const insertProdCSPPlugin: Plugin = {
|
|
name: "prod-csp",
|
|
transformIndexHtml: {
|
|
order: "pre",
|
|
handler: insertCSPMetaTag(
|
|
"when making changes here, also update the CSP header in http_service.go",
|
|
buildCSP()
|
|
),
|
|
},
|
|
};
|