☰
Electron Forge Vite + TypeScript 模板:从零快速搭建基于 Vite 构建的 TypeScript Electron 应用
2026/10/7 1:47:42 网站建设 项目流程
  • 开发工具
  • 桌面应用
  • 前端构建

【免费下载链接】forge

:electron: A complete tool for building and publishing Electron applications

项目地址:https://gitcode.com/gh_mirrors/fo/forge
点击查看免费下载

Electron Forge 官方提供了开箱即用的vite-typescript模板,它在@electron-forge/plugin-vite的基础上预置了合理的 TypeScript 配置,让你无需手工拼接 Vite、TypeScript 与 Electron 三者之间的构建链路,即可快速得到一个主进程、预加载脚本、渲染进程全部由 Vite 打包的工程。读完本文,你将掌握该模板的初始化命令、生成后的目录结构、forge.config.mts中 Vite 插件的完整配置语义,以及主进程加载渲染页面所需的关键全局变量用法,并了解模板背后的源码实现逻辑。

模板定位:Vite + TypeScript 一站式脚手架

vite-typescript模板是 Electron Forge 为「想用 Vite 作为打包工具、同时希望全程使用 TypeScript 开发」的开发者准备的官方模板。它的核心依赖是@electron-forge/plugin-vite插件——该插件负责把标准 Vite 工具链接入 Electron Forge,让主进程代码与渲染进程代码都由 Vite 完成编译与打包。

模板同时复用了 Forge 的基础模板(@electron-forge/template-base),因此初始化后的工程天然包含 Forge 的 maker(Squirrel、ZIP、RPM、DEB 等)与 fuses 安全加固配置,你可以在 Vite 模板 与 Vite 插件 文档之间对照使用(纯 JavaScript 变体使用--template=vite)。

快速开始:初始化与运行

使用create-electron-app即可一步创建项目,模板参数为vite-typescript:

npx create-electron-app@latest my-new-app --template=vite-typescript

初始化完成后,进入生成的目录并启动开发模式:

cd my-new-app npm start

npm start会调用electron-forge start,此时 Vite 插件会先并行构建各构建目标,再以--watch模式启动渲染进程的 Vite Dev Server,Electron 窗口随即打开并加载MAIN_WINDOW_VITE_DEV_SERVER_URL指向的开发服务器地址,从而实现渲染进程的热更新(HMR)。

模板生成后的目录结构

以模板的 tmpl 目录 为基准,初始化后的工程大致如下:

my-new-app/ ├── forge.config.mts # Forge 配置:Vite 插件、makers、fuses ├── vite.main.config.mts # 主进程构建配置 ├── vite.preload.config.mts # 预加载脚本构建配置 ├── vite.renderer.config.mts# 渲染进程构建配置 ├── tsconfig.json # TypeScript 编译器配置 ├── index.html # 渲染进程 HTML 入口 └── src/ ├── main.ts # Electron 主进程入口 ├── preload.ts # 预加载脚本 ├── renderer.ts # 渲染进程入口 └── declarations.d.ts # 全局类型声明(Vite 魔法常量、CSS 模块)

其中package.json的关键字段由模板自动生成,main指向 Vite 构建产物:

{ "main": ".vite/build/main.cjs", "scripts": { "lint": "oxlint && oxfmt --check", "lint:fix": "oxlint --fix && oxfmt --write", "typecheck": "tsc --noEmit" } }

模板在devDependencies中预置了vite、typescript与@electron-forge/plugin-vite,并额外提供 oxlint/oxfmt 作为默认 lint/format 工具。typecheck脚本对应tsc --noEmit,可在不产出文件的前提下做全量类型检查。

深入 forge.config.mts:Vite 插件的完整配置

模板生成的 forge.config.mts 是理解整套构建体系的钥匙。它通过new VitePlugin({...})声明两个配置段:

plugins: [ new VitePlugin({ build: [ { // `entry` 是 config 对应文件中 `build.lib.entry` 的别名 entry: 'src/main.ts', config: 'vite.main.config.mts', target: 'main', }, { entry: 'src/preload.ts', config: 'vite.preload.config.mts', target: 'preload', }, ], renderer: [ { name: 'main_window', config: 'vite.renderer.config.mts', }, ], }), ]

对照插件的类型定义 Config.ts,各字段语义如下:

  • build:声明需要以库模式(lib)打包的入口,典型场景是主进程、预加载脚本、Worker 进程等。每项包含:
    • entry:构建入口文件,是该项config中build.lib.entry的别名,二者取其一即可;
    • config:该入口对应的 Vite 配置文件路径;
    • target:构建目标,取值为'main'或'preload',默认'main',用于让插件按对应语义注入构建常量与外部化策略。
  • renderer:声明渲染进程的 Vite 配置。每项包含:
    • name:入口的可读名称(如main_window),它是后续魔法常量的命名前缀(见下文),同时决定生产构建产物的目录名;
    • config:渲染进程的 Vite 配置文件路径。
  • concurrent(可选):是否并发运行多个构建任务,接受布尔值或正整数;传入数字时可限制同时进行的构建数量,用于缓解打包时多个 Vite 构建并发导致的内存峰值。
  • hotRestart(可选):在electron-forge start期间,若主进程产物被重新构建,是否自动重启应用;仅在开发模式下生效,打包时无影响。

同一份配置也支持写进package.json的config.forge字段(.mjs/.cjs形式),配置项完全一致。模板之所以选用.mts,是因为要携带 TypeScript 类型标注;若使用--template=vite的 JS 变体,模板初始化逻辑会把forge.config.mts剥离类型并重命名为forge.config.mjs,同时把src/main.ts等入口改写为.js后缀。

fuses 安全加固

模板还在forge.config.mts中预置了FusesPlugin,在打包、代码签名之前对 Electron 二进制进行加固:关闭RunAsNode、禁用 Node CLI 调试参数环境变量、开启 Cookie 加密与嵌入式 asar 完整性校验、强制应用只从 asar 加载等。这些属于模板的默认安全基线,可按需调整。

三个 Vite 配置文件:各司其职

模板为每个构建目标各提供一个极简的 Vite 配置(仅defineConfig({})),因为插件的默认配置已覆盖大部分逻辑:

  • vite.main.config.mts:主进程构建配置。
  • vite.preload.config.mts:预加载脚本构建配置。
  • vite.renderer.config.mts:渲染进程构建配置。

从插件内置的主进程配置 vite.main.config.ts 可以看到默认行为:

const config: UserConfig = { build: { copyPublicDir: false, rollupOptions: { external: [...external, 'electron/main'], }, }, plugins: [ ...(forgeEnv.forgeConfig.hotRestart ? [pluginHotRestart('restart')] : []), ], define, resolve: { conditions: ['node'], mainFields: ['module', 'jsnext:main', 'jsnext'], }, };

关键点在于:

  1. 产物强制为 CommonJS:当build.lib未在用户配置中覆盖时,插件会设置fileName: () => '[name].cjs'与formats: ['cjs']。因此主进程与预加载脚本的产物扩展名是.cjs,即便package.json声明了"type": "module",Electron 也会按 CommonJS 解析——这正是package.json的main指向.vite/build/main.cjs、主进程中预加载路径写成path.join(__dirname, 'preload.cjs')的原因。
  2. 主进程构建默认外部化Node 侧依赖,并针对node条件解析依赖;渲染进程构建则走标准 Web 语义。

主进程如何加载渲染页面:魔法全局变量

开发模式与生产模式的加载路径不同,模板通过 Vite 插件注入的全局变量来切换。参考 main.ts:

if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL); } else { mainWindow.loadFile( path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`), ); }

变量命名规则为「渲染入口名称 + 固定后缀」:

  • 开发服务器地址:<NAME>_VITE_DEV_SERVER_URL;
  • 静态文件目录名:<NAME>_VITE_NAME。

因此对于name: 'main_window'的渲染入口,插件会注入MAIN_WINDOW_VITE_DEV_SERVER_URL与MAIN_WINDOW_VITE_NAME两个常量。开发时前者指向 Vite Dev Server(启用 HMR),生产时后者对应out/renderer/main_window/下的构建目录,配合loadFile加载。

在 TypeScript 工程中,这两个魔法常量已通过模板的 declarations.d.ts 声明:

/// <reference types="@electron-forge/plugin-vite/forge-vite-env" /> declare module '*.css';

该引用指向插件包内提供的 forge-vite-env.d.ts,其中声明了全局常量MAIN_WINDOW_VITE_DEV_SERVER_URL: string、MAIN_WINDOW_VITE_NAME: string,并扩展了 Vite 的ConfigEnv,使各配置文件中可以安全访问forgeConfig与forgeConfigSelf,从而获得类型安全的配置编写体验。若新建其他渲染入口,只需在该文件(或自己的.d.ts)中追加对应的declare const。

TypeScript 与 Vite 配置的默认约定

模板的 tsconfig.json 采用现代 ESM 友好的组合:module: "preserve"+moduleResolution: "bundler",配合target: "ESNext",让 Vite 可以直接消费 TypeScript 源码而无需额外转译;同时开启allowJs、esModuleInterop、resolveJsonModule、sourceMap等实用选项,include覆盖src/**/*与根目录的*.ts/*.mts。

三个 Vite 配置文件默认都是空配置(defineConfig({})),需要扩展时直接写入对应目标即可,例如在主进程配置中把原生 Node 模块声明为 external:

import { defineConfig } from 'vite'; export default defineConfig({ build: { rollupOptions: { external: ['serialport', 'sqlite3'], }, }, });

vite-typescript模板同样适用于该做法,且由于构建目标类型明确,Vite 不会把这类 Node 依赖错误地打进浏览器目标产物。更详细的 Vite 插件配置(如concurrent内存优化、HMR 使用、构建并发模型)可参见 Vite 插件文档。

模板背后的生成逻辑(源码视角)

模板初始化逻辑位于 ViteTemplate.ts,其initializeTemplate展示了vite-typescript与 JS 变体的差异是如何在代码层面实现的:

  • 删除基础模板的forge.config.js,写入forge.config.mts;若是 JS 变体,则剥离类型后重命名为forge.config.mjs,并通过字符串替换把src/main.ts→src/main.js、vite.main.config.mts→vite.main.config.mjs等路径一并改写;
  • TypeScript 变体直接复制vite.main.config.mts、vite.preload.config.mts、vite.renderer.config.mts与tsconfig.json;JS 变体则复制后剥离类型并重命名为.mjs;
  • 删除基础模板的 JS 源文件,按需复制main.ts/renderer.ts/preload.ts与declarations.d.ts;JS 变体复制 TS 源文件后去除类型注解再改名为.js;
  • 将src/index.html移至工程根目录,并把脚本标签改写为<script type="module" src="/src/renderer.ts"></script>(JS 变体为renderer.js);
  • 从package.json中移除仅 TypeScript 变体需要的typecheck脚本与@types/electron-squirrel-startup、typescript等开发依赖(见TS_ONLY_SCRIPTS与TS_ONLY_DEV_DEPS两个集合)。

由此可见,「vite-typescript 模板」与「vite 模板」共用同一份模板源文件,唯一的区别是create-electron-app传入的typescript选项为真时保留类型信息与 TS 专用依赖,这让两条命令生成的工程在结构上高度一致、便于在 JS/TS 之间迁移。

写在最后

vite-typescript模板的价值在于把三件事一次性做对:Vite 插件正确的三段式配置(主进程 / 预加载 / 渲染进程)、TypeScript 工程化默认值(tsconfig.json、typecheck、全局类型声明),以及开发 / 生产双模式下渲染页面加载的魔法变量方案。上手最快的方式就是执行初始化命令后直接修改forge.config.mts与三个 Vite 配置文件,再结合 Vite 插件 文档深入每一项高级选项。

  • 开发工具
  • 桌面应用
  • 前端构建

【免费下载链接】forge

:electron: A complete tool for building and publishing Electron applications

项目地址:https://gitcode.com/gh_mirrors/fo/forge
点击查看免费下载
上一篇:3步快速上手Neural-Chat-7b-v3:从安装到推理的完整教程
下一篇:金融日历系统详解:用Finance-Python处理中国市场节假日与交易日

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询