mirror of
https://github.com/alex8088/electron-vite.git
synced 2025-11-09 22:16:01 +08:00
refactor: split electron plugin into preset and validator plugins
This commit is contained in:
parent
0a79da03db
commit
88f6db2239
108
src/config.ts
108
src/config.ts
@ -7,7 +7,7 @@ import {
|
|||||||
type UserConfig as ViteConfig,
|
type UserConfig as ViteConfig,
|
||||||
type UserConfigExport as ViteConfigExport,
|
type UserConfigExport as ViteConfigExport,
|
||||||
type ConfigEnv,
|
type ConfigEnv,
|
||||||
type Plugin,
|
type PluginOption,
|
||||||
type LogLevel,
|
type LogLevel,
|
||||||
createLogger,
|
createLogger,
|
||||||
mergeConfig,
|
mergeConfig,
|
||||||
@ -15,7 +15,14 @@ import {
|
|||||||
} from 'vite'
|
} from 'vite'
|
||||||
import { build } from 'esbuild'
|
import { build } from 'esbuild'
|
||||||
|
|
||||||
import { electronMainVitePlugin, electronPreloadVitePlugin, electronRendererVitePlugin } from './plugins/electron'
|
import {
|
||||||
|
electronMainConfigPresetPlugin,
|
||||||
|
electronMainConfigValidatorPlugin,
|
||||||
|
electronPreloadConfigPresetPlugin,
|
||||||
|
electronPreloadConfigValidatorPlugin,
|
||||||
|
electronRendererConfigPresetPlugin,
|
||||||
|
electronRendererConfigValidatorPlugin
|
||||||
|
} from './plugins/electron'
|
||||||
import assetPlugin from './plugins/asset'
|
import assetPlugin from './plugins/asset'
|
||||||
import workerPlugin from './plugins/worker'
|
import workerPlugin from './plugins/worker'
|
||||||
import importMetaPlugin from './plugins/importMeta'
|
import importMetaPlugin from './plugins/importMeta'
|
||||||
@ -173,21 +180,24 @@ export async function resolveConfig(
|
|||||||
resetOutDir(mainViteConfig, outDir, 'main')
|
resetOutDir(mainViteConfig, outDir, 'main')
|
||||||
}
|
}
|
||||||
|
|
||||||
mergePlugins(mainViteConfig, [
|
const builtInMainPlugins: PluginOption[] = [
|
||||||
...electronMainVitePlugin({ root }),
|
electronMainConfigPresetPlugin({ root }),
|
||||||
|
electronMainConfigValidatorPlugin(),
|
||||||
assetPlugin(),
|
assetPlugin(),
|
||||||
workerPlugin(),
|
workerPlugin(),
|
||||||
modulePathPlugin(
|
modulePathPlugin(
|
||||||
mergeConfig(
|
mergeConfig(
|
||||||
{
|
{
|
||||||
plugins: [electronMainVitePlugin({ root })[0], assetPlugin(), importMetaPlugin(), esmShimPlugin()]
|
plugins: [electronMainConfigPresetPlugin({ root }), assetPlugin(), importMetaPlugin(), esmShimPlugin()]
|
||||||
},
|
},
|
||||||
mainViteConfig
|
mainViteConfig
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
importMetaPlugin(),
|
importMetaPlugin(),
|
||||||
esmShimPlugin()
|
esmShimPlugin()
|
||||||
])
|
]
|
||||||
|
|
||||||
|
mainViteConfig.plugins = builtInMainPlugins.concat(mainViteConfig.plugins || [])
|
||||||
|
|
||||||
loadResult.config.main = mainViteConfig
|
loadResult.config.main = mainViteConfig
|
||||||
loadResult.config.main.configFile = false
|
loadResult.config.main.configFile = false
|
||||||
@ -204,29 +214,34 @@ export async function resolveConfig(
|
|||||||
if (outDir) {
|
if (outDir) {
|
||||||
resetOutDir(preloadViteConfig, outDir, 'preload')
|
resetOutDir(preloadViteConfig, outDir, 'preload')
|
||||||
}
|
}
|
||||||
mergePlugins(preloadViteConfig, [
|
|
||||||
...electronPreloadVitePlugin({ root }),
|
const builtInPreloadPlugins: PluginOption[] = [
|
||||||
|
electronPreloadConfigPresetPlugin({ root }),
|
||||||
|
electronPreloadConfigValidatorPlugin(),
|
||||||
assetPlugin(),
|
assetPlugin(),
|
||||||
importMetaPlugin(),
|
importMetaPlugin(),
|
||||||
esmShimPlugin(),
|
esmShimPlugin()
|
||||||
...(preloadViteConfig.isolatedEntries
|
]
|
||||||
? [
|
|
||||||
isolateEntriesPlugin(
|
if (preloadViteConfig.isolatedEntries) {
|
||||||
mergeConfig(
|
builtInPreloadPlugins.push(
|
||||||
{
|
isolateEntriesPlugin(
|
||||||
plugins: [
|
mergeConfig(
|
||||||
electronPreloadVitePlugin({ root })[0],
|
{
|
||||||
assetPlugin(),
|
plugins: [
|
||||||
importMetaPlugin(),
|
electronPreloadConfigPresetPlugin({ root }),
|
||||||
esmShimPlugin()
|
assetPlugin(),
|
||||||
]
|
importMetaPlugin(),
|
||||||
},
|
esmShimPlugin()
|
||||||
preloadViteConfig
|
]
|
||||||
)
|
},
|
||||||
)
|
preloadViteConfig
|
||||||
]
|
)
|
||||||
: [])
|
)
|
||||||
])
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
preloadViteConfig.plugins = builtInPreloadPlugins.concat(preloadViteConfig.plugins)
|
||||||
|
|
||||||
loadResult.config.preload = preloadViteConfig
|
loadResult.config.preload = preloadViteConfig
|
||||||
loadResult.config.preload.configFile = false
|
loadResult.config.preload.configFile = false
|
||||||
@ -244,21 +259,25 @@ export async function resolveConfig(
|
|||||||
resetOutDir(rendererViteConfig, outDir, 'renderer')
|
resetOutDir(rendererViteConfig, outDir, 'renderer')
|
||||||
}
|
}
|
||||||
|
|
||||||
mergePlugins(rendererViteConfig, [
|
const builtInRendererPlugins: PluginOption[] = [
|
||||||
...electronRendererVitePlugin({ root }),
|
electronRendererConfigPresetPlugin({ root }),
|
||||||
...(rendererViteConfig.isolatedEntries
|
electronRendererConfigValidatorPlugin()
|
||||||
? [
|
]
|
||||||
isolateEntriesPlugin(
|
|
||||||
mergeConfig(
|
if (rendererViteConfig.isolatedEntries) {
|
||||||
{
|
builtInRendererPlugins.push(
|
||||||
plugins: [electronRendererVitePlugin({ root })[0]]
|
isolateEntriesPlugin(
|
||||||
},
|
mergeConfig(
|
||||||
rendererViteConfig
|
{
|
||||||
)
|
plugins: [electronRendererConfigPresetPlugin({ root })]
|
||||||
)
|
},
|
||||||
]
|
rendererViteConfig
|
||||||
: [])
|
)
|
||||||
])
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
rendererViteConfig.plugins = builtInRendererPlugins.concat(rendererViteConfig.plugins || [])
|
||||||
|
|
||||||
loadResult.config.renderer = rendererViteConfig
|
loadResult.config.renderer = rendererViteConfig
|
||||||
loadResult.config.renderer.configFile = false
|
loadResult.config.renderer.configFile = false
|
||||||
@ -295,11 +314,6 @@ function resetOutDir(config: ViteConfig, outDir: string, subOutDir: string): voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergePlugins(config: ViteConfig, plugins: Plugin[]): void {
|
|
||||||
const userPlugins = config.plugins || []
|
|
||||||
config.plugins = userPlugins.concat(plugins)
|
|
||||||
}
|
|
||||||
|
|
||||||
const CONFIG_FILE_NAME = 'electron.vite.config'
|
const CONFIG_FILE_NAME = 'electron.vite.config'
|
||||||
|
|
||||||
export async function loadConfigFromFile(
|
export async function loadConfigFromFile(
|
||||||
|
|||||||
@ -50,368 +50,363 @@ function resolveBuildOutputs(
|
|||||||
return outputs
|
return outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
export function electronMainVitePlugin(options?: ElectronPluginOptions): Plugin[] {
|
export function electronMainConfigPresetPlugin(options?: ElectronPluginOptions): Plugin {
|
||||||
return [
|
return {
|
||||||
{
|
name: 'vite:electron-main-config-preset',
|
||||||
name: 'vite:electron-main-preset-config',
|
apply: 'build',
|
||||||
apply: 'build',
|
enforce: 'pre',
|
||||||
enforce: 'pre',
|
config(config): void {
|
||||||
config(config): void {
|
const root = options?.root || process.cwd()
|
||||||
const root = options?.root || process.cwd()
|
|
||||||
|
|
||||||
const nodeTarget = getElectronNodeTarget()
|
const nodeTarget = getElectronNodeTarget()
|
||||||
|
|
||||||
const pkg = loadPackageData() || { type: 'commonjs' }
|
const pkg = loadPackageData() || { type: 'commonjs' }
|
||||||
|
|
||||||
const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs'
|
const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs'
|
||||||
|
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
resolve: {
|
resolve: {
|
||||||
browserField: false,
|
browserField: false,
|
||||||
mainFields: ['module', 'jsnext:main', 'jsnext'],
|
mainFields: ['module', 'jsnext:main', 'jsnext'],
|
||||||
conditions: ['node']
|
conditions: ['node']
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: path.resolve(root, 'out', 'main'),
|
||||||
|
target: nodeTarget,
|
||||||
|
assetsDir: 'chunks',
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
|
||||||
|
output: {}
|
||||||
},
|
},
|
||||||
build: {
|
reportCompressedSize: false,
|
||||||
outDir: path.resolve(root, 'out', 'main'),
|
minify: false
|
||||||
target: nodeTarget,
|
|
||||||
assetsDir: 'chunks',
|
|
||||||
rollupOptions: {
|
|
||||||
external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
|
|
||||||
output: {}
|
|
||||||
},
|
|
||||||
reportCompressedSize: false,
|
|
||||||
minify: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const build = config.build || {}
|
|
||||||
const rollupOptions = build.rollupOptions || {}
|
|
||||||
if (!rollupOptions.input) {
|
|
||||||
const libOptions = build.lib
|
|
||||||
const outputOptions = rollupOptions.output
|
|
||||||
defaultConfig.build['lib'] = {
|
|
||||||
entry: findLibEntry(root, 'main'),
|
|
||||||
formats:
|
|
||||||
libOptions && libOptions.formats && libOptions.formats.length > 0
|
|
||||||
? []
|
|
||||||
: [
|
|
||||||
outputOptions && !Array.isArray(outputOptions) && outputOptions.format
|
|
||||||
? outputOptions.format
|
|
||||||
: format
|
|
||||||
]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defaultConfig.build.rollupOptions.output['format'] = format
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(
|
|
||||||
build.assetsDir || defaultConfig.build.assetsDir,
|
|
||||||
'[name]-[hash].[ext]'
|
|
||||||
)
|
|
||||||
|
|
||||||
const buildConfig = mergeConfig(defaultConfig.build, build)
|
|
||||||
config.build = buildConfig
|
|
||||||
|
|
||||||
config.resolve = mergeConfig(defaultConfig.resolve, config.resolve || {})
|
|
||||||
|
|
||||||
config.define = config.define || {}
|
|
||||||
config.define = { ...processEnvDefine(), ...config.define }
|
|
||||||
|
|
||||||
config.envPrefix = config.envPrefix || ['MAIN_VITE_', 'VITE_']
|
|
||||||
|
|
||||||
config.publicDir = config.publicDir || 'resources'
|
|
||||||
// do not copy public dir
|
|
||||||
config.build.copyPublicDir = false
|
|
||||||
// module preload polyfill does not apply to nodejs (main process)
|
|
||||||
config.build.modulePreload = false
|
|
||||||
// enable ssr build
|
|
||||||
config.build.ssr = true
|
|
||||||
config.build.ssrEmitAssets = true
|
|
||||||
config.ssr = { ...config.ssr, ...{ noExternal: true } }
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'vite:electron-main-resolved-config',
|
|
||||||
apply: 'build',
|
|
||||||
enforce: 'post',
|
|
||||||
configResolved(config): void {
|
|
||||||
const build = config.build
|
|
||||||
if (!build.target) {
|
|
||||||
throw new Error('build.target option is required in the electron vite main config.')
|
|
||||||
} else {
|
|
||||||
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
|
||||||
if (targets.some(t => !t.startsWith('node'))) {
|
|
||||||
throw new Error('The electron vite main config build.target option must be "node?".')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const build = config.build || {}
|
||||||
|
const rollupOptions = build.rollupOptions || {}
|
||||||
|
if (!rollupOptions.input) {
|
||||||
const libOptions = build.lib
|
const libOptions = build.lib
|
||||||
const rollupOptions = build.rollupOptions
|
const outputOptions = rollupOptions.output
|
||||||
|
defaultConfig.build['lib'] = {
|
||||||
if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
|
entry: findLibEntry(root, 'main'),
|
||||||
throw new Error(
|
formats:
|
||||||
'An entry point is required in the electron vite main config, ' +
|
libOptions && libOptions.formats && libOptions.formats.length > 0
|
||||||
'which can be specified using "build.lib.entry" or "build.rollupOptions.input".'
|
? []
|
||||||
)
|
: [outputOptions && !Array.isArray(outputOptions) && outputOptions.format ? outputOptions.format : format]
|
||||||
}
|
|
||||||
|
|
||||||
const resolvedOutputs = resolveBuildOutputs(rollupOptions.output, libOptions)
|
|
||||||
|
|
||||||
if (resolvedOutputs) {
|
|
||||||
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
|
||||||
if (outputs.length > 1) {
|
|
||||||
throw new Error('The electron vite main config does not support multiple outputs.')
|
|
||||||
} else {
|
|
||||||
const outpout = outputs[0]
|
|
||||||
if (['es', 'cjs'].includes(outpout.format || '')) {
|
|
||||||
if (outpout.format === 'es' && !supportESM()) {
|
|
||||||
throw new Error(
|
|
||||||
'The electron vite main config output format does not support "es", ' +
|
|
||||||
'you can upgrade electron to the latest version or switch to "cjs" format.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`The electron vite main config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
defaultConfig.build.rollupOptions.output['format'] = format
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(
|
||||||
|
build.assetsDir || defaultConfig.build.assetsDir,
|
||||||
|
'[name]-[hash].[ext]'
|
||||||
|
)
|
||||||
|
|
||||||
|
const buildConfig = mergeConfig(defaultConfig.build, build)
|
||||||
|
config.build = buildConfig
|
||||||
|
|
||||||
|
config.resolve = mergeConfig(defaultConfig.resolve, config.resolve || {})
|
||||||
|
|
||||||
|
config.define = config.define || {}
|
||||||
|
config.define = { ...processEnvDefine(), ...config.define }
|
||||||
|
|
||||||
|
config.envPrefix = config.envPrefix || ['MAIN_VITE_', 'VITE_']
|
||||||
|
|
||||||
|
config.publicDir = config.publicDir || 'resources'
|
||||||
|
// do not copy public dir
|
||||||
|
config.build.copyPublicDir = false
|
||||||
|
// module preload polyfill does not apply to nodejs (main process)
|
||||||
|
config.build.modulePreload = false
|
||||||
|
// enable ssr build
|
||||||
|
config.build.ssr = true
|
||||||
|
config.build.ssrEmitAssets = true
|
||||||
|
config.ssr = { ...config.ssr, ...{ noExternal: true } }
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function electronPreloadVitePlugin(options?: ElectronPluginOptions): Plugin[] {
|
export function electronMainConfigValidatorPlugin(): Plugin {
|
||||||
return [
|
return {
|
||||||
{
|
name: 'vite:electron-main-config-validator',
|
||||||
name: 'vite:electron-preload-preset-config',
|
apply: 'build',
|
||||||
apply: 'build',
|
enforce: 'post',
|
||||||
enforce: 'pre',
|
configResolved(config): void {
|
||||||
config(config): void {
|
const build = config.build
|
||||||
const root = options?.root || process.cwd()
|
if (!build.target) {
|
||||||
|
throw new Error('build.target option is required in the electron vite main config.')
|
||||||
const nodeTarget = getElectronNodeTarget()
|
} else {
|
||||||
|
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
||||||
const pkg = loadPackageData() || { type: 'commonjs' }
|
if (targets.some(t => !t.startsWith('node'))) {
|
||||||
|
throw new Error('The electron vite main config build.target option must be "node?".')
|
||||||
const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs'
|
|
||||||
|
|
||||||
const defaultConfig = {
|
|
||||||
ssr: {
|
|
||||||
resolve: {
|
|
||||||
conditions: ['module', 'browser', 'development|production'],
|
|
||||||
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
outDir: path.resolve(root, 'out', 'preload'),
|
|
||||||
target: nodeTarget,
|
|
||||||
assetsDir: 'chunks',
|
|
||||||
rollupOptions: {
|
|
||||||
external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
|
|
||||||
output: {}
|
|
||||||
},
|
|
||||||
reportCompressedSize: false,
|
|
||||||
minify: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const build = config.build || {}
|
|
||||||
const rollupOptions = build.rollupOptions || {}
|
|
||||||
if (!rollupOptions.input) {
|
|
||||||
const libOptions = build.lib
|
|
||||||
const outputOptions = rollupOptions.output
|
|
||||||
defaultConfig.build['lib'] = {
|
|
||||||
entry: findLibEntry(root, 'preload'),
|
|
||||||
formats:
|
|
||||||
libOptions && libOptions.formats && libOptions.formats.length > 0
|
|
||||||
? []
|
|
||||||
: [
|
|
||||||
outputOptions && !Array.isArray(outputOptions) && outputOptions.format
|
|
||||||
? outputOptions.format
|
|
||||||
: format
|
|
||||||
]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defaultConfig.build.rollupOptions.output['format'] = format
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(
|
|
||||||
build.assetsDir || defaultConfig.build.assetsDir,
|
|
||||||
'[name]-[hash].[ext]'
|
|
||||||
)
|
|
||||||
|
|
||||||
const buildConfig = mergeConfig(defaultConfig.build, build)
|
|
||||||
config.build = buildConfig
|
|
||||||
|
|
||||||
const resolvedOutputs = resolveBuildOutputs(config.build.rollupOptions!.output, config.build.lib || false)
|
|
||||||
|
|
||||||
if (resolvedOutputs) {
|
|
||||||
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
|
||||||
|
|
||||||
if (outputs.find(({ format }) => format === 'es')) {
|
|
||||||
if (Array.isArray(config.build.rollupOptions!.output)) {
|
|
||||||
config.build.rollupOptions!.output.forEach(output => {
|
|
||||||
if (output.format === 'es') {
|
|
||||||
output['entryFileNames'] = '[name].mjs'
|
|
||||||
output['chunkFileNames'] = '[name]-[hash].mjs'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
config.build.rollupOptions!.output!['entryFileNames'] = '[name].mjs'
|
|
||||||
config.build.rollupOptions!.output!['chunkFileNames'] = '[name]-[hash].mjs'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.define = config.define || {}
|
|
||||||
config.define = { ...processEnvDefine(), ...config.define }
|
|
||||||
|
|
||||||
config.envPrefix = config.envPrefix || ['PRELOAD_VITE_', 'VITE_']
|
|
||||||
|
|
||||||
config.publicDir = config.publicDir || 'resources'
|
|
||||||
// do not copy public dir
|
|
||||||
config.build.copyPublicDir = false
|
|
||||||
// module preload polyfill does not apply to nodejs (preload scripts)
|
|
||||||
config.build.modulePreload = false
|
|
||||||
// enable ssr build
|
|
||||||
config.build.ssr = true
|
|
||||||
config.build.ssrEmitAssets = true
|
|
||||||
config.ssr = mergeConfig(defaultConfig.ssr, config.ssr || {})
|
|
||||||
config.ssr.noExternal = true
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
const libOptions = build.lib
|
||||||
name: 'vite:electron-preload-resolved-config',
|
const rollupOptions = build.rollupOptions
|
||||||
apply: 'build',
|
|
||||||
enforce: 'post',
|
if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
|
||||||
configResolved(config): void {
|
throw new Error(
|
||||||
const build = config.build
|
'An entry point is required in the electron vite main config, ' +
|
||||||
if (!build.target) {
|
'which can be specified using "build.lib.entry" or "build.rollupOptions.input".'
|
||||||
throw new Error('build.target option is required in the electron vite preload config.')
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolvedOutputs = resolveBuildOutputs(rollupOptions.output, libOptions)
|
||||||
|
|
||||||
|
if (resolvedOutputs) {
|
||||||
|
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
||||||
|
if (outputs.length > 1) {
|
||||||
|
throw new Error('The electron vite main config does not support multiple outputs.')
|
||||||
} else {
|
} else {
|
||||||
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
const outpout = outputs[0]
|
||||||
if (targets.some(t => !t.startsWith('node'))) {
|
if (['es', 'cjs'].includes(outpout.format || '')) {
|
||||||
throw new Error('The electron vite preload config build.target must be "node?".')
|
if (outpout.format === 'es' && !supportESM()) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const libOptions = build.lib
|
|
||||||
const rollupOptions = build.rollupOptions
|
|
||||||
|
|
||||||
if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
|
|
||||||
throw new Error(
|
|
||||||
'An entry point is required in the electron vite preload config, ' +
|
|
||||||
'which can be specified using "build.lib.entry" or "build.rollupOptions.input".'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolvedOutputs = resolveBuildOutputs(rollupOptions.output, libOptions)
|
|
||||||
|
|
||||||
if (resolvedOutputs) {
|
|
||||||
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
|
||||||
if (outputs.length > 1) {
|
|
||||||
throw new Error('The electron vite preload config does not support multiple outputs.')
|
|
||||||
} else {
|
|
||||||
const outpout = outputs[0]
|
|
||||||
if (['es', 'cjs'].includes(outpout.format || '')) {
|
|
||||||
if (outpout.format === 'es' && !supportESM()) {
|
|
||||||
throw new Error(
|
|
||||||
'The electron vite preload config output format does not support "es", ' +
|
|
||||||
'you can upgrade electron to the latest version or switch to "cjs" format.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The electron vite preload config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`
|
'The electron vite main config output format does not support "es", ' +
|
||||||
|
'you can upgrade electron to the latest version or switch to "cjs" format.'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
throw new Error(
|
||||||
}
|
`The electron vite main config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export function electronRendererVitePlugin(options?: ElectronPluginOptions): Plugin[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'vite:electron-renderer-preset-config',
|
|
||||||
enforce: 'pre',
|
|
||||||
config(config): void {
|
|
||||||
const root = options?.root || process.cwd()
|
|
||||||
|
|
||||||
config.base =
|
|
||||||
config.mode === 'production' || process.env.NODE_ENV_ELECTRON_VITE === 'production' ? './' : config.base
|
|
||||||
config.root = config.root || './src/renderer'
|
|
||||||
|
|
||||||
const chromeTarget = getElectronChromeTarget()
|
|
||||||
|
|
||||||
const emptyOutDir = (): boolean => {
|
|
||||||
let outDir = config.build?.outDir
|
|
||||||
if (outDir) {
|
|
||||||
if (!path.isAbsolute(outDir)) {
|
|
||||||
outDir = path.resolve(root, outDir)
|
|
||||||
}
|
|
||||||
const resolvedRoot = normalizePath(path.resolve(root))
|
|
||||||
return normalizePath(outDir).startsWith(resolvedRoot + '/')
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultConfig = {
|
|
||||||
build: {
|
|
||||||
outDir: path.resolve(root, 'out', 'renderer'),
|
|
||||||
target: chromeTarget,
|
|
||||||
modulePreload: { polyfill: false },
|
|
||||||
rollupOptions: {
|
|
||||||
input: findInput(root)
|
|
||||||
},
|
|
||||||
reportCompressedSize: false,
|
|
||||||
minify: false,
|
|
||||||
emptyOutDir: emptyOutDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.build?.outDir) {
|
|
||||||
config.build.outDir = path.resolve(root, config.build.outDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildConfig = mergeConfig(defaultConfig.build, config.build || {})
|
|
||||||
config.build = buildConfig
|
|
||||||
|
|
||||||
config.envDir = config.envDir || path.resolve(root)
|
|
||||||
|
|
||||||
config.envPrefix = config.envPrefix || ['RENDERER_VITE_', 'VITE_']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'vite:electron-renderer-resolved-config',
|
|
||||||
enforce: 'post',
|
|
||||||
configResolved(config): void {
|
|
||||||
if (config.base !== './' && config.base !== '/') {
|
|
||||||
config.logger.warn(colors.yellow('(!) Should not set "base" option for the electron vite renderer config.'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const build = config.build
|
|
||||||
if (!build.target) {
|
|
||||||
throw new Error('build.target option is required in the electron vite renderer config.')
|
|
||||||
} else {
|
|
||||||
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
|
||||||
if (targets.some(t => !t.startsWith('chrome') && !/^es((202\d{1})|next)$/.test(t))) {
|
|
||||||
config.logger.warn(
|
|
||||||
'The electron vite renderer config build.target is not "chrome?" or "es?". This could be a mistake.'
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const rollupOptions = build.rollupOptions
|
export function electronPreloadConfigPresetPlugin(options?: ElectronPluginOptions): Plugin {
|
||||||
if (!rollupOptions.input) {
|
return {
|
||||||
config.logger.warn(colors.yellow(`index.html file is not found in ${colors.dim('/src/renderer')} directory.`))
|
name: 'vite:electron-preload-config-preset',
|
||||||
throw new Error('build.rollupOptions.input option is required in the electron vite renderer config.')
|
apply: 'build',
|
||||||
|
enforce: 'pre',
|
||||||
|
config(config): void {
|
||||||
|
const root = options?.root || process.cwd()
|
||||||
|
|
||||||
|
const nodeTarget = getElectronNodeTarget()
|
||||||
|
|
||||||
|
const pkg = loadPackageData() || { type: 'commonjs' }
|
||||||
|
|
||||||
|
const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs'
|
||||||
|
|
||||||
|
const defaultConfig = {
|
||||||
|
ssr: {
|
||||||
|
resolve: {
|
||||||
|
conditions: ['module', 'browser', 'development|production'],
|
||||||
|
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: path.resolve(root, 'out', 'preload'),
|
||||||
|
target: nodeTarget,
|
||||||
|
assetsDir: 'chunks',
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
|
||||||
|
output: {}
|
||||||
|
},
|
||||||
|
reportCompressedSize: false,
|
||||||
|
minify: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const build = config.build || {}
|
||||||
|
const rollupOptions = build.rollupOptions || {}
|
||||||
|
if (!rollupOptions.input) {
|
||||||
|
const libOptions = build.lib
|
||||||
|
const outputOptions = rollupOptions.output
|
||||||
|
defaultConfig.build['lib'] = {
|
||||||
|
entry: findLibEntry(root, 'preload'),
|
||||||
|
formats:
|
||||||
|
libOptions && libOptions.formats && libOptions.formats.length > 0
|
||||||
|
? []
|
||||||
|
: [outputOptions && !Array.isArray(outputOptions) && outputOptions.format ? outputOptions.format : format]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
defaultConfig.build.rollupOptions.output['format'] = format
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(
|
||||||
|
build.assetsDir || defaultConfig.build.assetsDir,
|
||||||
|
'[name]-[hash].[ext]'
|
||||||
|
)
|
||||||
|
|
||||||
|
const buildConfig = mergeConfig(defaultConfig.build, build)
|
||||||
|
config.build = buildConfig
|
||||||
|
|
||||||
|
const resolvedOutputs = resolveBuildOutputs(config.build.rollupOptions!.output, config.build.lib || false)
|
||||||
|
|
||||||
|
if (resolvedOutputs) {
|
||||||
|
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
||||||
|
|
||||||
|
if (outputs.find(({ format }) => format === 'es')) {
|
||||||
|
if (Array.isArray(config.build.rollupOptions!.output)) {
|
||||||
|
config.build.rollupOptions!.output.forEach(output => {
|
||||||
|
if (output.format === 'es') {
|
||||||
|
output['entryFileNames'] = '[name].mjs'
|
||||||
|
output['chunkFileNames'] = '[name]-[hash].mjs'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
config.build.rollupOptions!.output!['entryFileNames'] = '[name].mjs'
|
||||||
|
config.build.rollupOptions!.output!['chunkFileNames'] = '[name]-[hash].mjs'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.define = config.define || {}
|
||||||
|
config.define = { ...processEnvDefine(), ...config.define }
|
||||||
|
|
||||||
|
config.envPrefix = config.envPrefix || ['PRELOAD_VITE_', 'VITE_']
|
||||||
|
|
||||||
|
config.publicDir = config.publicDir || 'resources'
|
||||||
|
// do not copy public dir
|
||||||
|
config.build.copyPublicDir = false
|
||||||
|
// module preload polyfill does not apply to nodejs (preload scripts)
|
||||||
|
config.build.modulePreload = false
|
||||||
|
// enable ssr build
|
||||||
|
config.build.ssr = true
|
||||||
|
config.build.ssrEmitAssets = true
|
||||||
|
config.ssr = mergeConfig(defaultConfig.ssr, config.ssr || {})
|
||||||
|
config.ssr.noExternal = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function electronPreloadConfigValidatorPlugin(): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'vite:electron-preload-config-validator',
|
||||||
|
apply: 'build',
|
||||||
|
enforce: 'post',
|
||||||
|
configResolved(config): void {
|
||||||
|
const build = config.build
|
||||||
|
if (!build.target) {
|
||||||
|
throw new Error('build.target option is required in the electron vite preload config.')
|
||||||
|
} else {
|
||||||
|
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
||||||
|
if (targets.some(t => !t.startsWith('node'))) {
|
||||||
|
throw new Error('The electron vite preload config build.target must be "node?".')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const libOptions = build.lib
|
||||||
|
const rollupOptions = build.rollupOptions
|
||||||
|
|
||||||
|
if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
|
||||||
|
throw new Error(
|
||||||
|
'An entry point is required in the electron vite preload config, ' +
|
||||||
|
'which can be specified using "build.lib.entry" or "build.rollupOptions.input".'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolvedOutputs = resolveBuildOutputs(rollupOptions.output, libOptions)
|
||||||
|
|
||||||
|
if (resolvedOutputs) {
|
||||||
|
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
|
||||||
|
if (outputs.length > 1) {
|
||||||
|
throw new Error('The electron vite preload config does not support multiple outputs.')
|
||||||
|
} else {
|
||||||
|
const outpout = outputs[0]
|
||||||
|
if (['es', 'cjs'].includes(outpout.format || '')) {
|
||||||
|
if (outpout.format === 'es' && !supportESM()) {
|
||||||
|
throw new Error(
|
||||||
|
'The electron vite preload config output format does not support "es", ' +
|
||||||
|
'you can upgrade electron to the latest version or switch to "cjs" format.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`The electron vite preload config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function electronRendererConfigPresetPlugin(options?: ElectronPluginOptions): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'vite:electron-renderer-config-preset',
|
||||||
|
enforce: 'pre',
|
||||||
|
config(config): void {
|
||||||
|
const root = options?.root || process.cwd()
|
||||||
|
|
||||||
|
config.base =
|
||||||
|
config.mode === 'production' || process.env.NODE_ENV_ELECTRON_VITE === 'production' ? './' : config.base
|
||||||
|
config.root = config.root || './src/renderer'
|
||||||
|
|
||||||
|
const chromeTarget = getElectronChromeTarget()
|
||||||
|
|
||||||
|
const emptyOutDir = (): boolean => {
|
||||||
|
let outDir = config.build?.outDir
|
||||||
|
if (outDir) {
|
||||||
|
if (!path.isAbsolute(outDir)) {
|
||||||
|
outDir = path.resolve(root, outDir)
|
||||||
|
}
|
||||||
|
const resolvedRoot = normalizePath(path.resolve(root))
|
||||||
|
return normalizePath(outDir).startsWith(resolvedRoot + '/')
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultConfig = {
|
||||||
|
build: {
|
||||||
|
outDir: path.resolve(root, 'out', 'renderer'),
|
||||||
|
target: chromeTarget,
|
||||||
|
modulePreload: { polyfill: false },
|
||||||
|
rollupOptions: {
|
||||||
|
input: findInput(root)
|
||||||
|
},
|
||||||
|
reportCompressedSize: false,
|
||||||
|
minify: false,
|
||||||
|
emptyOutDir: emptyOutDir()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.build?.outDir) {
|
||||||
|
config.build.outDir = path.resolve(root, config.build.outDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildConfig = mergeConfig(defaultConfig.build, config.build || {})
|
||||||
|
config.build = buildConfig
|
||||||
|
|
||||||
|
config.envDir = config.envDir || path.resolve(root)
|
||||||
|
|
||||||
|
config.envPrefix = config.envPrefix || ['RENDERER_VITE_', 'VITE_']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function electronRendererConfigValidatorPlugin(): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'vite:electron-renderer-config-validator',
|
||||||
|
enforce: 'post',
|
||||||
|
configResolved(config): void {
|
||||||
|
if (config.base !== './' && config.base !== '/') {
|
||||||
|
config.logger.warn(colors.yellow('(!) Should not set "base" option for the electron vite renderer config.'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const build = config.build
|
||||||
|
if (!build.target) {
|
||||||
|
throw new Error('build.target option is required in the electron vite renderer config.')
|
||||||
|
} else {
|
||||||
|
const targets = Array.isArray(build.target) ? build.target : [build.target]
|
||||||
|
if (targets.some(t => !t.startsWith('chrome') && !/^es((202\d{1})|next)$/.test(t))) {
|
||||||
|
config.logger.warn(
|
||||||
|
'The electron vite renderer config build.target is not "chrome?" or "es?". This could be a mistake.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rollupOptions = build.rollupOptions
|
||||||
|
if (!rollupOptions.input) {
|
||||||
|
config.logger.warn(colors.yellow(`index.html file is not found in ${colors.dim('/src/renderer')} directory.`))
|
||||||
|
throw new Error('build.rollupOptions.input option is required in the electron vite renderer config.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user