【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)

源代码仓库:
Github仓库【electron_git】

Commit :
bb40040

Github Desktop 页面分析

本节目标:
1、实现类似Github Desktop的「空仓库」提示页
2、添加本地仓库逻辑编写

从 Github Desktop 我们看到 他的 主要页面分为三个区域

  • Head头部区域 (操作分支)
  • Side侧边栏区域 (查看更新的文件)
  • Main主区域 (查看 文件 Diff内容)

【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)_第1张图片

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

主要文件

【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)_第2张图片

二、IPC 通信模块设计与实现

渲染进程 预处理脚本 主进程 操作系统 调用 window.api.chooseFolder() ipcRenderer.invoke('chooseFolder') 显示文件选择对话框 返回选择的路径 返回路径结果 返回 Promise 结果 更新 Redux 状态 渲染进程 预处理脚本 主进程 操作系统

核心实现流程

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} 选择的文件夹路径
 */
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}
     */
  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

你可能感兴趣的:(_Electron,electron,git,javascript)