Files
opencode/services/site/vite.config.ts

113 lines
4.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineConfig, PluginOption } from "vite"
import { solidStart } from "@solidjs/start/config"
import { nitro } from "nitro/vite"
import { fromPathname } from "./src/lib/language"
import { docs } from "./src/docs/vite"
import { i18nSlices } from "./script/i18n-plugin"
import { foldSettingsForProduction } from "./script/fold-settings"
import { cssVariantsForProduction, devOnlyCss } from "./script/css-variants-plugin"
// Nitro's dev server drops any page the app renders with a 404 status and falls through to a bare
// "Cannot GET". In development only, serve the not-found page's preview (/dev/404, which follows
// Settings › 404 arcade › Mode like the real route) with a 404 status instead, so bad URLs look and
// hydrate as they do in production.
function notFoundInDev(): PluginOption {
return {
name: "not-found-in-dev",
apply: "serve",
configureServer(server) {
return () =>
server.middlewares.use(async (req, res, next) => {
const page =
req.method === "GET" && !req.url?.startsWith("/dev/404") && req.headers.accept?.includes("text/html")
if (!page) return next()
// The preview renders in the address's language (its /<locale> prefix, else the visitor's
// cookie or Accept-Language), with that language's lang and dir, as the real route does.
const locale = fromPathname(req.url ?? "/")
const response = await fetch(`http://${req.headers.host}${locale ? `/${locale}` : ""}/dev/404`, {
headers: {
cookie: req.headers.cookie ?? "",
"accept-language": req.headers["accept-language"] ?? "",
},
}).catch(() => undefined)
if (!response?.ok) return next()
res.statusCode = 404
res.setHeader("content-type", "text/html; charset=utf-8")
res.end(await response.text())
})
},
}
}
export default defineConfig({
plugins: [
// Before Solid compiles JSX, in both the server and browser builds (script/fold-settings.ts).
foldSettingsForProduction(),
solidStart({
middleware: "./src/middleware.ts",
}) as PluginOption,
nitro({
compatibilityDate: "2024-09-19",
preset: "cloudflare-module",
cloudflare: {
nodeCompat: true,
},
}),
notFoundInDev(),
devOnlyCss(),
cssVariantsForProduction(),
docs(),
i18nSlices(),
],
server: {
allowedHosts: true,
port: 3001,
proxy: {
// Development only: the 404 arcade loads anoma.ly/arcade games under our own origin, so its
// touch panel can send synthetic input into the same-origin frame. Production needs the
// arcade's input bridge instead (see component/site/arcade/games.ts).
"/arcade-proxy": {
target: "https://anoma.ly",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(/^\/arcade-proxy/, "/arcade"),
},
// Development only: heavy media is in the files bucket (src/lib/media.ts), so play the dev copies.
"/files": {
target: "https://dev.opencode.ai",
changeOrigin: true,
},
},
},
build: {
rollupOptions: {
external: ["cloudflare:workers"],
},
minify: false,
// The stylesheets the pages load are minified even though the Worker's code is not.
cssMinify: true,
// Browsers with native light-dark() (and CSS nesting). For older targets the minifier lowers
// light-dark() to --lightningcss-light/--lightningcss-dark variables set only where a rule
// declares color-scheme, so the site's tokens freeze at the theme of the element that defines
// them: a forced-dark card or band (color-scheme: dark) kept the page's light tokens in
// production, though the dev server (no lowering) showed it right.
cssTarget: ["chrome123", "edge123", "firefox120", "safari17.5"],
},
environments: {
// The browser bundles are minified; the Worker keeps readable code for its stack traces.
client: {
build: {
// Nitro copies public/ with fs.cp, which keeps the symlinks into packages/ui as links.
// Letting Vite copy it first writes real files.
copyPublicDir: true,
// Oxc, Vite 8's own minifier. "esbuild" here left the bundles unminified: Vite only adds its
// esbuild minifier when the top-level build.minify asks for it, and that stays off for the Worker.
minify: "oxc",
// strobe builds with STROBE_SOURCEMAP=hidden: maps beside the scripts without a
// sourceMappingURL comment, so the scripts stay byte for byte and profiles name source lines.
sourcemap: process.env.STROBE_SOURCEMAP === "hidden" ? "hidden" : undefined,
},
},
},
})