mirror of
https://github.com/alex8088/electron-vite.git
synced 2026-11-02 06:42:22 +08:00
fix(bytecode): unable to obtain the bytecode build session in Node.js 24 (#928)
This commit is contained in:
parent
1cbef3fb80
commit
b66840e2ec
20
src/build.ts
20
src/build.ts
@ -1,6 +1,6 @@
|
||||
import { build as viteBuild } from 'vite'
|
||||
import { build as viteBuild, mergeConfig } from 'vite'
|
||||
import { type InlineConfig, type MainViteConfig, type PreloadViteConfig, resolveConfig } from './config'
|
||||
import { BytecodeBuild, runWithBytecodeBuild } from './bytecode/build'
|
||||
import { BytecodeBuild, bytecodeBuildPluginName } from './bytecode/build'
|
||||
import { asyncFlatten } from './utils'
|
||||
|
||||
async function useBytecode(config?: MainViteConfig | PreloadViteConfig): Promise<boolean> {
|
||||
@ -14,7 +14,15 @@ async function useBytecode(config?: MainViteConfig | PreloadViteConfig): Promise
|
||||
*/
|
||||
export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
||||
process.env.NODE_ENV_ELECTRON_VITE = 'production'
|
||||
const config = await resolveConfig(inlineConfig, 'build', 'production')
|
||||
|
||||
const bytecodeBuild = new BytecodeBuild()
|
||||
const config = await resolveConfig(
|
||||
mergeConfig(inlineConfig, {
|
||||
plugins: [{ name: bytecodeBuildPluginName, api: { build: bytecodeBuild } }]
|
||||
}),
|
||||
'build',
|
||||
'production'
|
||||
)
|
||||
|
||||
if (!config.config) {
|
||||
return
|
||||
@ -22,7 +30,7 @@ export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
||||
|
||||
const mainBytecode = await useBytecode(config.config.main)
|
||||
const preloadBytecode = await useBytecode(config.config.preload)
|
||||
const bytecodeBuild = mainBytecode || preloadBytecode ? new BytecodeBuild() : undefined
|
||||
const hasBytecode = mainBytecode || preloadBytecode
|
||||
|
||||
const buildTargets = async (): Promise<void> => {
|
||||
// Build targets in order: main -> preload -> renderer
|
||||
@ -38,11 +46,11 @@ export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytecodeBuild) return buildTargets()
|
||||
if (!hasBytecode) return buildTargets()
|
||||
|
||||
try {
|
||||
await bytecodeBuild.start()
|
||||
await runWithBytecodeBuild(bytecodeBuild, buildTargets)
|
||||
await buildTargets()
|
||||
} finally {
|
||||
await bytecodeBuild.stop()
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { AsyncLocalStorage } from 'node:async_hooks'
|
||||
import { type Plugin } from 'vite'
|
||||
import { BytecodeCompiler, type BytecodeCompileResult, type BytecodeTarget } from './compiler'
|
||||
|
||||
// Nested isolated-entry builds inherit the compilation session from the parent build.
|
||||
const activeBuild = new AsyncLocalStorage<BytecodeBuild>()
|
||||
export const bytecodeBuildPluginName = 'vite:electron-bytecode-build'
|
||||
|
||||
export class BytecodeBuild {
|
||||
private readonly compiler = new BytecodeCompiler()
|
||||
@ -20,10 +19,7 @@ export class BytecodeBuild {
|
||||
}
|
||||
}
|
||||
|
||||
export function runWithBytecodeBuild<T>(build: BytecodeBuild, callback: () => Promise<T>): Promise<T> {
|
||||
return activeBuild.run(build, callback)
|
||||
}
|
||||
|
||||
export function getBytecodeBuild(): BytecodeBuild | undefined {
|
||||
return activeBuild.getStore()
|
||||
export function getBytecodeBuild(plugins: readonly Plugin[]): BytecodeBuild | undefined {
|
||||
const plugin = plugins.find(plugin => plugin.name === bytecodeBuildPluginName)
|
||||
return (plugin?.api as { build?: BytecodeBuild } | undefined)?.build
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ import { type BytecodeTarget } from '../bytecode/compiler'
|
||||
|
||||
// Versioned envelope: magic/version (8), UTF-16 source length (4), module ID (16), V8 cache.
|
||||
// Keep our metadata separate from the private V8 cache header.
|
||||
async function compileToBytecode(builder: BytecodeBuild, target: BytecodeTarget, code: string): Promise<Buffer> {
|
||||
async function compileToBytecode(build: BytecodeBuild, target: BytecodeTarget, code: string): Promise<Buffer> {
|
||||
const id = randomBytes(16)
|
||||
// Reserve enough source space for an untruncated, per-artifact placeholder identity.
|
||||
const source = code + '\n/*' + id.toString('hex') + '*/'
|
||||
const result = await builder.compile(target, source)
|
||||
const result = await build.compile(target, source)
|
||||
const header = Buffer.alloc(28)
|
||||
header.write('EVBC0001', 0, 'ascii')
|
||||
header.writeUInt32LE(result.sourceLength, 8)
|
||||
@ -118,12 +118,14 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||
|
||||
let supported = false
|
||||
let isPreload = false
|
||||
let bytecodeBuild: BytecodeBuild | undefined
|
||||
|
||||
return {
|
||||
name: 'vite:bytecode',
|
||||
apply: 'build',
|
||||
enforce: 'post',
|
||||
configResolved(config): void {
|
||||
bytecodeBuild = getBytecodeBuild(config.plugins)
|
||||
if (supported) {
|
||||
return
|
||||
}
|
||||
@ -182,8 +184,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||
|
||||
const bundles = Object.keys(output)
|
||||
|
||||
const compiler = getBytecodeBuild()
|
||||
if (!compiler) {
|
||||
if (!bytecodeBuild) {
|
||||
throw new Error('Bytecode compilation requires an electron-vite build session')
|
||||
}
|
||||
for (const name of bundles) {
|
||||
@ -206,7 +207,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||
}
|
||||
}
|
||||
if (bytecodeChunks.includes(name)) {
|
||||
const bytecodeBuffer = await compileToBytecode(compiler, isPreload ? 'preload' : 'main', _code)
|
||||
const bytecodeBuffer = await compileToBytecode(bytecodeBuild, isPreload ? 'preload' : 'main', _code)
|
||||
this.emitFile({
|
||||
type: 'asset',
|
||||
fileName: name + 'c',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user