mirror of
https://github.com/alex8088/electron-vite.git
synced 2026-06-14 18:48:22 +08:00
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).
51 lines
1.9 KiB
JavaScript
51 lines
1.9 KiB
JavaScript
const { app } = require('electron')
|
|
const vm = require('vm')
|
|
const v8 = require('v8')
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
|
|
v8.setFlagsFromString('--no-lazy')
|
|
v8.setFlagsFromString('--no-flush-bytecode')
|
|
|
|
// Compile a chunk to a V8 code cache in the SAME process type that will consume it.
|
|
// On Electron 42+/V8 14.8 the cache is bound to a per-process-type snapshot AND flag
|
|
// hash, so a cache built in the wrong process type is rejected (and forcing acceptance
|
|
// corrupts execution). Spawned WITHOUT ELECTRON_RUN_AS_NODE (whose isolate matches
|
|
// neither). Code in / cache out go through ELECTRON_VITE_BYTECODE_IN / _OUT temp files.
|
|
// - main chunks -> compiled here, in the browser (main) process.
|
|
// - preload chunks -> ELECTRON_VITE_BYTECODE_RENDERER=1: a hidden window whose
|
|
// sandbox:false preload compiles it in a renderer isolate.
|
|
app.disableHardwareAcceleration()
|
|
|
|
const params = ['exports', 'require', 'module', '__filename', '__dirname']
|
|
const inFile = process.env.ELECTRON_VITE_BYTECODE_IN
|
|
const outFile = process.env.ELECTRON_VITE_BYTECODE_OUT
|
|
|
|
if (process.env.ELECTRON_VITE_BYTECODE_RENDERER) {
|
|
const { BrowserWindow, ipcMain } = require('electron')
|
|
app.whenReady().then(() => {
|
|
ipcMain.once('electron-vite:bytecode-done', () => app.quit())
|
|
const win = new BrowserWindow({
|
|
show: false,
|
|
webPreferences: {
|
|
preload: path.join(__dirname, 'electron-bytecode-preload.cjs'),
|
|
sandbox: false,
|
|
contextIsolation: true
|
|
}
|
|
})
|
|
win.loadURL('data:text/html,<!doctype html><html></html>')
|
|
})
|
|
} else {
|
|
app.whenReady().then(() => {
|
|
try {
|
|
const code = fs.readFileSync(inFile, 'utf-8')
|
|
const fn = vm.compileFunction(code, params, { produceCachedData: true })
|
|
fs.writeFileSync(outFile, fn.cachedData)
|
|
} catch (error) {
|
|
console.error(error)
|
|
process.exitCode = 1
|
|
}
|
|
app.quit()
|
|
})
|
|
}
|