import type { ForgeConfig } from '@electron-forge/shared-types'; import { MakerSquirrel } from '@electron-forge/maker-squirrel'; import { MakerZIP } from '@electron-forge/maker-zip'; import { MakerDeb } from '@electron-forge/maker-deb'; import { MakerRpm } from '@electron-forge/maker-rpm'; import { MakerDMG } from '@electron-forge/maker-dmg'; import { VitePlugin } from '@electron-forge/plugin-vite'; import { FusesPlugin } from '@electron-forge/plugin-fuses'; import { FuseV1Options, FuseVersion } from '@electron/fuses'; import * as fs from 'fs-extra'; import * as path from 'path'; const config: ForgeConfig = { packagerConfig: { asar: true, tmpdir: path.resolve(process.cwd(), '..', 'electron-packager-tmp'), name: 'NianXX', icon: path.join(__dirname, 'public/logo'), appCopyright: 'Copyright © 2026 智念科技', }, rebuildConfig: {}, makers: [ new MakerSquirrel({ iconUrl: path.join(__dirname, 'public/logo.ico'), setupIcon: path.join(__dirname, 'public/logo.ico'), setupExe: 'NianXX.exe', }), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({}), new MakerDMG( (arch: string) => ({ name: `NianXX-${arch}`, icon: path.join(__dirname, 'public/logo.icns'), appPath: '', } as any) ), ], plugins: [ new VitePlugin({ build: [ { entry: 'src/main/main.ts', config: 'vite.main.config.ts', target: 'main', }, { entry: 'src/preload.ts', config: 'vite.preload.config.ts', target: 'preload', }, ], renderer: [ { name: 'main_window', config: 'vite.renderer.config.ts', }, ], }), new FusesPlugin({ version: FuseVersion.V1, [FuseV1Options.RunAsNode]: false, [FuseV1Options.EnableCookieEncryption]: true, [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false, [FuseV1Options.EnableNodeCliInspectArguments]: false, [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true, [FuseV1Options.OnlyLoadAppFromAsar]: true, }), ], hooks: { async packageAfterCopy(forgeConfig, buildPath, electronVersion, platform, arch) { const src = path.join(__dirname, 'src/main/scripts'); const dest = path.join(buildPath, '.vite', 'build', 'scripts'); await fs.ensureDir(dest); // 动态导入esbuild const esbuildModule = await import('esbuild'); const esbuildBuild = esbuildModule.build; const files = await fs.readdir(src); for (const file of files) { if (file.endsWith('.js')) { await esbuildBuild({ entryPoints: [path.join(src, file)], outfile: path.join(dest, file), bundle: true, platform: 'node', target: 'node24', external: [ 'electron' ], format: 'cjs', }); } else { await fs.copy(path.join(src, file), path.join(dest, file)); } } const playwrightSrc = path.join(__dirname, 'node_modules', 'playwright'); const playwrightDest = path.join(buildPath, 'node_modules', 'playwright'); if (await fs.pathExists(playwrightSrc)) { await fs.ensureDir(path.join(buildPath, 'node_modules')); await fs.copy(playwrightSrc, playwrightDest); } const playwrightCoreSrc = path.join(__dirname, 'node_modules', 'playwright-core'); const playwrightCoreDest = path.join(buildPath, 'node_modules', 'playwright-core'); if (await fs.pathExists(playwrightCoreSrc)) { await fs.ensureDir(path.join(buildPath, 'node_modules')); await fs.copy(playwrightCoreSrc, playwrightCoreDest); } const chromiumBidiSrc = path.join(__dirname, 'node_modules', 'chromium-bidi'); const chromiumBidiDest = path.join(buildPath, 'node_modules', 'chromium-bidi'); if (await fs.pathExists(chromiumBidiSrc)) { await fs.ensureDir(path.join(buildPath, 'node_modules')); await fs.copy(chromiumBidiSrc, chromiumBidiDest); } const bytenodeSrc = path.join(__dirname, 'node_modules', 'bytenode'); const bytenodeDest = path.join(buildPath, 'node_modules', 'bytenode'); if (await fs.pathExists(bytenodeSrc)) { await fs.ensureDir(path.join(buildPath, 'node_modules')); await fs.copy(bytenodeSrc, bytenodeDest); } }, async prePackage() { const outDir = path.resolve(process.cwd(), 'out'); fs.rmSync(outDir, { recursive: true, force: true }); }, async preMake() { const makeDir = path.resolve(process.cwd(), 'out', 'make'); fs.rmSync(makeDir, { recursive: true, force: true }); }, async postPackage(_forgeConfig, options) { // eslint-disable-next-line @typescript-eslint/no-var-requires const electronVersion = require('electron/package.json').version; const nodeVersion = process.version; const versionData = { node: nodeVersion, electron: electronVersion, platform: process.platform, arch: process.arch, buildTime: new Date().toISOString(), }; const outDir = path.resolve(process.cwd(), 'out'); fs.ensureDirSync(outDir); const outputs = (options && (options as any).outputPaths) || []; if (Array.isArray(outputs) && outputs.length > 0) { for (const p of outputs) { try { const versionFile = path.join(p, 'version'); fs.writeFileSync(versionFile, JSON.stringify(versionData, null, 2)); } catch {} } } }, async postMake(_forgeConfig, outputs) { // eslint-disable-next-line @typescript-eslint/no-var-requires const electronVersion = require('electron/package.json').version; const nodeVersion = process.version; const versionData = { node: nodeVersion, electron: electronVersion, platform: process.platform, arch: process.arch, buildTime: new Date().toISOString(), }; const outDir = path.resolve(process.cwd(), 'out'); fs.ensureDirSync(outDir); if (Array.isArray(outputs) && outputs.length > 0) { for (const p of outputs) { try { const versionFile = path.join(p as any, 'version'); fs.writeFileSync(versionFile, JSON.stringify(versionData, null, 2)); } catch {} } } }, }, }; export default config;