mirror of
https://github.com/alex8088/electron-vite.git
synced 2026-07-10 00:11:10 +08:00
Compare commits
4 Commits
3e9ded666c
...
9152dfc943
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9152dfc943 | ||
|
|
0276407b5b | ||
|
|
fe7e631f47 | ||
|
|
08be346407 |
110
src/config.ts
110
src/config.ts
@ -7,6 +7,8 @@ import {
|
||||
type UserConfig as ViteConfig,
|
||||
type ConfigEnv,
|
||||
type PluginOption,
|
||||
type Plugin,
|
||||
type BuildEnvironmentOptions as ViteBuildOptions,
|
||||
type LogLevel,
|
||||
createLogger,
|
||||
mergeConfig,
|
||||
@ -28,11 +30,13 @@ import importMetaPlugin from './plugins/importMeta'
|
||||
import esmShimPlugin from './plugins/esmShim'
|
||||
import modulePathPlugin from './plugins/modulePath'
|
||||
import isolateEntriesPlugin from './plugins/isolateEntries'
|
||||
import { isObject, isFilePathESM, deepClone } from './utils'
|
||||
import { type ExternalOptions, externalizeDepsPlugin } from './plugins/externalizeDeps'
|
||||
import { type BytecodeOptions, bytecodePlugin } from './plugins/bytecode'
|
||||
import { isObject, isFilePathESM, deepClone, asyncFlatten } from './utils'
|
||||
|
||||
export { defineConfig as defineViteConfig } from 'vite'
|
||||
|
||||
interface IsolatedEntriesOption {
|
||||
interface IsolatedEntriesMixin {
|
||||
/**
|
||||
* Build each entry point as an isolated bundle without code splitting.
|
||||
*
|
||||
@ -40,17 +44,56 @@ interface IsolatedEntriesOption {
|
||||
* preventing automatic code splitting across entries and ensuring each
|
||||
* output file is fully standalone.
|
||||
*
|
||||
* **Important**: When using `isolatedEntries` in `preload` config, you
|
||||
* should also disable `build.externalizeDeps` to ensure third-party dependencies
|
||||
* from `node_modules` are bundled together, which is required for Electron
|
||||
* sandbox support.
|
||||
*
|
||||
* @experimental
|
||||
* @default false
|
||||
*/
|
||||
isolatedEntries?: boolean
|
||||
}
|
||||
|
||||
export interface MainViteConfig extends ViteConfig {}
|
||||
interface ExternalizeDepsMixin {
|
||||
/**
|
||||
* Options pass on to `externalizeDeps` plugin in electron-vite.
|
||||
*
|
||||
* Automatically externalize dependencies.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
externalizeDeps?: boolean | ExternalOptions
|
||||
}
|
||||
|
||||
export interface PreloadViteConfig extends ViteConfig, IsolatedEntriesOption {}
|
||||
interface BytecodeMixin {
|
||||
/**
|
||||
* Options pass on to `bytecode` plugin in electron-vite.
|
||||
* https://electron-vite.org/guide/source-code-protection#bytecodeplugin-options
|
||||
*
|
||||
* Compile source code to v8 bytecode.
|
||||
*/
|
||||
bytecode?: boolean | BytecodeOptions
|
||||
}
|
||||
|
||||
export interface RendererViteConfig extends ViteConfig, IsolatedEntriesOption {}
|
||||
interface MainBuildOptions extends ViteBuildOptions, ExternalizeDepsMixin, BytecodeMixin {}
|
||||
|
||||
interface PreloadBuildOptions extends ViteBuildOptions, ExternalizeDepsMixin, BytecodeMixin, IsolatedEntriesMixin {}
|
||||
|
||||
interface RendererBuildOptions extends ViteBuildOptions, IsolatedEntriesMixin {}
|
||||
|
||||
interface BaseViteConfig<T> extends Omit<ViteConfig, 'build'> {
|
||||
/**
|
||||
* Build specific options
|
||||
*/
|
||||
build?: T
|
||||
}
|
||||
|
||||
export interface MainViteConfig extends BaseViteConfig<MainBuildOptions> {}
|
||||
|
||||
export interface PreloadViteConfig extends BaseViteConfig<PreloadBuildOptions> {}
|
||||
|
||||
export interface RendererViteConfig extends BaseViteConfig<RendererBuildOptions> {}
|
||||
|
||||
export interface UserConfig {
|
||||
/**
|
||||
@ -157,6 +200,8 @@ export async function resolveConfig(
|
||||
resetOutDir(mainViteConfig, outDir, 'main')
|
||||
}
|
||||
|
||||
const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(mainViteConfig)
|
||||
|
||||
const builtInMainPlugins: PluginOption[] = [
|
||||
electronMainConfigPresetPlugin({ root }),
|
||||
electronMainConfigValidatorPlugin(),
|
||||
@ -165,13 +210,20 @@ export async function resolveConfig(
|
||||
modulePathPlugin(
|
||||
mergeConfig(
|
||||
{
|
||||
plugins: [electronMainConfigPresetPlugin({ root }), assetPlugin(), importMetaPlugin(), esmShimPlugin()]
|
||||
plugins: [
|
||||
electronMainConfigPresetPlugin({ root }),
|
||||
assetPlugin(),
|
||||
importMetaPlugin(),
|
||||
esmShimPlugin(),
|
||||
...configDrivenPlugins
|
||||
]
|
||||
},
|
||||
mainViteConfig
|
||||
)
|
||||
),
|
||||
importMetaPlugin(),
|
||||
esmShimPlugin()
|
||||
esmShimPlugin(),
|
||||
...configDrivenPlugins
|
||||
]
|
||||
|
||||
mainViteConfig.plugins = builtInMainPlugins.concat(mainViteConfig.plugins || [])
|
||||
@ -188,15 +240,18 @@ export async function resolveConfig(
|
||||
resetOutDir(preloadViteConfig, outDir, 'preload')
|
||||
}
|
||||
|
||||
const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(preloadViteConfig)
|
||||
|
||||
const builtInPreloadPlugins: PluginOption[] = [
|
||||
electronPreloadConfigPresetPlugin({ root }),
|
||||
electronPreloadConfigValidatorPlugin(),
|
||||
assetPlugin(),
|
||||
importMetaPlugin(),
|
||||
esmShimPlugin()
|
||||
esmShimPlugin(),
|
||||
...configDrivenPlugins
|
||||
]
|
||||
|
||||
if (preloadViteConfig.isolatedEntries) {
|
||||
if (preloadViteConfig.build?.isolatedEntries) {
|
||||
builtInPreloadPlugins.push(
|
||||
isolateEntriesPlugin(
|
||||
mergeConfig(
|
||||
@ -205,7 +260,8 @@ export async function resolveConfig(
|
||||
electronPreloadConfigPresetPlugin({ root }),
|
||||
assetPlugin(),
|
||||
importMetaPlugin(),
|
||||
esmShimPlugin()
|
||||
esmShimPlugin(),
|
||||
...configDrivenPlugins
|
||||
]
|
||||
},
|
||||
preloadViteConfig
|
||||
@ -233,7 +289,7 @@ export async function resolveConfig(
|
||||
electronRendererConfigValidatorPlugin()
|
||||
]
|
||||
|
||||
if (rendererViteConfig.isolatedEntries) {
|
||||
if (rendererViteConfig.build?.isolatedEntries) {
|
||||
builtInRendererPlugins.push(
|
||||
isolateEntriesPlugin(
|
||||
mergeConfig(
|
||||
@ -278,6 +334,38 @@ function resetOutDir(config: ViteConfig, outDir: string, subOutDir: string): voi
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveConfigDrivenPlugins(config: MainViteConfig | PreloadViteConfig): Promise<PluginOption[]> {
|
||||
const userPlugins = (await asyncFlatten(config.plugins || [])).filter(Boolean) as Plugin[]
|
||||
|
||||
const configDrivenPlugins: PluginOption[] = []
|
||||
|
||||
const hasExternalizeDepsPlugin = userPlugins.some(p => p.name === 'vite:externalize-deps')
|
||||
if (!hasExternalizeDepsPlugin) {
|
||||
const externalOptions = config.build?.externalizeDeps ?? true
|
||||
if (externalOptions) {
|
||||
isOptions<ExternalOptions>(externalOptions)
|
||||
? configDrivenPlugins.push(externalizeDepsPlugin(externalOptions))
|
||||
: configDrivenPlugins.push(externalizeDepsPlugin())
|
||||
}
|
||||
}
|
||||
|
||||
const hasBytecodePlugin = userPlugins.some(p => p.name === 'vite:bytecode')
|
||||
if (!hasBytecodePlugin) {
|
||||
const bytecodeOptions = config.build?.bytecode
|
||||
if (bytecodeOptions) {
|
||||
isOptions<BytecodeOptions>(bytecodeOptions)
|
||||
? configDrivenPlugins.push(bytecodePlugin(bytecodeOptions))
|
||||
: configDrivenPlugins.push(bytecodePlugin())
|
||||
}
|
||||
}
|
||||
|
||||
return configDrivenPlugins
|
||||
}
|
||||
|
||||
function isOptions<T extends object>(value: boolean | T): value is T {
|
||||
return typeof value === 'object' && value !== null
|
||||
}
|
||||
|
||||
const CONFIG_FILE_NAME = 'electron.vite.config'
|
||||
|
||||
export async function loadConfigFromFile(
|
||||
|
||||
@ -150,7 +150,9 @@ export interface BytecodeOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile to v8 bytecode to protect source code.
|
||||
* Compile source code to v8 bytecode.
|
||||
*
|
||||
* @deprecated use `build.bytecode` config option instead
|
||||
*/
|
||||
export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||
if (process.env.NODE_ENV_ELECTRON_VITE !== 'production') {
|
||||
|
||||
@ -7,7 +7,9 @@ export interface ExternalOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically externalize dependencies
|
||||
* Automatically externalize dependencies.
|
||||
*
|
||||
* @deprecated use `build.externalizeDeps` config option instead
|
||||
*/
|
||||
export function externalizeDepsPlugin(options: ExternalOptions = {}): Plugin | null {
|
||||
const { exclude = [], include = [] } = options
|
||||
|
||||
@ -88,7 +88,6 @@ async function bundleEntryFile(
|
||||
const reporter = watch ? buildReporterPlugin() : undefined
|
||||
const viteConfig = mergeConfig(config, {
|
||||
build: {
|
||||
rollupOptions: { input },
|
||||
write: false,
|
||||
watch: false
|
||||
},
|
||||
@ -106,7 +105,15 @@ async function bundleEntryFile(
|
||||
],
|
||||
logLevel: 'warn',
|
||||
configFile: false
|
||||
})
|
||||
}) as InlineConfig
|
||||
|
||||
// rewrite the input instead of merging
|
||||
const buildOptions = viteConfig.build!
|
||||
buildOptions.rollupOptions = {
|
||||
...buildOptions.rollupOptions,
|
||||
input
|
||||
}
|
||||
|
||||
const bundles = await viteBuild(viteConfig)
|
||||
|
||||
return {
|
||||
|
||||
@ -111,3 +111,12 @@ export function deepClone<T>(value: T): DeepWritable<T> {
|
||||
}
|
||||
return value as DeepWritable<T>
|
||||
}
|
||||
|
||||
type AsyncFlatten<T extends unknown[]> = T extends (infer U)[] ? Exclude<Awaited<U>, U[]>[] : never
|
||||
|
||||
export async function asyncFlatten<T extends unknown[]>(arr: T): Promise<AsyncFlatten<T>> {
|
||||
do {
|
||||
arr = (await Promise.all(arr)).flat(Infinity) as any
|
||||
} while (arr.some((v: any) => v?.then))
|
||||
return arr as unknown[] as AsyncFlatten<T>
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user