refactor: share and normalize build output resolution

This commit is contained in:
alex8088 2026-10-11 00:59:44 +08:00
parent 0655933704
commit 19050aaec9
3 changed files with 49 additions and 61 deletions

View File

@ -1,10 +1,10 @@
import path from 'node:path'
import { randomBytes } from 'node:crypto'
import colors from 'picocolors'
import { type Plugin, type LibraryOptions, type Rolldown, normalizePath } from 'vite'
import { type Plugin, type Rolldown, normalizePath } from 'vite'
import * as babel from '@babel/core'
import MagicString from 'magic-string'
import { toRelativePath } from '../utils'
import { toRelativePath, resolveBuildOutputs } from '../utils'
import type { BytecodeCompiler, BytecodeTarget } from '../bytecodeCompiler'
// Inspired by https://github.com/bytenode/bytenode
@ -140,10 +140,9 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
return
}
const build = config.build
const resolvedOutputs = resolveBuildOutputs(build.rolldownOptions.output, build.lib)
if (resolvedOutputs) {
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
const outputs = resolveBuildOutputs(build.rolldownOptions.output, build.lib)
const output = outputs[0]
if (output) {
if (output.format === 'es') {
config.logger.warn(
colors.yellow(
@ -280,17 +279,6 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
}
}
function resolveBuildOutputs(
outputs: Rolldown.OutputOptions | Rolldown.OutputOptions[] | undefined,
libOptions: LibraryOptions | false
): Rolldown.OutputOptions | Rolldown.OutputOptions[] | undefined {
if (libOptions && !Array.isArray(outputs)) {
const libFormats = libOptions.formats || []
return libFormats.map(format => ({ ...outputs, format }))
}
return outputs
}
interface ProtectStringsPluginState extends babel.PluginPass {
opts: { protectedStrings: Set<string> }
}

View File

@ -2,9 +2,9 @@ import path from 'node:path'
import fs from 'node:fs'
import { builtinModules } from 'node:module'
import colors from 'picocolors'
import { type Plugin, type LibraryOptions, type Rolldown, type UserConfig, mergeConfig, normalizePath } from 'vite'
import { type Plugin, type UserConfig, mergeConfig, normalizePath } from 'vite'
import { getElectronNodeTarget, getElectronChromeTarget, supportESM } from '../electron'
import { loadPackageData } from '../utils'
import { loadPackageData, resolveBuildOutputs } from '../utils'
export interface ElectronPluginOptions {
root?: string
@ -38,17 +38,6 @@ function processEnvDefine(): Record<string, string> {
}
}
function resolveBuildOutputs(
outputs: Rolldown.OutputOptions | Rolldown.OutputOptions[] | undefined,
libOptions: LibraryOptions | false
): Rolldown.OutputOptions | Rolldown.OutputOptions[] | undefined {
if (libOptions && !Array.isArray(outputs)) {
const libFormats = libOptions.formats || []
return libFormats.map(format => ({ ...outputs, format }))
}
return outputs
}
export function electronMainConfigPresetPlugin(options?: ElectronPluginOptions): Plugin {
return {
name: 'vite:electron-main-config-preset',
@ -148,16 +137,15 @@ export function electronMainConfigValidatorPlugin(): Plugin {
)
}
const resolvedOutputs = resolveBuildOutputs(rolldownOptions.output, libOptions)
const outputs = resolveBuildOutputs(rolldownOptions.output, libOptions)
if (resolvedOutputs) {
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
if (outputs.length > 0) {
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()) {
const output = outputs[0]
if (['es', 'cjs'].includes(output.format || '')) {
if (output.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.'
@ -232,12 +220,9 @@ export function electronPreloadConfigPresetPlugin(options?: ElectronPluginOption
const buildConfig = mergeConfig(defaultConfig.build, build)
config.build = buildConfig
const resolvedOutputs = resolveBuildOutputs(config.build.rolldownOptions!.output, config.build.lib || false)
const outputs = resolveBuildOutputs(config.build.rolldownOptions!.output, config.build.lib)
if (resolvedOutputs) {
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
if (outputs.find(({ format }) => format === 'es')) {
if (outputs.some(({ format }) => format === 'es')) {
if (Array.isArray(config.build.rolldownOptions!.output)) {
config.build.rolldownOptions!.output.forEach(output => {
if (output.format === 'es') {
@ -252,7 +237,6 @@ export function electronPreloadConfigPresetPlugin(options?: ElectronPluginOption
: path.posix.join(build.assetsDir || defaultConfig.build.assetsDir, '[name]-[hash].mjs')
}
}
}
config.define = config.define || {}
config.define = { ...processEnvDefine(), ...config.define }
@ -302,16 +286,15 @@ export function electronPreloadConfigValidatorPlugin(): Plugin {
)
}
const resolvedOutputs = resolveBuildOutputs(rolldownOptions.output, libOptions)
const outputs = resolveBuildOutputs(rolldownOptions.output, libOptions)
if (resolvedOutputs) {
const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs]
if (outputs.length > 0) {
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()) {
const output = outputs[0]
if (['es', 'cjs'].includes(output.format || '')) {
if (output.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.'

View File

@ -3,7 +3,7 @@ import path from 'node:path'
import fs from 'node:fs'
import { createHash } from 'node:crypto'
import { createRequire } from 'node:module'
import { loadEnv as viteLoadEnv } from 'vite'
import { type LibraryOptions, type Rolldown, loadEnv as viteLoadEnv } from 'vite'
export function isObject(value: unknown): value is Record<string, unknown> {
return Object.prototype.toString.call(value) === '[object Object]'
@ -32,6 +32,23 @@ export function toRelativePath(filename: string, importer: string): string {
return relPath.startsWith('.') ? relPath : `./${relPath}`
}
/**
* Resolve configured build outputs into an array.
*/
export function resolveBuildOutputs(
outputs: Rolldown.OutputOptions | Rolldown.OutputOptions[] | undefined,
libOptions: LibraryOptions | false | undefined
): Rolldown.OutputOptions[] {
if (Array.isArray(outputs)) {
return outputs
}
if (libOptions) {
const libFormats = libOptions.formats || []
return libFormats.map(format => ({ ...outputs, format }))
}
return outputs ? [outputs] : []
}
/**
* Load `.env` files within the `envDir` (default: `process.cwd()`) .
* By default, only env variables prefixed with `VITE_`, `MAIN_VITE_`, `PRELOAD_VITE_` and