mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-09 22:25:02 +03:00
fix(desktop): prevent main bundle require collision (#60430)
This commit is contained in:
committed by
GitHub
Unverified
parent
d9be7138b7
commit
2c49a18436
@@ -60,20 +60,11 @@ export default defineConfig(async ({ command }) => {
|
||||
minify: command === "build",
|
||||
rolldownOptions: {
|
||||
input: { index: "src/main/index.ts" },
|
||||
// Keep this identical to electron-vite's Node 20.11+ shim. Its regex insertion can
|
||||
// corrupt bundled TypeScript, while an output banner places the shim safely.
|
||||
output: {
|
||||
format: "es",
|
||||
// DesktopPaths resolves resources from the main output directory,
|
||||
// including when the lazy desktop entry shares it with other chunks.
|
||||
chunkFileNames: "[name]-[hash].js",
|
||||
banner: `
|
||||
// -- CommonJS Shims --
|
||||
import __cjs_mod__ from 'node:module';
|
||||
const __filename = import.meta.filename;
|
||||
const __dirname = import.meta.dirname;
|
||||
const require = __cjs_mod__.createRequire(import.meta.url);
|
||||
`,
|
||||
},
|
||||
},
|
||||
externalizeDeps: {
|
||||
@@ -92,6 +83,17 @@ const require = __cjs_mod__.createRequire(import.meta.url);
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
{
|
||||
// Rolldown emits its own scoped createRequire runtime for CommonJS dependencies.
|
||||
// electron-vite's post-bundle regex shim injects a top-level `const require` that collides
|
||||
// with bundled ESM modules declaring their own `require` (such as @effect/platform-node).
|
||||
name: "opencode:disable-esm-shim",
|
||||
configResolved(config) {
|
||||
const shim = config.plugins.find((plugin) => plugin.name === "vite:esm-shim")
|
||||
|
||||
if (shim) delete shim.renderChunk
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
preload: {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { $ } from "bun"
|
||||
import { exists } from "node:fs/promises"
|
||||
import path from "node:path"
|
||||
import { copyBuiltCliToResources, downloadCliToResources, getCurrentCli, resolveChannel } from "./utils"
|
||||
import { verifyBundles } from "./verify-bundles"
|
||||
|
||||
// Prepares resources/ (icons, metainfo, the bundled CLI) for OPENCODE_CHANNEL and builds the app into out/.
|
||||
// The CLI comes from ../cli/dist when it holds the target; otherwise dev downloads the published dev CLI,
|
||||
@@ -29,3 +30,5 @@ if (built) await copyBuiltCliToResources(cli)
|
||||
if (!built) await downloadCliToResources(channel === "beta" ? "beta" : undefined)
|
||||
|
||||
await $`bunx electron-vite build`
|
||||
|
||||
await verifyBundles(path.join(dir, "out"))
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import path from "node:path"
|
||||
import { Script, SourceTextModule } from "node:vm"
|
||||
|
||||
const targets = ["main", "preload"] as const
|
||||
|
||||
// Parses every built main and preload bundle without executing it, catching syntax and early
|
||||
// redeclaration errors even in chunks that the app loads lazily at runtime.
|
||||
export async function verifyBundles(outDir: string) {
|
||||
const glob = new Bun.Glob("**/*.{js,cjs,mjs}")
|
||||
const failures: string[] = []
|
||||
|
||||
for (const target of targets) {
|
||||
const dir = path.join(outDir, target)
|
||||
const files = await Array.fromAsync(glob.scan({ cwd: dir, onlyFiles: true })).catch(() => [])
|
||||
|
||||
if (files.length === 0) throw new Error(`Expected built chunks in ${dir}, found none`)
|
||||
|
||||
const errors = await Promise.all(
|
||||
files.sort().map(async (file) => {
|
||||
const label = `${target}/${file.replaceAll("\\", "/")}`
|
||||
const error = parseError(await Bun.file(path.join(dir, file)).text(), label)
|
||||
|
||||
return error ? `${label}: ${error}` : undefined
|
||||
}),
|
||||
)
|
||||
|
||||
failures.push(...errors.filter((item): item is string => item !== undefined))
|
||||
}
|
||||
|
||||
if (failures.length > 0) throw new Error(`Desktop bundle syntax check failed:\n${failures.join("\n")}`)
|
||||
}
|
||||
|
||||
function parseError(code: string, identifier: string) {
|
||||
const source = code.replace(/^#!.*\r?\n/, "\n")
|
||||
|
||||
try {
|
||||
if (identifier.endsWith(".cjs")) {
|
||||
new Script(`(function (exports, require, module, __filename, __dirname) { ${source}\n})`, {
|
||||
filename: identifier,
|
||||
})
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
new SourceTextModule(source, { identifier })
|
||||
|
||||
return undefined
|
||||
} catch (error) {
|
||||
return error instanceof Error ? error.message : String(error)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user