Browse Source

开启热加载

master
hejl 2 weeks ago
parent
commit
7a2465c74b
  1. 1
      .gitignore
  2. 118
      gofaster/HOT_RELOAD.md
  3. 8
      gofaster/app/dev-hot.bat
  4. 7
      gofaster/app/dev-hot.ps1
  5. 9
      gofaster/app/dist/renderer/js/index.js
  6. 7
      gofaster/app/src/renderer/components/LoginModal.vue
  7. 47
      gofaster/backend/.air.toml
  8. 8
      gofaster/backend/dev.bat
  9. 7
      gofaster/backend/dev.ps1
  10. 7
      gofaster/backend/internal/auth/model/auth.go
  11. 6
      gofaster/backend/internal/auth/service/auth_service.go
  12. 28
      gofaster/dev-full.ps1

1
.gitignore vendored

@ -12,3 +12,4 @@ @@ -12,3 +12,4 @@
/gofaster/app/node_modules
/gofaster/app/dist
/gofaster/backend/logs
/gofaster/tmp/

118
gofaster/HOT_RELOAD.md

@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
# 🔥 GoFaster 热加载开发指南
## 概述
GoFaster 项目支持前后端热加载,修改代码后无需手动重启服务,大大提高开发效率。
## 🚀 快速启动
### 方式1:一键启动(推荐)
```bash
# 在项目根目录执行
./dev-full.ps1
```
这将同时启动前后端热加载服务。
### 方式2:分别启动
```bash
# 启动后端热加载
cd backend
./dev.ps1
# 启动前端热加载(新终端)
cd app
./dev-hot.ps1
```
## 🔧 热加载配置
### 后端 Go 热加载
- **工具**: `air` (Go 热加载工具)
- **配置文件**: `backend/.air.toml`
- **监听文件**: `.go`, `.tpl`, `.tmpl`, `.html`
- **排除目录**: `tmp`, `vendor`, `docs`, `testdata`
### 前端 Electron 热加载
- **工具**: `vue-cli-service` + `electron`
- **配置文件**: `app/vue.config.js`
- **监听文件**: `.vue`, `.js`, `.css`, `.html`
- **自动重载**: 代码修改后自动重新编译并重启 Electron
## 📁 文件结构
```
gofaster/
├── dev-full.ps1 # 一键启动脚本
├── backend/
│ ├── .air.toml # 后端热加载配置
│ ├── dev.bat # Windows 后端启动脚本
│ └── dev.ps1 # PowerShell 后端启动脚本
└── app/
├── dev-hot.bat # Windows 前端启动脚本
└── dev-hot.ps1 # PowerShell 前端启动脚本
```
## 🎯 使用场景
### 后端开发
1. 修改 Go 代码
2. 保存文件
3. `air` 自动检测变化
4. 自动重新编译并重启服务
5. 无需手动重启
### 前端开发
1. 修改 Vue 组件、样式或逻辑
2. 保存文件
3. `vue-cli-service` 自动重新编译
4. Electron 自动重载
5. 界面立即更新
## ⚡ 性能优化
### 后端优化
- 排除测试文件和文档目录
- 设置合理的重载延迟(1秒)
- 只监听必要的文件类型
### 前端优化
- 启用增量编译
- 排除不必要的文件监听
- 使用内存中的热重载
## 🐛 故障排除
### 后端热加载不工作
1. 检查 `air` 是否安装:`go version -m $(which air)`
2. 确认 `.air.toml` 配置正确
3. 检查文件权限和路径
### 前端热加载不工作
1. 确认 `npm run dev` 正常运行
2. 检查 `vue.config.js` 配置
3. 查看控制台错误信息
### 端口冲突
- 后端默认端口:8080
- 前端开发端口:3000
- 如遇冲突,修改相应配置文件
## 💡 开发技巧
1. **保持两个终端窗口**:一个运行后端,一个运行前端
2. **使用 VS Code 集成终端**:方便同时查看前后端日志
3. **合理使用日志**:热重载时日志会保留,便于调试
4. **测试验证码接口**:修改后端代码后,验证码接口会立即生效
## 🔄 热加载流程
```
修改代码 → 保存文件 → 自动检测 → 重新编译 → 重启服务 → 立即生效
```
## 📚 相关文档
- [Air 官方文档](https://github.com/air-verse/air)
- [Vue CLI 热重载](https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve)
- [Electron 开发指南](https://www.electronjs.org/docs/tutorial/development)
---
**享受高效的开发体验!** 🎉

8
gofaster/app/dev-hot.bat

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
@echo off
echo Starting GoFaster Frontend with Hot Reload...
echo.
echo Hot reload enabled - code changes will automatically rebuild and reload
echo Press Ctrl+C to stop
echo.
npm run dev

7
gofaster/app/dev-hot.ps1

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
Write-Host "Starting GoFaster Frontend with Hot Reload..." -ForegroundColor Green
Write-Host ""
Write-Host "Hot reload enabled - code changes will automatically rebuild and reload" -ForegroundColor Yellow
Write-Host "Press Ctrl+C to stop" -ForegroundColor Yellow
Write-Host ""
npm run dev

9
gofaster/app/dist/renderer/js/index.js vendored

@ -2375,7 +2375,7 @@ __webpack_require__.r(__webpack_exports__); @@ -2375,7 +2375,7 @@ __webpack_require__.r(__webpack_exports__);
username: this.loginForm.username,
password: this.loginForm.password,
captcha: this.loginForm.captcha,
captchaId: this.captchaId
captcha_id: this.captchaId // 修复字段名:后端期望 snake_case
})
// 登录成功
@ -2404,8 +2404,9 @@ __webpack_require__.r(__webpack_exports__); @@ -2404,8 +2404,9 @@ __webpack_require__.r(__webpack_exports__);
this.errorMessage = ''
// 调用获取验证码接口
const response = await _services_userService__WEBPACK_IMPORTED_MODULE_0__.userService.getCaptcha()
this.captchaImage = response.captchaImage
this.captchaId = response.captchaID
// 修复字段映射:后端返回的是 snake_case,前端使用 camelCase
this.captchaImage = response.data.captcha_image
this.captchaId = response.data.captcha_id
this.loginForm.captcha = ''
console.log('验证码获取成功:', response)
} catch (error) {
@ -6889,7 +6890,7 @@ __webpack_require__.r(__webpack_exports__); @@ -6889,7 +6890,7 @@ __webpack_require__.r(__webpack_exports__);
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("b656c4a813fb38f6")
/******/ __webpack_require__.h = () => ("d46aac25b901a9b0")
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */

7
gofaster/app/src/renderer/components/LoginModal.vue

@ -159,7 +159,7 @@ export default { @@ -159,7 +159,7 @@ export default {
username: this.loginForm.username,
password: this.loginForm.password,
captcha: this.loginForm.captcha,
captchaId: this.captchaId
captcha_id: this.captchaId // snake_case
})
//
@ -188,8 +188,9 @@ export default { @@ -188,8 +188,9 @@ export default {
this.errorMessage = ''
//
const response = await userService.getCaptcha()
this.captchaImage = response.captchaImage
this.captchaId = response.captchaID
// snake_case使 camelCase
this.captchaImage = response.data.captcha_image
this.captchaId = response.data.captcha_id
this.loginForm.captcha = ''
console.log('验证码获取成功:', response)
} catch (error) {

47
gofaster/backend/.air.toml

@ -1,21 +1,44 @@ @@ -1,21 +1,44 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
cmd = "go build -o ./tmp/main.exe ."
args_bin = ["-v"]
bin = "./tmp/main.exe"
runner = ["./tmp/main.exe"]
include_ext = ["go", "tpl", "tmpl", "html"]
exclude_dir = ["assets", "tmp", "vendor", "docs"]
args_bin = []
bin = "./tmp/main.exe"
cmd = "go build -o ./tmp/main.exe ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "docs"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_root = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
time = true
level = "debug"
main_only = false
time = false
[misc]
clean_on_exit = true
clean_before_build = true
clean_on_exit = false
[windows]
filter_extension = ["exe", "dll", "so", "a"]
[screen]
clear_on_rebuild = false
keep_scroll = true

8
gofaster/backend/dev.bat

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
@echo off
echo Starting GoFaster Backend with Hot Reload...
echo.
echo Hot reload enabled - code changes will automatically restart the server
echo Press Ctrl+C to stop
echo.
air

7
gofaster/backend/dev.ps1

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
Write-Host "Starting GoFaster Backend with Hot Reload..." -ForegroundColor Green
Write-Host ""
Write-Host "Hot reload enabled - code changes will automatically restart the server" -ForegroundColor Yellow
Write-Host "Press Ctrl+C to stop" -ForegroundColor Yellow
Write-Host ""
air

7
gofaster/backend/internal/auth/model/auth.go

@ -4,9 +4,10 @@ import "time" @@ -4,9 +4,10 @@ import "time"
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required" validate:"required,min=3,max=50"`
Password string `json:"password" binding:"required" validate:"required,min=6,max=100"`
Captcha string `json:"captcha" binding:"required" validate:"required,len=4"`
Username string `json:"username" binding:"required" validate:"required,min=3,max=50"`
Password string `json:"password" binding:"required" validate:"required,min=6,max=100"`
Captcha string `json:"captcha" binding:"required" validate:"required,len=4"`
CaptchaID string `json:"captcha_id" binding:"required" validate:"required"`
}
// LoginResponse 登录响应

6
gofaster/backend/internal/auth/service/auth_service.go

@ -43,7 +43,7 @@ func NewAuthService(userRepo repository.UserRepository, captchaRepo repository.C @@ -43,7 +43,7 @@ func NewAuthService(userRepo repository.UserRepository, captchaRepo repository.C
// Login 用户登录
func (s *authService) Login(ctx context.Context, req *model.LoginRequest, clientIP string) (*model.LoginResponse, error) {
// 1. 验证验证码
if err := s.ValidateCaptcha(ctx, req.Username, req.Captcha); err != nil {
if err := s.ValidateCaptcha(ctx, req.CaptchaID, req.Captcha); err != nil {
return nil, fmt.Errorf("验证码错误: %w", err)
}
@ -280,14 +280,14 @@ func (s *authService) generateCaptchaImage(text string) string { @@ -280,14 +280,14 @@ func (s *authService) generateCaptchaImage(text string) string {
// 使用HTML5 Canvas风格的文本渲染
width := 120
height := 40
// 创建一个简单的SVG图片,包含验证码文本
svg := fmt.Sprintf(`<svg width="%d" height="%d" xmlns="http://www.w3.org/2000/svg">
<rect width="%d" height="%d" fill="#f0f0f0"/>
<text x="%d" y="%d" font-family="Arial, sans-serif" font-size="24" font-weight="bold"
fill="#333" text-anchor="middle" dominant-baseline="middle">%s</text>
</svg>`, width, height, width, height, width/2, height/2, text)
// 将SVG转换为Base64
return fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString([]byte(svg)))
}

28
gofaster/dev-full.ps1

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
Write-Host "🚀 Starting GoFaster Full Stack Development Environment..." -ForegroundColor Cyan
Write-Host ""
Write-Host "Frontend: Electron + Vue.js with Hot Reload" -ForegroundColor Green
Write-Host "Backend: Go + Gin with Hot Reload" -ForegroundColor Green
Write-Host ""
Write-Host "Press Ctrl+C to stop all services" -ForegroundColor Yellow
Write-Host ""
# 启动后端热加载(后台运行)
Write-Host "Starting Backend with Hot Reload..." -ForegroundColor Green
Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd backend; air" -WindowStyle Normal
# 等待2秒让后端启动
Start-Sleep -Seconds 2
# 启动前端热加载(后台运行)
Write-Host "Starting Frontend with Hot Reload..." -ForegroundColor Green
Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd app; npm run dev" -WindowStyle Normal
Write-Host ""
Write-Host "✅ Both services started successfully!" -ForegroundColor Green
Write-Host "Frontend: http://localhost:3000 (Electron app)" -ForegroundColor Cyan
Write-Host "Backend: http://localhost:8080" -ForegroundColor Cyan
Write-Host "Swagger: http://localhost:8080/swagger/index.html" -ForegroundColor Cyan
Write-Host ""
Write-Host "💡 Code changes will automatically trigger rebuilds and reloads!" -ForegroundColor Yellow
Write-Host "Press any key to exit this launcher..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Loading…
Cancel
Save