refactor: 迁移至 electron-vite 官方推荐目录结构

- electron/* -> src/main/* (主进程)
- electron/preload.ts -> src/preload/index.ts (预加载)
- src/electron-api.d.ts -> src/preload/index.d.ts (类型声明)
- src/* -> src/renderer/src/* (渲染进程)
- src/index.html -> src/renderer/index.html
- electron.vite.config.ts 简化为自动入口检测 (零配置)
- tsconfig.app.json -> tsconfig.web.json, 更新 includes/paths
- 构建产物 dist-electron/ -> out/ (修复 main/preload 输出覆盖 bug)
- 更新 package.json main 字段 + electron-builder files
- 更新 .gitignore + eslint ignores
- 更新 AGENTS.md 架构文档
This commit is contained in:
2026-07-10 23:46:34 +08:00
parent 157af4399f
commit eda30250c6
71 changed files with 112 additions and 127 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
node_modules/ node_modules/
dist-electron/ out/
release/ release/
dist/ dist/
*.log *.log
@@ -15,7 +15,7 @@ yarn-error.log*
*.njsproj *.njsproj
*.sln *.sln
# Legacy codebase archived Vue 2 version, not part of v2 build # Legacy codebase - archived Vue 2 version, not part of v2 build
legacy/ legacy/
# Brainstorming artifacts # Brainstorming artifacts
+21 -16
View File
@@ -6,10 +6,10 @@ Fork of [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesk
## Stack ## Stack
- **Shell:** Electron 43 (`electron/main.ts`) - **Shell:** Electron 43 (`src/main/index.ts`)
- **Preload:** `electron/preload.ts` (contextBridge, typed API) - **Preload:** `src/preload/index.ts` (contextBridge, typed API)
- **Renderer:** Vue 3 + Pinia + Element Plus + Vue Router (`src/`) - **Renderer:** Vue 3 + Pinia + Element Plus + Vue Router (`src/renderer/src/`)
- **IPC types:** `src/electron-api.d.ts` (ElectronAPI interface, global Window augmentation) - **IPC types:** `src/preload/index.d.ts` (ElectronAPI interface, global Window augmentation)
- **Build:** electron-vite + Vite 6 + TypeScript 5 - **Build:** electron-vite + Vite 6 + TypeScript 5
- **Redis client:** ioredis 5 (main process only) - **Redis client:** ioredis 5 (main process only)
- **Persistence:** electron-store + safeStorage (credentials) - **Persistence:** electron-store + safeStorage (credentials)
@@ -18,7 +18,7 @@ Fork of [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesk
```bash ```bash
npm run dev # electron-vite dev (HMR, renderer on :5173) npm run dev # electron-vite dev (HMR, renderer on :5173)
npm run build # production build -> dist-electron/ npm run build # production build -> out/
npm start # preview built app npm start # preview built app
npm run build:unpack # build + electron-builder --dir npm run build:unpack # build + electron-builder --dir
npm run build:win # build + electron-builder --win npm run build:win # build + electron-builder --win
@@ -30,9 +30,8 @@ npm run lint # eslint --fix
## Architecture ## Architecture
``` ```
Electron main (electron/) Electron main (src/main/)
├── main.ts # Window creation, app lifecycle ├── index.ts # Window creation, app lifecycle
├── preload.ts # contextBridge.exposeInMainWorld
├── ipc-handlers.ts # all IPC channel handlers ├── ipc-handlers.ts # all IPC channel handlers
├── store.ts # electron-store (connections, settings) ├── store.ts # electron-store (connections, settings)
├── credential.ts # safeStorage encrypt/decrypt ├── credential.ts # safeStorage encrypt/decrypt
@@ -53,11 +52,16 @@ Electron main (electron/)
├── commandLogger.ts # command execution log ├── commandLogger.ts # command execution log
└── format.ts # value decode/format detection └── format.ts # value decode/format detection
Renderer (src/) Preload (src/preload/)
├── index.ts # contextBridge.exposeInMainWorld
└── index.d.ts # ElectronAPI type declarations
Renderer (src/renderer/)
├── index.html # Vite entry HTML
└── src/
├── main.ts # Vue 3 bootstrap (Pinia, Element Plus) ├── main.ts # Vue 3 bootstrap (Pinia, Element Plus)
├── App.vue # Shell layout (TitleBar + Sidebar + MainArea + StatusBar) ├── App.vue # Shell layout (TitleBar + Sidebar + MainArea + StatusBar)
├── env.d.ts # Vite client + *.vue / *.css module declarations ├── env.d.ts # Vite client + *.vue / *.css module declarations
├── electron-api.d.ts # ElectronAPI interface + global Window augmentation
├── stores/ ├── stores/
│ ├── app.ts # theme, fontSize, scanCount │ ├── app.ts # theme, fontSize, scanCount
│ ├── connection.ts # connections CRUD, connect/disconnect, health check │ ├── connection.ts # connections CRUD, connect/disconnect, health check
@@ -203,19 +207,20 @@ Renderer (src/)
## Build config ## Build config
- `electron.vite.config.ts` defines three build targets: main, preload, renderer - `electron.vite.config.ts` defines three build targets: main, preload, renderer
- Main + preload output to `dist-electron/`; renderer to `dist-electron/renderer/` - Entry points auto-detected: `src/main/index.ts`, `src/preload/index.ts`, `src/renderer/index.html`
- Build output: `out/main/`, `out/preload/`, `out/renderer/`
- electron-builder packages into `release/` - electron-builder packages into `release/`
- Renderer dev server runs on port 5173 - Renderer dev server runs on port 5173
- Main/preload use `externalizeDepsPlugin()` to keep node_modules external - Main/preload use `externalizeDepsPlugin()` to keep node_modules external
- `@renderer` alias resolves to `src` - `@renderer` alias resolves to `src/renderer/src`
## TypeScript ## TypeScript
- Root `tsconfig.json` references `tsconfig.node.json` (main + preload) and `tsconfig.app.json` (renderer) - Root `tsconfig.json` references `tsconfig.node.json` (main + preload) and `tsconfig.web.json` (renderer)
- Node target (`tsconfig.node.json`) includes `electron/**/*` + `electron.vite.config.ts` - Node target (`tsconfig.node.json`) includes `src/main/**/*`, `src/preload/**/*.ts`, `electron.vite.config.ts`
- App target (`tsconfig.app.json`) includes `src/**/*` - Web target (`tsconfig.web.json`) includes `src/renderer/src/**/*`, `src/preload/**/*.d.ts`
- Both use `verbatimModuleSyntax` (type-only imports required) and `moduleResolution: "bundler"` - Both use `verbatimModuleSyntax` (type-only imports required) and `moduleResolution: "bundler"`
- `src/electron-api.d.ts` declares the `ElectronAPI` interface and augments global `Window` - `src/preload/index.d.ts` declares the `ElectronAPI` interface and augments global `Window`
## Security ## Security
+5 -30
View File
@@ -5,44 +5,19 @@ import { resolve } from 'path'
export default defineConfig({ export default defineConfig({
main: { main: {
plugins: [externalizeDepsPlugin()], plugins: [externalizeDepsPlugin()],
build: {
outDir: 'dist-electron',
rollupOptions: {
input: {
index: resolve(__dirname, 'electron/main.ts')
}
}
}
}, },
preload: { preload: {
plugins: [externalizeDepsPlugin()], plugins: [externalizeDepsPlugin()],
build: {
outDir: 'dist-electron',
rollupOptions: {
input: {
index: resolve(__dirname, 'electron/preload.ts')
}
}
}
}, },
renderer: { renderer: {
root: 'src',
build: {
outDir: resolve(__dirname, 'dist-electron/renderer'),
rollupOptions: {
input: {
index: resolve(__dirname, 'src/index.html')
}
}
},
resolve: { resolve: {
alias: { alias: {
'@renderer': resolve(__dirname, 'src') '@renderer': resolve(__dirname, 'src/renderer/src'),
} },
}, },
plugins: [vue()], plugins: [vue()],
server: { server: {
port: 5173 port: 5173,
} },
} },
}) })
+1 -1
View File
@@ -13,7 +13,7 @@ const commonLanguageOptions = {
} }
export default tseslint.config( export default tseslint.config(
{ ignores: ['dist', 'dist-electron', 'release', 'coverage', 'node_modules'] }, { ignores: ['dist', 'out', 'release', 'coverage', 'node_modules'] },
{ {
extends: [js.configs.recommended, ...tseslint.configs.recommended], extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.ts'], files: ['**/*.ts'],
+3 -4
View File
@@ -9,7 +9,7 @@
}, },
"homepage": "http://git.jokul.space/Jokul/JRedisDesktop", "homepage": "http://git.jokul.space/Jokul/JRedisDesktop",
"type": "module", "type": "module",
"main": "./dist-electron/main.js", "main": "./out/main/index.js",
"allowScripts": { "allowScripts": {
"electron": true, "electron": true,
"esbuild": true, "esbuild": true,
@@ -60,10 +60,9 @@
"output": "release" "output": "release"
}, },
"files": [ "files": [
"dist/**/*", "out/**/*",
"dist-electron/**/*",
"!**/*.map", "!**/*.map",
"!dist-electron/**/*.map", "!out/**/*.map",
"package.json" "package.json"
], ],
"publish": { "publish": {
+1 -1
View File
@@ -22,7 +22,7 @@ function createWindow(): void {
icon: nativeImage.createFromPath(iconPath), icon: nativeImage.createFromPath(iconPath),
backgroundColor: nativeTheme.shouldUseDarkColors ? '#0f0f1a' : '#f8fafc', backgroundColor: nativeTheme.shouldUseDarkColors ? '#0f0f1a' : '#f8fafc',
webPreferences: { webPreferences: {
preload: join(__dirname, '../preload.js'), preload: join(__dirname, '../preload/index.mjs'),
contextIsolation: true, contextIsolation: true,
nodeIntegration: false, nodeIntegration: false,
sandbox: false, sandbox: false,
View File
+1 -1
View File
@@ -7,6 +7,6 @@
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module" src="./main.ts"></script> <script type="module" src="./src/main.ts"></script>
</body> </body>
</html> </html>
View File
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"files": [], "files": [],
"references": [ "references": [
{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.node.json" } { "path": "./tsconfig.web.json" }
] ]
} }
+1 -1
View File
@@ -19,5 +19,5 @@
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true "noFallthroughCasesInSwitch": true
}, },
"include": ["electron.vite.config.ts", "electron"] "include": ["electron.vite.config.ts", "src/main/**/*", "src/preload/**/*.ts"]
} }
+8 -2
View File
@@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.web.tsbuildinfo",
"target": "es2023", "target": "es2023",
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"module": "ESNext", "module": "ESNext",
@@ -14,10 +14,16 @@
"moduleDetection": "force", "moduleDetection": "force",
"noEmit": true, "noEmit": true,
/* Path alias */
"baseUrl": ".",
"paths": {
"@renderer/*": ["src/renderer/src/*"]
},
/* Linting */ /* Linting */
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true "noFallthroughCasesInSwitch": true
}, },
"include": ["src"] "include": ["src/renderer/src/**/*", "src/preload/**/*.d.ts"]
} }