mirror of
https://github.com/anomalyco/opencode.git
synced 2026-10-23 14:40:23 +00:00
141 lines
4.7 KiB
JavaScript
141 lines
4.7 KiB
JavaScript
import { readFileSync } from "node:fs"
|
|
import { createRequire } from "node:module"
|
|
import solidPlugin from "vite-plugin-solid"
|
|
import tailwindcss from "@tailwindcss/vite"
|
|
import { fileURLToPath } from "url"
|
|
|
|
const theme = fileURLToPath(new URL("./public/oc-theme-preload.js", import.meta.url))
|
|
|
|
const themeScript = readFileSync(theme, "utf8")
|
|
|
|
const tailwind = tailwindcss()
|
|
|
|
const tailwindGenerate = tailwind.find((plugin) => plugin.name === "@tailwindcss/vite:generate:serve")
|
|
|
|
const tailwindHotUpdate = tailwindGenerate?.hotUpdate
|
|
|
|
// Tailwind 4.3.3 expects a server that Vite's bundled dev hook does not provide.
|
|
if (tailwindGenerate && typeof tailwindHotUpdate === "function") {
|
|
tailwindGenerate.hotUpdate = function (context) {
|
|
if (!context.server) return
|
|
|
|
return tailwindHotUpdate.call(this, context)
|
|
}
|
|
}
|
|
|
|
// The markdown worker imports these directly, so they are served unbundled to keep worker startup
|
|
// stable.
|
|
const workerDeps = ["@pierre/highlights", "marked"]
|
|
|
|
// The Office previews load their wasm and fonts through `new URL(..., import.meta.url)`, which a pre-bundle would move
|
|
// away from the files.
|
|
const officeDeps = ["@betteroffice/docx", "@betteroffice/fonts", "@betteroffice/pptx", "@betteroffice/xlsx"]
|
|
|
|
// The build emits the Office engines' wasm and worker files for every `new URL(..., import.meta.url)` it sees, even in
|
|
// code that tree shaking drops. A file that no other emitted file names never loads, so it is left out of the build.
|
|
const officeEmitted = /^(?:docx_\w+_bg|ooxml_opc_bg|pptx_wasm_bg|xlsx_wasm_bg|residentEngineWorker)\b/
|
|
|
|
/** @type {import("vite").Plugin} */
|
|
const dropUnloadedOfficeFiles = {
|
|
name: "opencode-desktop:drop-unloaded-office-files",
|
|
apply: "build",
|
|
generateBundle: {
|
|
order: "post",
|
|
handler(_, bundle) {
|
|
const files = Object.values(bundle).filter((file) => !file.fileName.endsWith(".map"))
|
|
const name = (file) => file.fileName.split("/").pop() ?? file.fileName
|
|
const source = (file) => (file.type === "chunk" ? file.code : typeof file.source === "string" ? file.source : "")
|
|
const named = (file) => files.some((other) => other !== file && source(other).includes(name(file)))
|
|
|
|
files
|
|
.filter((file) => officeEmitted.test(name(file)) && !named(file))
|
|
.forEach((file) => {
|
|
delete bundle[file.fileName]
|
|
delete bundle[`${file.fileName}.map`]
|
|
})
|
|
},
|
|
},
|
|
}
|
|
|
|
/** @type {import("rolldown").Plugin} */
|
|
const bundleNestedWorkerDeps = {
|
|
name: "opencode-desktop:bundle-nested-worker-deps",
|
|
resolveId(id, importer) {
|
|
if (!importer || !workerDeps.includes(id) || !importer.includes("node_modules")) return
|
|
|
|
try {
|
|
return createRequire(importer).resolve(id)
|
|
} catch {
|
|
return
|
|
}
|
|
},
|
|
}
|
|
|
|
// The components lab globs every story, and the dependency scan cannot parse a .tsx story that calls import.meta.glob
|
|
// itself. The lab is a development tool, so its dependencies are found when it first opens rather than at startup.
|
|
/** @type {import("rolldown").Plugin} */
|
|
const skipComponentsLab = {
|
|
name: "opencode-desktop:skip-components-lab",
|
|
resolveId(id) {
|
|
if (id === "@/components-lab/lab") return { id, external: true }
|
|
},
|
|
}
|
|
|
|
export const channel = (() => {
|
|
const raw = process.env.OPENCODE_CHANNEL
|
|
|
|
if (raw === "local" || raw === "dev" || raw === "beta" || raw === "prod") return raw
|
|
|
|
if (process.env.OPENCODE_CHANNEL === "latest") return "prod"
|
|
|
|
return "dev"
|
|
})()
|
|
|
|
/**
|
|
* @type {import("vite").PluginOption}
|
|
*/
|
|
export default [
|
|
{
|
|
name: "opencode-desktop:config",
|
|
config() {
|
|
return {
|
|
resolve: {
|
|
alias: {
|
|
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
|
// The font package imports its 33 MB Chinese, Japanese and Korean add-on on demand; the app does not ship it.
|
|
"@betteroffice/fonts-cjk": fileURLToPath(
|
|
new URL("../gui-extensions/src/microsoft-office/fonts-cjk.ts", import.meta.url),
|
|
),
|
|
},
|
|
},
|
|
define: {
|
|
"import.meta.env.VITE_OPENCODE_CHANNEL": JSON.stringify(channel),
|
|
},
|
|
worker: {
|
|
format: "es",
|
|
},
|
|
optimizeDeps: {
|
|
exclude: [...workerDeps, ...officeDeps],
|
|
rolldownOptions: { plugins: [bundleNestedWorkerDeps, skipComponentsLab] },
|
|
},
|
|
}
|
|
},
|
|
},
|
|
dropUnloadedOfficeFiles,
|
|
{
|
|
name: "opencode-desktop:theme-preload",
|
|
transformIndexHtml: {
|
|
order: "pre",
|
|
handler: inlineThemePreload,
|
|
},
|
|
},
|
|
...tailwind,
|
|
solidPlugin(),
|
|
]
|
|
|
|
export function inlineThemePreload(html) {
|
|
return html.replace(
|
|
/<script id="oc-theme-preload-script" src="(?:\.\/|\/)oc-theme-preload\.js"><\/script>/,
|
|
`<script id="oc-theme-preload-script">${themeScript}</script>`,
|
|
)
|
|
}
|