electron-vite/bin/electron-bytecode-preload.cjs
Léonard C. cc591ff7cb
fix(bytecodePlugin): support Electron 42 / V8 14.8 code cache
With build.bytecode enabled, apps crash at launch on Electron 42 (V8 14.8)
with "Invalid or incompatible cached data (cachedDataRejected)". Electron 41
(V8 14.6) is unaffected, on the same machine and arch.

On V8 14.8 the code cache is bound to a per-process-type snapshot/isolate
checksum AND flag hash (electron/electron#51831 gives each process type its
own Node startup snapshot), and vm.Script no longer runs a cache when the
loader supplies a placeholder source.

Fix: compile each chunk in the Electron process type that will consume it,
via vm.compileFunction:
- main chunks    -> the browser (main) process
- preload chunks -> a renderer process (a hidden window whose sandbox:false
                    preload compiles the chunk)
Load via vm.compileFunction under --no-lazy, which runs the cache and ignores
the placeholder body (made unique per file to avoid V8 compilation-cache
collisions). No header bytes are patched, so an incompatible cache fails
loudly instead of corrupting execution.

Note: bytecode compilation now spawns Electron processes (a main process, and
a hidden window for the preload). On Windows this works without an interactive
desktop (e.g. over SSH); on Linux a display may be required (e.g. xvfb).
2026-06-06 22:44:00 +02:00

22 lines
848 B
JavaScript

// Compiler preload: runs in a renderer process (sandbox:false) so the produced code
// cache matches the V8 isolate (snapshot + flag hash) of the app's runtime preload,
// which the browser/main process cache does not on Electron 42+ / V8 14.8.
const fs = require('fs')
const vm = require('vm')
const v8 = require('v8')
const { ipcRenderer } = require('electron')
v8.setFlagsFromString('--no-lazy')
v8.setFlagsFromString('--no-flush-bytecode')
const params = ['exports', 'require', 'module', '__filename', '__dirname']
try {
const code = fs.readFileSync(process.env.ELECTRON_VITE_BYTECODE_IN, 'utf-8')
const fn = vm.compileFunction(code, params, { produceCachedData: true })
fs.writeFileSync(process.env.ELECTRON_VITE_BYTECODE_OUT, fn.cachedData)
} catch (error) {
console.error(error)
}
ipcRenderer.send('electron-vite:bytecode-done')