From 2e8ee357d580fca6892573d59df665fd4667e0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timeless=E5=B0=8F=E5=B8=85?= <1250076672@qq.com> Date: Thu, 21 May 2026 00:30:13 +0800 Subject: [PATCH] init vue --- README.md | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..04d2ab1 --- /dev/null +++ b/README.md @@ -0,0 +1,332 @@ +# Electron + Vue3 + TypeScript 项目 + +基于 [electron-vite](https://electron-vite.org/) 构建的现代化 Electron 应用模板。 + +## 技术栈 + +| 领域 | 技术 | +|------|------| +| 构建工具 | [electron-vite](https://electron-vite.org/) | +| 前端框架 | Vue 3 (Composition API) | +| 语言 | TypeScript | +| UI | 原生 HTML/CSS + Vue 组件 | + +## 项目结构 + +``` +├── electron.vite.config.ts # Vite 配置(electron-vite 专用) +├── tsconfig*.json # TypeScript 配置 +├── src/ +│ ├── main/ # 主进程(Node.js 环境) +│ │ └── index.ts +│ ├── preload/ # 预加载脚本(桥接层) +│ │ ├── index.ts +│ │ └── index.d.ts # 类型声明 +│ └── renderer/ # 渲染进程(浏览器环境) +│ ├── index.html +│ └── src/ +│ ├── main.ts # Vue 入口 +│ ├── App.vue +│ └── components/ +│ └── Counter.vue +├── out/ # 构建输出目录 +└── package.json +``` + +## 核心概念 + +### 1. 三进程架构 + +Electron 有三个独立的进程: + +``` +┌─────────────────────────────────────────────────┐ +│ Main Process │ +│ (Node.js) - 创建窗口、管理应用生命周期 │ +│ │ │ +│ ▼ │ +│ ┌───────────────────────────────────────────┐ │ +│ │ Preload Script │ │ +│ │ (上下文桥接,安全暴露 API 到渲染进程) │ │ +│ └───────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌───────────────────────────────────────────┐ │ +│ │ Renderer Process │ │ +│ │ (Chromium) - Vue 应用运行,DOM 操作 │ │ +│ └───────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────┘ +``` + +**主进程 (main)**:运行 Node.js,负责窗口管理、应用生命周期、系统 API 调用 + +**预加载脚本 (preload)**:运行在渲染进程中,但能访问 Node.js API,通过 `contextBridge` 安全暴露有限 API + +**渲染进程 (renderer)**:运行 Web 内容,Vue/React 应用在此执行,只能通过 IPC 与主进程通信 + +### 2. 上下文隔离 (Context Isolation) + +```javascript +// main.js - 窗口配置 +webPreferences: { + contextIsolation: true, // 启用上下文隔离 + nodeIntegration: false, // 禁用 Node.js 访问 + preload: 'preload.js' // 加载预加载脚本 +} +``` + +- `contextIsolation: true` 防止渲染进程直接访问 Node.js,防止 XSS 攻击 +- 渲染进程只能通过 `window.electron` 或 `window.api` 访问预暴露的 API + +### 3. IPC 通信模式 + +``` +Renderer Main + │ │ + │ ipcRenderer.invoke('xxx') │ + │ ─────────────────────────────►│ + │ │ ipcMain.handle('xxx', ...) + │ Promise │ + │ ◄─────────────────────────────│ + ▼ ▼ +``` + +```typescript +// preload - 暴露 IPC 通道 +contextBridge.exposeInMainWorld('api', { + getData: () => ipcRenderer.invoke('get-data') +}) + +// renderer - 调用 +const data = await window.api.getData() + +// main - 处理 +ipcMain.handle('get-data', () => { + return { message: 'Hello from main!' } +}) +``` + +### 4. electron-vite 构建流程 + +``` +┌─────────────────────────────────────────────────────────┐ +│ electron-vite dev │ +├─────────────────────────────────────────────────────────┤ +│ main │ Vite (SSR) → out/main/index.js │ +│ preload │ Vite (ESM) → out/preload/index.mjs │ +│ renderer│ Vite + Vue → http://localhost:5173 │ +└─────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────┐ +│ electron-vite build │ +├─────────────────────────────────────────────────────────┤ +│ main │ Vite (SSR) → out/main/index.js │ +│ preload │ Vite (ESM) → out/preload/index.mjs │ +│ renderer│ Vite + Vue → out/renderer/ │ +└─────────────────────────────────────────────────────────┘ +``` + +electron-vite 自动处理: +- 主进程和预加载脚本的 CommonJS/ESM 兼容 +- 渲染进程的热模块替换 (HMR) +- 路径别名、依赖打包等 + +### 5. Vue 组件生命周期 + +```typescript + +``` + +- `onMounted` - 组件挂载时启动定时器 +- `onUnmounted` - 组件卸载时清理定时器,防止内存泄漏 + +## 命令 + +```bash +# 开发模式(热重载) +npm run dev + +# 生产构建 +npm run build + +# 运行已构建的应用 +npm start + +# 打包为可执行文件 +npm run package +``` + +## 开发建议 + +1. **IPC 优先**:渲染进程不直接操作系统 API,通过 IPC 委托给主进程 +2. **类型安全**:preload 的 API 声明在 `.d.ts` 文件中,renderer 可获得智能提示 +3. **组件化**:UI 逻辑封装在 Vue 组件中,主进程只负责业务无关的系统操作 +4. **清理资源**:组件卸载时务必清理定时器、事件监听器等 + +## TypeScript 配置 + +项目有 3 个 TypeScript 配置文件: + +### tsconfig.json(根配置/入口) +```json +{ + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.web.json" } + ] +} +``` +**作用**:项目总入口,本身不编译代码,通过 `references` 引用其他两个配置。 + +### tsconfig.node.json(Node.js 环境) +**对应**:`src/main/` + `src/preload/` + `electron.vite.config.ts` + +```json +{ + "lib": ["ES2022"], + "include": ["src/main/**/*", "src/preload/**/*", "electron.vite/**/*"] +} +``` +**作用**:为主进程和预加载脚本提供类型检查,这两个运行在 Node.js 环境,需要 Node.js 内置类型(如 `process`、`path`、`fs`)。 + +### tsconfig.web.json(浏览器环境) +**对应**:`src/renderer/` + +```json +{ + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "jsx": "preserve", + "jsxImportSource": "vue", + "include": ["src/renderer/**/*"] +} +``` +**作用**:为渲染进程(Vue 应用)提供类型检查,需要 DOM 类型(如 `window`、`document`、`HTMLElement`)和 Vue JSX 支持。 + +### 为什么分开? +``` +┌─────────────────┐ +│ tsconfig.json │ ← 根配置,定义整体规则 +└────────┬────────┘ + │ + references + │ + ┌────┴────┐ + ▼ ▼ +┌───────┐ ┌───────┐ +│ node │ │ web │ ← 分别针对不同运行环境 +│ .json │ │ .json │ +└───┬───┘ └───┬───┘ + │ │ + Node.js 浏览器 + API 类型 DOM 类型 +``` + +不同运行环境有不同的全局 API,分开配置可以: +- 避免类型冲突(Node.js 的 `global` vs 浏览器的 `window`) +- 按需引入类型库,减小检查范围 +- IDE 根据当前文件路径自动选择对应配置 + +## 全部文件清单 + +| 文件 | 作用 | +|------|------| +| `package.json` | 项目配置:依赖、脚本、electron-builder 设置 | +| **`electron.vite.config.ts`** | **构建入口**:定义三个进程的入口路径、插件、别名 | +| `tsconfig.json` | TS 总入口,引用其他两个配置 | +| `tsconfig.node.json` | Node.js 环境配置(主进程、预加载) | +| `tsconfig.web.json` | 浏览器环境配置(渲染进程、Vue) | +| `src/main/index.ts` | Electron 主进程:创建窗口、管理应用生命周期、处理 IPC | +| `src/preload/index.ts` | 预加载脚本:通过 contextBridge 暴露安全 API | +| `src/preload/index.d.ts` | 预加载 API 的 TypeScript 类型声明 | +| `src/renderer/index.html` | 渲染进程 HTML 入口 | +| `src/renderer/src/main.ts` | Vue 应用入口 | +| `src/renderer/src/App.vue` | Vue 根组件 | +| `src/renderer/src/components/Counter.vue` | 计数器业务组件 | +| `out/` | 构建输出目录(`.gitignore` 忽略) | + +## electron.vite.config.ts 详解 + +这是 electron-vite 的核心配置文件,作用类似普通 Vite 项目的 `vite.config.ts`,但需要为三个进程分别配置: + +```typescript +import { defineConfig, externalizeDepsPlugin } from 'electron-vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ + // ── 主进程配置 ── + main: { + plugins: [externalizeDepsPlugin()], // 依赖外置,不打包进输出 + build: { + rollupOptions: { + input: { index: 'src/main/index.ts' } + } + } + }, + + // ── 预加载脚本配置 ── + preload: { + plugins: [externalizeDepsPlugin()], + build: { + rollupOptions: { + input: { index: 'src/preload/index.ts' } + } + } + }, + + // ── 渲染进程配置 ── + renderer: { + root: 'src/renderer', // HTML 所在目录 + plugins: [vue()], // Vue 插件 + resolve: { + alias: { '@': 'src/renderer/src' } // 路径别名 + }, + build: { + rollupOptions: { + input: 'src/renderer/index.html' // HTML 入口 + } + } + } +}) +``` + +### 关键点 + +| 配置项 | 作用 | +|--------|------| +| `externalizeDepsPlugin()` | 将 `node_modules` 中的依赖转为 `require()` 引用,减小包体积 | +| `root: 'src/renderer'` | 告诉 Vite 渲染进程的 HTML 在哪个目录 | +| `plugins: [vue()]` | 在渲染进程启用 Vue 插件,处理 `.vue` 文件 | +| `resolve.alias` | 设置 `@` 指向 `src/renderer/src`,简化导入路径 | +| `build.rollupOptions.input` | 指定每个进程的入口文件 | + +### 构建后输出 + +``` +electron-vite build + │ + ▼ +┌──────────────────────────────────────────┐ +│ out/main/index.js (主进程) │ +│ out/preload/index.mjs (预加载) │ +│ out/renderer/index.html (渲染进程) │ +│ out/renderer/assets/* (JS/CSS) │ +└──────────────────────────────────────────┘ +``` \ No newline at end of file