From 8495dcd021435cf83f0debe6c66e09ff407e646e Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 10 Feb 2026 00:05:12 +0000 Subject: [PATCH] fix(ui): generate Monaco public assets in dev --- packages/ui/vite.config.ts | 150 ++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/packages/ui/vite.config.ts b/packages/ui/vite.config.ts index b0e1150c..3d18c162 100644 --- a/packages/ui/vite.config.ts +++ b/packages/ui/vite.config.ts @@ -7,83 +7,93 @@ import { resolve } from "path" const uiPackageJson = JSON.parse(fs.readFileSync(resolve(__dirname, "package.json"), "utf-8")) as { version?: string } const uiVersion = uiPackageJson.version ?? "0.0.0" +function copyMonacoPublicAssets(opts: { warn: (message: string) => void }) { + const publicDir = resolve(__dirname, "src/renderer/public") + const destRoot = resolve(publicDir, "monaco/vs") + + const candidates = [ + resolve(__dirname, "../../node_modules/monaco-editor/min/vs"), + resolve(__dirname, "node_modules/monaco-editor/min/vs"), + ] + const sourceRoot = candidates.find((p) => fs.existsSync(resolve(p, "loader.js"))) + if (!sourceRoot) { + opts.warn("Monaco source directory not found; skipping copy") + return + } + + fs.mkdirSync(destRoot, { recursive: true }) + + const copyRecursive = (src: string, dest: string) => { + const stat = fs.statSync(src) + if (stat.isDirectory()) { + fs.mkdirSync(dest, { recursive: true }) + for (const entry of fs.readdirSync(src)) { + copyRecursive(resolve(src, entry), resolve(dest, entry)) + } + return + } + fs.copyFileSync(src, dest) + } + + // Keep the working tree clean; these assets are generated. + try { + fs.rmSync(destRoot, { recursive: true, force: true }) + } catch { + // ignore + } + fs.mkdirSync(destRoot, { recursive: true }) + + // Copy core Monaco runtime. + for (const dir of ["base", "editor", "platform"] as const) { + const src = resolve(sourceRoot, dir) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, dir)) + } + } + + // loader.js is required. + copyRecursive(resolve(sourceRoot, "loader.js"), resolve(destRoot, "loader.js")) + + // Copy baseline rich language packages + workers. + for (const lang of ["typescript", "html", "json", "css"] as const) { + const src = resolve(sourceRoot, "language", lang) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, "language", lang)) + } + } + + // Copy baseline basic tokenizers. + for (const lang of ["python", "markdown", "cpp", "kotlin"] as const) { + const src = resolve(sourceRoot, "basic-languages", lang) + if (fs.existsSync(src)) { + copyRecursive(src, resolve(destRoot, "basic-languages", lang)) + } + } + + // Copy monaco.contribution.js entrypoints (needed by some loads). + const monacoContribution = resolve(sourceRoot, "basic-languages", "monaco.contribution.js") + if (fs.existsSync(monacoContribution)) { + copyRecursive(monacoContribution, resolve(destRoot, "basic-languages", "monaco.contribution.js")) + } + const underscoreContribution = resolve(sourceRoot, "basic-languages", "_.contribution.js") + if (fs.existsSync(underscoreContribution)) { + copyRecursive(underscoreContribution, resolve(destRoot, "basic-languages", "_.contribution.js")) + } +} + export default defineConfig({ root: "./src/renderer", plugins: [ solid(), { name: "prepare-monaco-public-assets", + // Ensure Monaco's AMD assets exist in `root/public` for both dev server and builds. + // These files are gitignored and generated on demand. + configureServer(server) { + copyMonacoPublicAssets({ warn: (msg) => server.config.logger.warn(msg) }) + }, buildStart() { - const publicDir = resolve(__dirname, "src/renderer/public") - const destRoot = resolve(publicDir, "monaco/vs") - - const candidates = [ - resolve(__dirname, "../../node_modules/monaco-editor/min/vs"), - resolve(__dirname, "node_modules/monaco-editor/min/vs"), - ] - const sourceRoot = candidates.find((p) => fs.existsSync(resolve(p, "loader.js"))) - if (!sourceRoot) { - this.warn("Monaco source directory not found; skipping copy") - return - } - - fs.mkdirSync(destRoot, { recursive: true }) - - const copyRecursive = (src: string, dest: string) => { - const stat = fs.statSync(src) - if (stat.isDirectory()) { - fs.mkdirSync(dest, { recursive: true }) - for (const entry of fs.readdirSync(src)) { - copyRecursive(resolve(src, entry), resolve(dest, entry)) - } - return - } - fs.copyFileSync(src, dest) - } - - // Keep the working tree clean; these assets are generated. - try { - fs.rmSync(destRoot, { recursive: true, force: true }) - } catch { - // ignore - } - fs.mkdirSync(destRoot, { recursive: true }) - - // Copy core Monaco runtime. - for (const dir of ["base", "editor", "platform"] as const) { - const src = resolve(sourceRoot, dir) - if (fs.existsSync(src)) { - copyRecursive(src, resolve(destRoot, dir)) - } - } - // loader.js is required. - copyRecursive(resolve(sourceRoot, "loader.js"), resolve(destRoot, "loader.js")) - - // Copy baseline rich language packages + workers. - for (const lang of ["typescript", "html", "json", "css"] as const) { - const src = resolve(sourceRoot, "language", lang) - if (fs.existsSync(src)) { - copyRecursive(src, resolve(destRoot, "language", lang)) - } - } - - // Copy baseline basic tokenizers. - for (const lang of ["python", "markdown", "cpp", "kotlin"] as const) { - const src = resolve(sourceRoot, "basic-languages", lang) - if (fs.existsSync(src)) { - copyRecursive(src, resolve(destRoot, "basic-languages", lang)) - } - } - - // Copy monaco.contribution.js entrypoints (needed by some loads). - const monacoContribution = resolve(sourceRoot, "basic-languages", "monaco.contribution.js") - if (fs.existsSync(monacoContribution)) { - copyRecursive(monacoContribution, resolve(destRoot, "basic-languages", "monaco.contribution.js")) - } - const underscoreContribution = resolve(sourceRoot, "basic-languages", "_.contribution.js") - if (fs.existsSync(underscoreContribution)) { - copyRecursive(underscoreContribution, resolve(destRoot, "basic-languages", "_.contribution.js")) - } + copyMonacoPublicAssets({ warn: (msg) => this.warn(msg) }) }, }, {