【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)
源代码仓库:
Github仓库【electron_git】Commit :
bb40040
Github Desktop 页面分析
本节目标:
1、实现类似Github Desktop的「空仓库」提示页
2、添加本地仓库逻辑编写

从 Github Desktop 我们看到 他的 主要页面分为三个区域
- Head头部区域 (操作分支)
- Side侧边栏区域 (查看更新的文件)
- Main主区域 (查看 文件 Diff内容)

Tip:其实初始化的时候只有一个类似main的界面,这里因为我已经添加过store了,所以有head和side部分。
一、目录搭建及依赖安装
- Ant Design 官网
- Redux 官网
- react-router 官网
- localforage官网
# 安装依赖
pnpm install antd --save
pnpm install @reduxjs/toolkit react-redux
pnpm add -D sass-embedded
pnpm install react-router-dom
# 简化持久化存储 根据 IndexedDB 和 WebSQL 支持进行降级策略
pnpm install localforage
主要文件

二、IPC 通信模块设计与实现
核心实现流程
1. IPC 模块注册机制
// ipc/index.js
import setupGitIPC from './git'
import setupChooseFileIPC from './operateTheFile'
/**
 * 聚合所有 IPC 通信模块
 * 新增 IPC 模块需在此处引入并调用
 */
export async function setupIPC() {
  setupGitIPC()
  setupChooseFileIPC()
}
// main/index.js
import { setupIPC } from '../ipc'
app.whenReady().then(() => {
  setupIPC() // 注册所有 IPC 通信
  createWindow()
  // ...其他初始化逻辑
})
2. 文件选择器实现
// operateTheFile/index.js
/**
 * 系统级文件夹选择对话框
 * @returns {Promise<string|null>} 选择的文件夹路径
 */
const chooseFolder = async () => {
  const result = await dialog.showOpenDialog(mainWindow, {
    properties: ['openDirectory']
  })
  if (result.filePaths.length > 0) {
    return result.filePaths[0]
  }
}
const setupChooseFileIPC = () => {
  ipcMain.handle('chooseFolder', () => {
    return chooseFolder()
  })
}
3.预处理层暴露 API
import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
// Custom APIs for renderer
const api = {
    /**
     * 打开文件夹选择对话框
     * @returns {Promise<string|null>}
     */
  chooseFolder: () => {
    return ipcRenderer.invoke('chooseFolder')
  }
}
4. 渲染进程调用示例
在app.jsx中我们点击button按钮时会调用window.api.chooseFolder唤起原生文件选择器操作文件
function App() {
  const gitStroe = useSelector((state) => state.gitStore)
  const dispatch = useDispatch()
  const outlet = useRoutes(router)
  // 定义一个异步函数 setRepoPath,用于选择文件夹并设置仓库路径
  const setRepoPath = async () => {
    // 调用 window.api.chooseFolder() 弹出文件夹选择对话框,并等待用户选择文件夹
    const repoPath = await window.api.chooseFolder()
    // 检查 gitStroe.repoPaths 中是否已经包含选择的文件夹路径
    if (!gitStroe.repoPaths.some((item) => item.path === repoPath)) {
      // 如果不包含,则将选择的文件夹路径添加到 gitStroe.repoPaths 中,并更新仓库名称
      dispatch(
        setRepoPaths([...gitStroe.repoPaths, { path: repoPath, name: repoPath.split('/').pop() }])
      )
      // 设置当前仓库为选择的文件夹名称
      dispatch(setCurrentRepo(repoPath.split('/').pop()))
    }
  }
  return (
    <div className="app-container">
             ...
             ...
             // 点击按钮触发 setRepoPath 函数
            <Button
              icon={<DatabaseOutlined />}
              size="large"
              style={{ marginLeft: 20 }}
              onClick={setRepoPath}
            >
              Add Local Repository
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}
export default App
