mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 11:39:41 +03:00
113 lines
4.6 KiB
TypeScript
113 lines
4.6 KiB
TypeScript
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,
|
||
},
|
||
},
|
||
},
|
||
})
|