mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-15 14:22:43 +00:00
fix(desktop): stop using tsx to boot Electron main in dev
Electron 40 ships Node 24.15, where tsx's ESM load hook returns null and crashes with ERR_INVALID_RETURN_PROPERTY_VALUE. Bundle main+preload via esbuild for `npm run dev` and always load the JS preload from dist/.
This commit is contained in:
parent
513dba42e6
commit
bf913abc2e
3 changed files with 19 additions and 15 deletions
|
|
@ -144,11 +144,10 @@ const IS_WSL = isWslEnvironment()
|
|||
const DARWIN_MAJOR = IS_MAC ? Number.parseInt(os.release(), 10) || 0 : 0
|
||||
const APP_ROOT = app.getAppPath()
|
||||
|
||||
// Preload script path: in dev we load the .ts source directly (tsx handles
|
||||
// the transform); in prod we load the bundled .js from dist/.
|
||||
const PRELOAD_PATH = IS_PACKAGED
|
||||
? path.join(APP_ROOT, 'dist', 'electron-preload.js')
|
||||
: path.join(import.meta.dirname, 'preload.ts')
|
||||
// Preload must be plain JS — Electron's sandbox can't run .ts, and tsx's
|
||||
// ESM loader is broken on Electron 40's Node (ERR_INVALID_RETURN_PROPERTY_VALUE).
|
||||
// Dev (`npm run dev`) and prod both load the esbuild output from dist/.
|
||||
const PRELOAD_PATH = path.join(APP_ROOT, 'dist', 'electron-preload.js')
|
||||
|
||||
function hiddenWindowsChildOptions(options: any = {}): ExecFileSyncOptionsWithStringEncoding {
|
||||
if (!IS_WINDOWS || Object.prototype.hasOwnProperty.call(options, 'windowsHide')) {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
"dev": "concurrently -k \"npm:dev:renderer\" \"npm:dev:electron\"",
|
||||
"dev:fake-boot": "cross-env HERMES_DESKTOP_BOOT_FAKE=1 HERMES_DESKTOP_BOOT_FAKE_STEP_MS=650 npm run dev",
|
||||
"dev:renderer": "node scripts/assert-root-install.mjs && vite --host 127.0.0.1 --port 5174",
|
||||
"dev:electron": "wait-on http://127.0.0.1:5174 && cross-env XCURSOR_SIZE=24 HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 NODE_OPTIONS=tsx electron electron/main.ts",
|
||||
"profile:main": "wait-on http://127.0.0.1:5174 && cross-env XCURSOR_SIZE=24 HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 NODE_OPTIONS=tsx electron --inspect=9229 electron/main.ts",
|
||||
"profile:main:cpu": "wait-on http://127.0.0.1:5174 && cross-env XCURSOR_SIZE=24 NODE_OPTIONS=--cpu-prof NODE_OPTIONS=tsx HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 electron electron/main.ts",
|
||||
"dev:electron": "wait-on http://127.0.0.1:5174 && node scripts/bundle-electron-main.mjs --dev && cross-env XCURSOR_SIZE=24 HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 electron .",
|
||||
"profile:main": "wait-on http://127.0.0.1:5174 && node scripts/bundle-electron-main.mjs --dev && cross-env XCURSOR_SIZE=24 HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 electron --inspect=9229 .",
|
||||
"profile:main:cpu": "wait-on http://127.0.0.1:5174 && node scripts/bundle-electron-main.mjs --dev && cross-env XCURSOR_SIZE=24 NODE_OPTIONS=--cpu-prof HERMES_DESKTOP_DEV_SERVER=http://127.0.0.1:5174 electron .",
|
||||
"start": "npm run build && electron .",
|
||||
"build": "node scripts/assert-root-install.mjs && node scripts/write-build-stamp.mjs && tsc -b && vite build && node scripts/bundle-electron-main.mjs && node scripts/stage-native-deps.mjs",
|
||||
"postbuild": "node scripts/assert-dist-built.mjs",
|
||||
|
|
|
|||
|
|
@ -25,9 +25,14 @@ const preloadEntry = resolve(root, 'electron/preload.ts')
|
|||
const preloadOut = resolve(distDir, 'electron-preload.js')
|
||||
|
||||
const external = ['electron', 'node-pty', 'fs']
|
||||
const define = {
|
||||
'process.env.HERMES_DESKTOP_IS_PACKAGED': JSON.stringify(true)
|
||||
}
|
||||
// Production bundles bake packaged=true so unpackaged `electron .` still
|
||||
// behaves like a packaged build. Dev bundles (`--dev`) leave the env alone
|
||||
// so HERMES_DESKTOP_DEV_SERVER / source-tree resolution keep working.
|
||||
const isDev = process.argv.includes('--dev')
|
||||
const define = isDev
|
||||
? {}
|
||||
: { 'process.env.HERMES_DESKTOP_IS_PACKAGED': JSON.stringify(true) }
|
||||
|
||||
// Bundle main.ts → dist/electron-main.mjs
|
||||
await build({
|
||||
entryPoints: [mainEntry],
|
||||
|
|
@ -37,15 +42,15 @@ await build({
|
|||
target: 'node20',
|
||||
outfile: mainOut,
|
||||
external,
|
||||
banner: {
|
||||
banner: {
|
||||
js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);",
|
||||
},
|
||||
define,
|
||||
logLevel: 'info',
|
||||
})
|
||||
console.log(`bundled ${mainOut}`)
|
||||
console.log(`bundled ${mainOut}${isDev ? ' (dev)' : ''}`)
|
||||
|
||||
// Bundle preload.ts → dist/electron-preload.cjs
|
||||
// Bundle preload.ts → dist/electron-preload.js
|
||||
await build({
|
||||
entryPoints: [preloadEntry],
|
||||
bundle: true,
|
||||
|
|
@ -57,4 +62,4 @@ await build({
|
|||
define,
|
||||
logLevel: 'info',
|
||||
})
|
||||
console.log(`bundled ${preloadOut}`)
|
||||
console.log(`bundled ${preloadOut}${isDev ? ' (dev)' : ''}`)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue