mirror of
https://github.com/alex8088/electron-vite.git
synced 2026-11-02 14:51:51 +08:00
chore: simplify bytecode compiler initialization
This commit is contained in:
parent
fa199eb372
commit
6b0f85a2a7
11
src/build.ts
11
src/build.ts
@ -1,6 +1,7 @@
|
|||||||
import { build as viteBuild, mergeConfig } from 'vite'
|
import { build as viteBuild, mergeConfig } from 'vite'
|
||||||
import { type InlineConfig, type MainViteConfig, type PreloadViteConfig, resolveConfig } from './config'
|
import { type InlineConfig, type MainViteConfig, type PreloadViteConfig, resolveConfig } from './config'
|
||||||
import { BytecodeBuild, bytecodeBuildPluginName } from './bytecode/build'
|
import { BytecodeCompiler } from './bytecodeCompiler'
|
||||||
|
import { BYTECODE_BUILD_PLUGIN_NAME } from './constants'
|
||||||
import { asyncFlatten } from './utils'
|
import { asyncFlatten } from './utils'
|
||||||
|
|
||||||
async function useBytecode(config?: MainViteConfig | PreloadViteConfig): Promise<boolean> {
|
async function useBytecode(config?: MainViteConfig | PreloadViteConfig): Promise<boolean> {
|
||||||
@ -15,10 +16,10 @@ async function useBytecode(config?: MainViteConfig | PreloadViteConfig): Promise
|
|||||||
export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
||||||
process.env.NODE_ENV_ELECTRON_VITE = 'production'
|
process.env.NODE_ENV_ELECTRON_VITE = 'production'
|
||||||
|
|
||||||
const bytecodeBuild = new BytecodeBuild()
|
const bytecodeCompiler = new BytecodeCompiler()
|
||||||
const config = await resolveConfig(
|
const config = await resolveConfig(
|
||||||
mergeConfig(inlineConfig, {
|
mergeConfig(inlineConfig, {
|
||||||
plugins: [{ name: bytecodeBuildPluginName, api: { build: bytecodeBuild } }]
|
plugins: [{ name: BYTECODE_BUILD_PLUGIN_NAME, api: { compiler: bytecodeCompiler } }]
|
||||||
}),
|
}),
|
||||||
'build',
|
'build',
|
||||||
'production'
|
'production'
|
||||||
@ -49,9 +50,9 @@ export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
|
|||||||
if (!hasBytecode) return buildTargets()
|
if (!hasBytecode) return buildTargets()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await bytecodeBuild.start()
|
await bytecodeCompiler.start()
|
||||||
await buildTargets()
|
await buildTargets()
|
||||||
} finally {
|
} finally {
|
||||||
await bytecodeBuild.stop()
|
await bytecodeCompiler.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
import { type Plugin } from 'vite'
|
|
||||||
import { BytecodeCompiler, type BytecodeCompileResult, type BytecodeTarget } from './compiler'
|
|
||||||
|
|
||||||
export const bytecodeBuildPluginName = 'vite:electron-bytecode-build'
|
|
||||||
|
|
||||||
export class BytecodeBuild {
|
|
||||||
private readonly compiler = new BytecodeCompiler()
|
|
||||||
|
|
||||||
start(): Promise<void> {
|
|
||||||
return this.compiler.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
compile(target: BytecodeTarget, code: string): Promise<BytecodeCompileResult> {
|
|
||||||
return this.compiler.compile(target, code)
|
|
||||||
}
|
|
||||||
|
|
||||||
stop(): Promise<void> {
|
|
||||||
return this.compiler.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getBytecodeBuild(plugins: readonly Plugin[]): BytecodeBuild | undefined {
|
|
||||||
const plugin = plugins.find(plugin => plugin.name === bytecodeBuildPluginName)
|
|
||||||
return (plugin?.api as { build?: BytecodeBuild } | undefined)?.build
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { type ChildProcess, spawn } from 'node:child_process'
|
import { type ChildProcess, spawn } from 'node:child_process'
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import { getElectronPath } from '../electron'
|
import { getElectronPath } from './electron'
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
const RPC_TIMEOUT = 30_000
|
const RPC_TIMEOUT = 30_000
|
||||||
1
src/constants.ts
Normal file
1
src/constants.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const BYTECODE_BUILD_PLUGIN_NAME = 'vite:electron-bytecode-build'
|
||||||
@ -5,18 +5,23 @@ import { type Plugin, type LibraryOptions, type Rolldown, normalizePath } from '
|
|||||||
import * as babel from '@babel/core'
|
import * as babel from '@babel/core'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { toRelativePath } from '../utils'
|
import { toRelativePath } from '../utils'
|
||||||
import { type BytecodeBuild, getBytecodeBuild } from '../bytecode/build'
|
import type { BytecodeCompiler, BytecodeTarget } from '../bytecodeCompiler'
|
||||||
import { type BytecodeTarget } from '../bytecode/compiler'
|
import { BYTECODE_BUILD_PLUGIN_NAME } from '../constants'
|
||||||
|
|
||||||
// Inspired by https://github.com/bytenode/bytenode
|
// Inspired by https://github.com/bytenode/bytenode
|
||||||
|
|
||||||
|
function getBytecodeCompiler(plugins: readonly Plugin[]): BytecodeCompiler | undefined {
|
||||||
|
const plugin = plugins.find(plugin => plugin.name === BYTECODE_BUILD_PLUGIN_NAME)
|
||||||
|
return (plugin?.api as { compiler?: BytecodeCompiler } | undefined)?.compiler
|
||||||
|
}
|
||||||
|
|
||||||
// Versioned envelope: magic/version (8), UTF-16 source length (4), module ID (16), V8 cache.
|
// 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.
|
// Keep our metadata separate from the private V8 cache header.
|
||||||
async function compileToBytecode(build: BytecodeBuild, target: BytecodeTarget, code: string): Promise<Buffer> {
|
async function compileToBytecode(compiler: BytecodeCompiler, target: BytecodeTarget, code: string): Promise<Buffer> {
|
||||||
const id = randomBytes(16)
|
const id = randomBytes(16)
|
||||||
// Reserve enough source space for an untruncated, per-artifact placeholder identity.
|
// Reserve enough source space for an untruncated, per-artifact placeholder identity.
|
||||||
const source = code + '\n/*' + id.toString('hex') + '*/'
|
const source = code + '\n/*' + id.toString('hex') + '*/'
|
||||||
const result = await build.compile(target, source)
|
const result = await compiler.compile(target, source)
|
||||||
const header = Buffer.alloc(28)
|
const header = Buffer.alloc(28)
|
||||||
header.write('EVBC0001', 0, 'ascii')
|
header.write('EVBC0001', 0, 'ascii')
|
||||||
header.writeUInt32LE(result.sourceLength, 8)
|
header.writeUInt32LE(result.sourceLength, 8)
|
||||||
@ -118,14 +123,14 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
|||||||
|
|
||||||
let supported = false
|
let supported = false
|
||||||
let isPreload = false
|
let isPreload = false
|
||||||
let bytecodeBuild: BytecodeBuild | undefined
|
let bytecodeCompiler: BytecodeCompiler | undefined
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'vite:bytecode',
|
name: 'vite:bytecode',
|
||||||
apply: 'build',
|
apply: 'build',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
configResolved(config): void {
|
configResolved(config): void {
|
||||||
bytecodeBuild = getBytecodeBuild(config.plugins)
|
bytecodeCompiler = getBytecodeCompiler(config.plugins)
|
||||||
if (supported) {
|
if (supported) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -184,8 +189,8 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
|||||||
|
|
||||||
const bundles = Object.keys(output)
|
const bundles = Object.keys(output)
|
||||||
|
|
||||||
if (!bytecodeBuild) {
|
if (!bytecodeCompiler) {
|
||||||
throw new Error('Bytecode compilation requires an electron-vite build session')
|
throw new Error('Bytecode compilation requires an electron-vite build')
|
||||||
}
|
}
|
||||||
for (const name of bundles) {
|
for (const name of bundles) {
|
||||||
const chunk = output[name]
|
const chunk = output[name]
|
||||||
@ -207,7 +212,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bytecodeChunks.includes(name)) {
|
if (bytecodeChunks.includes(name)) {
|
||||||
const bytecodeBuffer = await compileToBytecode(bytecodeBuild, isPreload ? 'preload' : 'main', _code)
|
const bytecodeBuffer = await compileToBytecode(bytecodeCompiler, isPreload ? 'preload' : 'main', _code)
|
||||||
this.emitFile({
|
this.emitFile({
|
||||||
type: 'asset',
|
type: 'asset',
|
||||||
fileName: name + 'c',
|
fileName: name + 'c',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user