共计 3310 个字符,预计需要花费 9 分钟才能阅读完成。
背景痛点:为什么需要桌面客户端?
每次打开浏览器访问 ChatGPT 网页版时,总会遇到几个烦人的问题:

- 历史记录管理困难:每次重新打开浏览器都要从头开始对话,找不到昨天的重要聊天记录
- 多窗口混乱:和十几个其他标签页混在一起,经常误关闭或找不到 ChatGPT 标签
- 功能局限:无法使用系统快捷键、没有本地存储空间、无法离线查看历史对话
桌面客户端能完美解决这些问题。就像豆包那样,一个独立的窗口,常驻任务栏,还能保存所有对话记录。更重要的是——我们可以自己动手做一个!
技术选型:为什么选择 Electron?
构建跨平台桌面应用主要有几个选择:
- Electron:
- 成熟稳定,GitHub、VSCode 等知名应用都在用
- 基于 Chromium,前端开发体验流畅
-
丰富的 npm 生态,各种现成插件
-
Tauri:
- 更轻量,打包体积小
- Rust 编写,性能更好
-
但生态还不够完善,中文资料少
-
NW.js:
- 类似 Electron 但社区更小
- 配置方式较老旧
综合来看,Electron 是最佳选择——资料多、坑少、适合快速开发。虽然打包体积大些(约 120MB),但对现代电脑根本不是问题。
核心实现步骤
1. 搭建基础框架
先初始化项目:
# 创建项目目录
mkdir chatgpt-desktop && cd chatgpt-desktop
# 初始化 package.json
npm init -y
# 安装 Electron
npm install electron --save-dev
# 安装 Vue3
npm install vue@next @vitejs/plugin-vue
创建 Electron 的主进程文件main.js:
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})
// 加载 Vue 开发服务器或打包后的文件
if(process.env.NODE_ENV === 'development') {win.loadURL('http://localhost:3000')
} else {win.loadFile(path.join(__dirname, 'dist/index.html'))
}
}
app.whenReady().then(createWindow)
2. 集成 ChatGPT API
首先获取 OpenAI API Key,然后封装请求方法:
// src/utils/chatgpt.js
export async function sendMessage(message, history = []) {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${import.meta.env.VITE_OPENAI_KEY}`
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [...history, {role: 'user', content: message}]
})
})
if (!response.ok) {throw new Error(`API 请求失败: ${response.status}`)
}
const data = await response.json()
return data.choices[0].message.content
}
3. 实现本地存储
选择 IndexedDB 作为存储方案(比 localStorage 容量大,比 SQLite 简单):
// src/utils/db.js
const DB_NAME = 'chatgpt_db'
const STORE_NAME = 'conversations'
let db = null
export async function initDB() {return new Promise((resolve, reject) => {const request = indexedDB.open(DB_NAME, 1)
request.onerror = (event) => {console.error('数据库打开失败', event)
reject(event)
}
request.onsuccess = (event) => {
db = event.target.result
resolve(db)
}
request.onupgradeneeded = (event) => {
const db = event.target.result
if (!db.objectStoreNames.contains(STORE_NAME)) {db.createObjectStore(STORE_NAME, { keyPath: 'id'})
}
}
})
}
export function saveConversation(conversation) {return new Promise((resolve, reject) => {const transaction = db.transaction(STORE_NAME, 'readwrite')
const store = transaction.objectStore(STORE_NAME)
const request = store.put(conversation)
request.onsuccess = () => resolve()
request.onerror = (event) => reject(event)
})
}
性能优化技巧
- 内存泄漏预防:
- 在 Vue 组件卸载时取消所有未完成的 API 请求
-
使用 Electron 的
webContents.getZoomFactor()防止内存暴涨 -
响应速度优化:
- 预加载常用界面
- 对 API 响应实现客户端缓存
// 预加载示例
win.webContents.on('did-finish-load', () => {
win.webContents.executeJavaScript(`
localStorage.setItem('cachedData', '...')
`)
})
常见问题解决方案
- API 限流处理:
- 实现请求队列和自动重试
-
添加备用 API Key 轮换机制
-
安装包签名:
- 使用 electron-builder 配合 Windows 证书签名
-
或考虑购买便宜的代码签名证书
-
跨域问题:
- 在 electron-builder 配置中添加
extraFiles包含证书文件 - 或配置代理服务器
进阶功能建议
- Markdown 渲染:
- 集成 markdown-it 库
-
添加代码高亮支持
-
快捷指令:
- 监听全局快捷键
- 实现类似
/save这样的命令
// 全局快捷键示例
const {globalShortcut} = require('electron')
globalShortcut.register('CommandOrControl+Shift+C', () => {win.webContents.send('shortcut-copy')
})
打包发布
使用 electron-builder 打包:
-
安装依赖:
npm install electron-builder --save-dev -
配置 package.json:
"build": { "appId": "com.example.chatgptdesktop", "win": { "target": "nsis", "icon": "build/icon.ico" } } -
打包命令:
npm run build
现在你就拥有了一个和豆包体验类似的 ChatGPT 桌面客户端!整个过程大约需要 2 - 3 天开发时间,但绝对值得——毕竟再也不用在浏览器标签海里找 ChatGPT 了。
下次可以试试添加更多功能,比如语音输入、对话导出 PDF,或者集成其他 AI 服务。桌面客户端的可能性是无限的!
正文完
