import { defineConfig } from "vite"; import elmPlugin from "vite-plugin-elm"; import { VitePWA } from "vite-plugin-pwa" import viteCompression from "vite-plugin-compression" // import vitePrerender from "vite-plugin-prerender" // import prerender from '@prerenderer/rollup-plugin' import { imagetools } from "vite-imagetools" import htmlPlugin from "vite-plugin-html-config" import { promises as fs } from "fs" import path from "path" // const Renderer = vitePrerender.PuppeteerRenderer; /** @type {import("vite").UserConfig} */ export default defineConfig(async () => { const pkg = JSON.parse(await fs.readFile(path.join(__dirname, "package.json"))); const lossyQuality = 85; const prerenderOptions = { staticDir: path.join(__dirname, "dist"), routes: pkg.routes, minify: { collapseBooleanAttributes: true, collapseInlineTagWhitespace: true, collapseWhitespace: true, decodeEntities: true, sortAttributes: true, sortClassName: true, minifyCSS: true, minifyJS: true, removeAttributeQuotes: true, removeComments: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, removeRedundantAttributes: true, removeOptionalTags: true, }, }; const host = process.env.URL || import.meta.url || "http://localhost"; const getURL = (path = "") => new URL(path, host).toString(); const getPath = (path = "") => { const x = new URL(path, host); return x.pathname + x.search; // return await import("./" + path); }; return { plugins: [ htmlPlugin({ title: pkg.displayName, // TODO .ico favicon: getPath("/data/images/icon.png?h=16&w=16"), links: [ { rel: "apple-touch-icon", href: getPath("/data/images/icon.png?h=180&w=180"), sizes: "180x180", }, { rel: "icon", href: getPath("/data/images/icon.png?h=32&w=32"), sizes: "32x32", type: "image/png", }, { rel: "icon", href: getPath("/data/images/icon.png?h=16&w=16"), sizes: "16x16", type: "image/png", }, { rel: "mask-icon", href: getPath("/data/images/icon.png?h=180&w=180"), sizes: "180x180", color: pkg.color, }, { rel: "icon", href: getPath("/data/images/icon.png?h=16&w=16"), sizes: "16x16", }, // TODO .ico { rel: "icon", href: getPath("/data/images/icon.png?h=16&w=16"), sizes: "16x16", }, ], metas: [ { name: "description", content: pkg.description, }, { name: "author", content: pkg.author.name, }, { name: "theme-color", content: pkg.color, }, { name: "og:url", content: host, }, { name: "og:type", content: "website", }, { name: "og:title", content: pkg.displayName, }, { name: "og:description", content: pkg.description, }, { name: "og:image", content: getURL("/data/images/logo.png"), }, { name: "twitter:card", content: "summary_large_image", }, { name: "twitter:domain", content: "", }, { name: "twitter:url", content: host, }, { name: "twitter:title", content: pkg.displayName, }, { name: "twitter:description", content: pkg.description, }, { name: "twitter:image", content: getURL("/data/images/logo.png"), }, ], }), elmPlugin.plugin(), VitePWA({ injectRegister: "auto", registerType: "autoUpdate", manifest: { name: pkg.displayName, // TODO better? short_name: pkg.displayName, description: pkg.description, theme_color: pkg.color, icons: [ { src: getPath("/data/images/icon.png?h=192&w=192"), sizes: "192x192", type: "image/png", }, { src: getPath("/data/images/icon.png?h=512&w=512"), sizes: "512x512", type: "image/png", }, { src: getPath("/data/images/icon.png?h=512&w=512"), sizes: "512x512", type: "image/png", purpose: "any maskable", }, ] }, devOptions: { enabled: true } }), imagetools({ defaultDirectives: (url) => { if (url.pathname.endsWith(".png")) { return new URLSearchParams({ format: "webp", lossless: true, quality: 100, }); } if (url.pathname.endsWith(".l.png")) { return new URLSearchParams({ format: "webp", quality: lossyQuality, }); } if (url.pathname.endsWith(".jpg")) { return new URLSearchParams({ format: "webp", quality: lossyQuality, }); } return new URLSearchParams(); }, }), viteCompression({ algorithm: "brotliCompress", }), // vitePrerender({ // ...prerenderOptions, // outputDir: path.join(__dirname, "dist", "prerender", "mobile"), // renderer: new Renderer({ // viewport: { // isMobile: true, // hasTouch: true, // width: 450, // height: 800, // }, // }), // }), // vitePrerender({ // ...prerenderOptions, // outputDir: path.join(__dirname, "dist", "prerender", "desktop"), // renderer: new Renderer({ // viewport: { // isMobile: false, // hasTouch: false, // width: 1500, // height: 1000, // }, // }), // }), ], } });