mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-19 02:20:02 -05:00
- The build rewrote start/end corners and positions with :lang(ar,fa,…) language lists, which Chromium before 141 (Android's WebView) drops: split buttons were square and start/end-placed controls sat wrong. Each list is now split into one language per check (postcss/langLists.mjs, run on the built CSS). - Home's action tiles stack the icon above the label on a phone; the labels broke mid-word. - Payloads' search box takes its own row on a phone instead of shrinking to nothing. - After Resend helper, pairing keeps checking for a minute, not 16 s. - Reverts the Android blur change: the doubled title was the emulator's software rendering, gone with its GPU on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
123 lines
5.1 KiB
TypeScript
123 lines
5.1 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { defineConfig, type Plugin } from "vite";
|
|
import react from "@vitejs/plugin-react";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
// @ts-expect-error plain .mjs helper shared with its vitest test, no type declarations
|
|
import { splitLangLists } from "./postcss/langLists.mjs";
|
|
|
|
/**
|
|
* The FAQ and What's New screens show the repo-root FAQ.md and CHANGELOG.md (lib/bundledDoc.ts).
|
|
* Imported as `../../../FAQ.md?raw`, the dev server served them as raw markdown instead of
|
|
* modules (they sit outside the client folder), so both screens failed there. As virtual modules
|
|
* they go through the normal pipeline in dev and in builds alike.
|
|
*/
|
|
function bundledDocs(): Plugin {
|
|
const files: Record<string, string> = {
|
|
"virtual:doc/faq": "../FAQ.md",
|
|
"virtual:doc/changelog": "../CHANGELOG.md",
|
|
};
|
|
return {
|
|
name: "ps5upload-bundled-docs",
|
|
resolveId(id) {
|
|
return id in files ? `\0${id}` : undefined;
|
|
},
|
|
load(id) {
|
|
if (!id.startsWith("\0virtual:doc/")) return undefined;
|
|
const file = fileURLToPath(new URL(files[id.slice(1)], import.meta.url));
|
|
this.addWatchFile(file);
|
|
return `export default ${JSON.stringify(readFileSync(file, "utf8"))};`;
|
|
},
|
|
};
|
|
}
|
|
|
|
// @ts-expect-error process is a nodejs global
|
|
const host = process.env.TAURI_DEV_HOST;
|
|
// The React runtime packages that go in their own long-lived vendor chunk.
|
|
const REACT_PACKAGES =
|
|
/[\\/]node_modules[\\/](react|react-dom|react-router|scheduler)[\\/]/;
|
|
// Dev server port (live reload uses the next one up). Desktop dev uses 1420;
|
|
// `make run-android` picks its own so both can run at once.
|
|
// @ts-expect-error process is a nodejs global
|
|
const port = Number(process.env.PS5UPLOAD_VITE_PORT) || 1420;
|
|
|
|
/** One language per `:lang()` in the built CSS (postcss/langLists.mjs says why). */
|
|
function oneLangPerSelector(): Plugin {
|
|
return {
|
|
name: "ps5upload-one-lang-per-selector",
|
|
apply: "build",
|
|
generateBundle(_, bundle) {
|
|
for (const file of Object.values(bundle)) {
|
|
if (file.type === "asset" && file.fileName.endsWith(".css") && typeof file.source === "string") {
|
|
file.source = splitLangLists(file.source);
|
|
}
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [react(), tailwindcss(), bundledDocs(), oneLangPerSelector()],
|
|
clearScreen: false,
|
|
base: process.env.VITE_BASE_URL || "./",
|
|
server: {
|
|
port,
|
|
strictPort: true,
|
|
// An explicit IPv4 address, not "localhost": Vite 8 binds the first address localhost
|
|
// resolves to, which on macOS is ::1 alone. The desktop WebView then could not load
|
|
// devUrl and `make run-client` opened a blank dark window (Chromium fell back to ::1,
|
|
// so the page looked fine in a browser). devUrl and playwright.config use 127.0.0.1 too.
|
|
host: host || "127.0.0.1",
|
|
hmr: host
|
|
? {
|
|
protocol: "ws",
|
|
host,
|
|
port: port + 1,
|
|
}
|
|
: undefined,
|
|
},
|
|
build: {
|
|
outDir: "dist",
|
|
emptyOutDir: true,
|
|
// Pin a conservative JS/CSS target. Tauri renders in a fixed WebView
|
|
// per platform, and the Android System WebView in particular can be
|
|
// an old Chromium. Without this, Vite ships its modern default
|
|
// (ES2020+ optional-chaining / nullish / logical-assignment that the
|
|
// v8/rolldown upgrade left un-lowered) and an older Android WebView
|
|
// renders the first screen, then crashes on `??=` / `?.` → the app
|
|
// "opens then terminates". safari13 (~ES2019) down-levels all of it
|
|
// and is safe for every WebView we ship to (Android Chromium,
|
|
// WebView2, WKWebView, WebKitGTK). Mirrors Tauri's recommended config.
|
|
target:
|
|
process.env.TAURI_ENV_PLATFORM === "windows" ? "chrome105" : "safari13",
|
|
chunkSizeWarningLimit: 900,
|
|
rollupOptions: {
|
|
// Silence rolldown's informational "[PLUGIN_TIMINGS] … significant time
|
|
// in @tailwindcss/vite:generate:build" note. Tailwind v4 scans the whole
|
|
// source tree to generate utilities, so its codegen is legitimately the
|
|
// slowest plugin — that's expected, not a problem to fix, and the note is
|
|
// just build noise. (rolldown input option, passed through by
|
|
// rolldown-vite; not in Vite's RollupOptions types yet.)
|
|
// @ts-expect-error checks is a rolldown passthrough not typed by Vite
|
|
checks: { pluginTimings: false },
|
|
output: {
|
|
manualChunks(id) {
|
|
if (!id.includes("node_modules")) return;
|
|
// Exact package names: a bare "react" substring also caught
|
|
// lucide-react and anything else with react in its path.
|
|
if (REACT_PACKAGES.test(id)) return "vendor-react";
|
|
return "vendor";
|
|
},
|
|
},
|
|
},
|
|
},
|
|
test: {
|
|
// Fail any test that reaches the network. See src/test-setup.ts for
|
|
// why: unmocked API wrappers silently hit a running dev engine.
|
|
setupFiles: ["./src/test-setup.ts"],
|
|
// Playwright owns real-browser journeys; Vitest must not import those
|
|
// files into its jsdom/node runner.
|
|
exclude: ["e2e/**", "**/node_modules/**", "**/.git/**"],
|
|
},
|
|
});
|