import { defineConfig, loadEnv } from "vite"; import solid from "vite-plugin-solid"; import solidStyled from "vite-plugin-solid-styled"; import suid from "@suid/vite-plugin"; import { VitePWA } from "vite-plugin-pwa"; import version from "vite-plugin-package-version"; import manifest from "./manifest.config"; import { GetManualChunk } from "rollup"; import devtools from "solid-devtools/vite"; /** * Put all strings (/i18n/{key}.) into separated chunks based on the key. */ const chunkStrs: GetManualChunk = (id, { getModuleInfo }) => { const match = /.*\/i18n\/(.*)\.[jt]s.*$/.exec(id); if (match) { const key = match[1]; const dependentEntryPoints = []; // we use a Set here so we handle each module at most once. This // prevents infinite loops in case of circular dependencies const idsToHandle = new Set(getModuleInfo(id)!.dynamicImporters); for (const moduleId of idsToHandle) { const { isEntry, dynamicImporters, importers } = getModuleInfo(moduleId)!; if (isEntry || dynamicImporters.length > 0) dependentEntryPoints.push(moduleId); // The Set iterator is intelligent enough to iterate over // elements that are added during iteration for (const importerId of importers) idsToHandle.add(importerId); } // If there is a unique entry, we put it into a chunk based on the // entry name if (dependentEntryPoints.length === 1) { return `${key}.${ dependentEntryPoints[0].split("/").slice(-1)[0].split(".")[0] }.strings`; } // For multiple entries, we put it into a "shared" chunk if (dependentEntryPoints.length > 1) { return `${key}.shared.strings`; } } }; const manualChunks: GetManualChunk = (id, meta) => { return chunkStrs(id, meta); }; export default defineConfig(({ mode }) => { const devConf = loadEnv(mode, import.meta.dirname, "DEV"); const serverHttpCertBase = devConf["DEV_SERVER_HTTP_CERT_BASE"]; const serverHttpCertPassword = devConf["DEV_SERVER_HTTP_CERT_PASS"]; const serverHttpCertKey = serverHttpCertBase ? `${serverHttpCertBase}.key` : undefined; const serverHttpCertCrt = serverHttpCertBase ? `${serverHttpCertBase}.crt` : undefined; const isTestBuild = ["development", "staging"].includes(mode); return { plugins: [ devtools({ autoname: true, locator: { targetIDE: (devConf["DEV_LOCATOR_EDITOR"] as | "vscode" | "atom" | "webstorm" | "vscode-insiders" | "") || undefined, componentLocation: true, jsxLocation: true, }, }), suid(), solid(), solidStyled({ filter: { include: "src/**/*.{tsx,jsx}", exclude: "node_modules/**/*.{ts,js,tsx,jsx}", }, }), VitePWA({ strategies: "injectManifest", registerType: "autoUpdate", devOptions: { enabled: true, }, srcDir: "src/serviceworker", filename: "main.ts", manifest: manifest, pwaAssets: { config: true, }, injectManifest: { globPatterns: ["**/*.{js,wasm,css,html,svg,png,ico}"], }, }), version(), ], server: { https: serverHttpCertBase ? { // This config controls https for the *dev server*. // See docs/dev-https.md for setting up https key: serverHttpCertKey, cert: serverHttpCertCrt, passphrase: serverHttpCertPassword, } : undefined, }, esbuild: { pure: isTestBuild ? undefined : ["console.debug", "console.trace"], drop: isTestBuild ? undefined : ["debugger"], }, define: { "import.meta.env.BUILT_AT": `"${new Date().toISOString()}"`, }, css: { devSourcemap: true, }, build: { target: ["firefox98", "safari15.4", "ios15.4", "chrome84", "edge87"], sourcemap: true, rollupOptions: { output: { manualChunks, }, }, }, }; });