☰
HiKid架构拆解:electron-vite三进程模型构建跨平台桌面应用完整实践
2026/10/14 15:18:07 网站建设 项目流程

【免费下载链接】hi-kid

HiKid - Your AI English Pal. A desktop app built with React and TypeScript, targeting children in non-English-speaking countries who want to practice English speaking and listening.

项目地址:https://gitcode.com/gh_mirrors/hi/hi-kid
点击查看免费下载

HiKid 是一款免费开源的AI 英语陪练桌面应用,专为非英语国家儿童设计,支持语音对话、故事讲述与单词游戏,且完全离线运行。本文将完整拆解 HiKid 如何基于electron-vite 三进程模型(Main 主进程、Preload 预加载、Renderer 渲染进程)构建跨平台桌面应用,覆盖目录结构、IPC 通信、路径别名与 electron-builder 打包全流程。

HiKid 是什么?先看效果

HiKid 的界面是一只可爱的小猫(Kitten):按住麦克风说话,AI 会理解你的英语并用语音回答。所有录音、语音识别(ASR)、大模型对话与语音合成(TTS)都在本地完成,数据不出机器。

技术上,HiKid 的核心选型非常主流:

层面选型说明
桌面框架Electron 39提供窗口、文件系统、子进程等系统能力
构建工具electron-vite 5 + Vite 7一条命令同时构建三个进程
前端React 19 + TypeScript 5.9渲染进程是一个标准 React SPA
打包electron-builder 26一键产出 win / mac / linux 安装包
测试Vitest 4主进程服务层单元测试

目录结构:三进程一目了然

electron-vite 项目最直观的特点就是src/下按进程划分的目录,HiKid 完全遵循这一约定:

hi-kid/ ├── electron.vite.config.ts # electron-vite 构建配置(三个构建目标) ├── electron-builder.yml # 跨平台打包配置 ├── package.json # 启动/构建/打包脚本 ├── src/ │ ├── main/ # ① 主进程(Node.js 环境) │ │ ├── index.ts # 应用入口:窗口创建、生命周期 │ │ ├── ipc/channels.ts # IPC 通道注册(业务逻辑中枢) │ │ ├── services/ # 服务层:agent、recorder、servers… │ │ └── __tests__/ # Vitest 单元测试 │ ├── preload/ # ② 预加载脚本(安全桥) │ │ ├── index.ts # contextBridge 暴露 window.api │ │ └── index.d.ts # 渲染进程可用的全局类型声明 │ ├── renderer/ # ③ 渲染进程(React SPA) │ │ ├── index.html │ │ └── src/ # App.tsx、组件、hooks │ └── shared/ # ④ 三进程共享代码(i18n 等)

这套结构的直接好处:每个文件属于哪个进程、能用哪些 API,一眼就能判断。比如services/recorder.ts用了 Node 的fs和子进程,它只能在主进程;而Kitten.tsx只用 React,属于渲染进程。

主进程(Main):应用的生命线

主进程入口是 src/main/index.ts,职责清晰:

  1. 创建 BrowserWindow:900×860 的无边框菜单栏窗口,并通过webPreferences.preload挂上预加载脚本;
  2. 区分开发/生产加载:开发环境加载ELECTRON_RENDERER_URL(支持 HMR 热更新),生产环境加载打包后的本地index.html;
  3. 管理生命周期:app.whenReady()时注册 IPC、创建窗口;before-quit/window-all-closed时调用cleanup()停止本地 TTS/ASR 服务与语音播放,避免残留子进程;
  4. 跨平台细节:macOS 自定义应用菜单显示 "HiKid"、Windows 设置 AppUserModelId、Linux 单独设置窗口图标。

业务逻辑则集中在 src/main/ipc/channels.ts,它通过ipcMain.handle注册了全部请求通道(服务启停、录音、模型下载、配置读写等),并借助webContents.send主动向渲染进程推送事件。底层的实际能力由 src/main/services/ 下的模块化服务承担:

  • agent.ts— 大模型对话 Agent(含打断、流式输出)
  • recorder.ts— 带 VAD(静音检测)的录音
  • servers.ts— 本地 TTS / ASR 服务进程管理
  • download.ts/releases.ts— 模型下载与安装清单
  • config.ts— 用户配置持久化(~/.config/hi-kid)
  • logger.ts、window.ts— 日志与主窗口引用

这种"入口薄、通道集中、服务独立"的分层,是三进程项目保持可维护性的关键实践。

Preload 进程:安全的关键桥梁

渲染进程运行在沙箱浏览器环境里,无法直接访问 Node.js。electron-vite 的三进程模型中,Preload 正是补上这一环的角色——它通过contextBridge.exposeInMainWorld把白名单式的 API 挂到window上。

看 src/preload/index.ts 的收尾代码:

if (process.contextIsolated) { contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) }

这里暴露了两个对象:

  • window.electron— 来自@electron-toolkit/preload,提供窗口控制(最小化、关闭等);
  • window.api— HiKid 自定义 API,全部基于ipcRenderer.invoke的 Promise 调用,例如sendMessage(text)、startRecording()、setConfig(config)。

更值得一提的是类型安全:src/preload/index.d.ts 用全局declare global声明了window.api的完整接口,渲染进程里写window.api.startRecording()时能获得完整的智能提示和参数校验——新增一个 IPC 功能只需四处改动(preload 定义 → d.ts 类型 → main 处理 → renderer 调用),流程在 CLAUDE.md 中有明确约定。

渲染进程(Renderer):一个标准 React SPA

渲染进程与做 Web 前端没有任何区别:src/renderer/src/main.tsx 挂载根组件,src/renderer/src/App.tsx 负责屏幕状态机(loading → 依赖检查 → 模型下载 → 引导页 → 对话页),并通过两个 hooks 与主进程解耦:

  • useConversation— 订阅kitten:state、transcription、llm:delta等事件,驱动小猫状态机(idle / listening / thinking / speaking)与聊天气泡;
  • useConfig— 读取与保存 AI 名称、System Prompt、模型接入地址等配置。

组件按功能拆分在 src/renderer/src/components/(Kitten、VoiceButton、ChatBubbles、SettingsPanel 等),共享的 i18n 资源放在src/shared/,实现同一份文案在中英文界面复用。

IPC 通信设计:invoke 请求 + 事件推送

HiKid 的 IPC 分为两类,这也是桌面应用通信的通用范式:

方向机制典型通道
渲染 → 主(请求/响应)ipcRenderer.invoke+ipcMain.handleservices:start、recorder:start、config:set、models:download
主 → 渲染(事件推送)webContents.send+ipcRenderer.onkitten:state、transcription、llm:delta、tts:event、download:progress、error

请求/响应通道天然适合"有返回值"的操作(如读取配置);而语音对话天然是流式的——识别出文字推transcription、模型逐字输出推llm:delta、开始/停止发音推tts:event。渲染进程只需订阅事件,UI 就会自动"活"起来。

订阅类 API 在 preload 中还统一返回一个取消函数(onKittenState(cb)返回() => unsubscribe),配合 React 的useEffect清理函数,能优雅避免事件监听泄漏——这是一个很值得抄作业的细节。

路径别名与构建:electron.vite.config.ts 只需十几行

三进程项目的构建配置出奇地简单,因为 electron-vite 默认就按src/main、src/preload、src/renderer三个约定目录分别构建。HiKid 的配置 electron.vite.config.ts 只额外做了两件事:

  • 为 renderer 注入@renderer→src/renderer/src、@shared→src/shared的路径别名;
  • 启用@vitejs/plugin-react支持 JSX 与 HMR。

三个 TypeScript 工程(tsconfig.json、tsconfig.node.json、tsconfig.web.json)分别覆盖 main+preload、web 与渲染层,npm run typecheck可分别校验。构建产物统一输出到out/目录(main / preload / renderer 三份 bundle),package.json的main字段直接指向./out/main/index.js。

开发体验方面,package.json 提供了完整的脚本链:

npm run dev # electron-vite dev:三进程并行构建 + 热更新 npm start # 生产模式预览 npm run build:win # 打包 Windows 安装包 npm run build:mac # 打包 macOS 应用 npm run build:linux# 打包 Linux 版本

跨平台打包与工程化

打包交给 electron-builder:electron-builder.yml 描述通用配置,另有 electron-builder.bundled.yml 用于内嵌依赖的 macOS 精简发行包(配合 scripts/prepare-bundled.js 预处理)。

工程化配套同样齐整:

  • 单元测试:src/main/tests/ 下对 agent、config、i18n、logger、recorder、window 等服务逐一覆盖,npm test即跑 Vitest;
  • 规范检查:ESLint 9 flat config + Prettier,npm run lint/npm run format;
  • 需求与计划文档:docs/plans/ 与 docs/brainstorms/ 保留了语音对话集成、可配置 AI 等特性的需求与实施记录,是很好的功能演进参考;
  • 安装文档:INSTALL.md / INSTALL-cn.md 分中英文说明依赖准备。

动手跑起来

本地环境要求 Node.js ≥ 20:

git clone https://gitcode.com/gh_mirrors/hi/hi-kid cd hi-kid npm install npm run dev # 开发模式,带热更新

总结:三进程模型的实践要点

通过 HiKid 这个项目,可以提炼出 electron-vite 三进程架构的 5 个可复用实践:

  1. 目录即进程:src/main/src/preload/src/renderer物理隔离,杜绝跨进程误用 API;
  2. 白名单暴露:preload 只暴露最小 API 面,并用.d.ts让调用方享受完整类型提示;
  3. 双向通信分层:请求用invoke,流式状态用send+ 订阅,订阅 API 返回取消函数;
  4. 入口薄、服务厚:主进程入口只管窗口与生命周期,业务下沉到services/便于单测;
  5. 一条命令跨平台:electron-vite 管构建,electron-builder 管打包,build:win/mac/linux各一行。

这套模式简单、可预期,是构建跨平台 Electron 桌面应用的可靠起点。

【免费下载链接】hi-kid

HiKid - Your AI English Pal. A desktop app built with React and TypeScript, targeting children in non-English-speaking countries who want to practice English speaking and listening.

项目地址:https://gitcode.com/gh_mirrors/hi/hi-kid
点击查看免费下载

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

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

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

立即咨询