Files
Meshray-Manager/docs/标准构建流程指南.md
2026-06-30 15:14:37 +08:00

591 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MeshRay - 标准构建流程指南
**最后更新**: 2026-03-24
**关键认识**: 前端必须先 npm buildembed.go 会被 Vite 清空!
---
## 🎯 **核心要点**
### ⚠️ **重要认识**
1. **前端修改后** → 必须执行 `npm run build`
2. **Vite 编译时** → 会清空 `dist/` 目录
3. **embed.go 被删** → 需要重新创建
4. **最后编译后端**`go build`
**错误做法** ❌:
```bash
# ❌ 一直编译后端,前端不重新构建
go build
go build
go build
```
**正确做法** ✅:
```bash
# ✅ 先构建前端,再构建后端
npm run build
# 重新创建 embed.go
go build
```
---
## 📋 **完整构建流程**
### 流程图:
```mermaid
graph TD
A[开始] --> B{修改了什么?}
B -->|前端代码 | C[npm run build]
B -->|后端代码 | G
C --> D[Vite 编译 dist/]
D --> E[⚠️ embed.go 被删除]
E --> F[重新创建 embed.go]
F --> G[go clean -cache]
G --> H[go build 编译后端]
H --> I[重启服务]
I --> J[测试访问]
J --> K{成功?}
K -->|是 | L[✅ 完成]
K -->|否 | M[检查日志]
```
---
## 🔧 **详细步骤**
### Step 1: 前端构建 ⭐⭐⭐
```bash
cd web
npm run build
```
**输出示例**:
```
✓ built in 13.41s
```
**生成的文件**:
```
dist/
├── index.html
├── assets/
│ ├── index-AIAUiq89.js
│ ├── Login-Brnne-RL.js ← 登录页组件
│ ├── Dashboard-DSsX0xA1.js ← 仪表盘组件
│ └── ... (共 44 个文件)
```
**注意**:
- ⚠️ Vite 会清空整个 `dist/` 目录
- ⚠️ `embed.go` 会被删除
- ✅ 每次都会生成新的 hash 文件名
---
### Step 2: 重新创建 embed.go ⭐⭐⭐
**方法 A: PowerShell 单行命令**(推荐)
```powershell
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline
```
---
**方法 B: 使用 cat 命令**Linux/Mac
```bash
cat > web/dist/embed.go << 'EOF'
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
EOF
```
---
**方法 C: 手动创建文件**
文件路径:`web/dist/embed.go`
内容:
```go
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
```
**验证**:
```bash
Test-Path "web\dist\embed.go"
# 返回:True ✅
```
---
### Step 3: 清理 Go 缓存
```bash
go clean -cache
```
**作用**:
- 清理编译器构建缓存
- 确保重新编译所有包
- 避免奇怪的编译错误
---
### Step 4: 编译后端 ⭐⭐⭐
```bash
go build -o meshray.exe -ldflags "-s -w -H=windowsgui" ./cmd/meshray
```
**参数说明**:
- `-o meshray.exe`: 输出文件名
- `-s -w`: 去除符号表和调试信息(减小体积)
- `-H=windowsgui`: Windows GUI 模式(无控制台窗口)
**编译时间**: 约 5-10 秒
---
### Step 5: 重启服务
```bash
# 停止旧服务
Get-Process -Name "meshray*" -ErrorAction SilentlyContinue | Stop-Process -Force
# 启动新服务
.\meshray.exe
```
**验证启动**:
```bash
Get-Content "logs\meshray.log" -Tail 3
```
**期望输出**:
```json
{"message": "Starting MeshRay", "address": ":9531"}
```
---
### Step 6: 测试访问
```bash
curl.exe http://localhost:9531/
```
**期望返回**:
```html
<!DOCTYPE html>
<html lang="zh-CN">
<title>MeshRay - 简单、高效异地组网</title>
<script src="/assets/index-AIAUiq89.js"></script>
```
---
## 🛠️ **一键构建脚本**
创建文件:`build.ps1`
```powershell
#!/usr/bin/env pwsh
# MeshRay 标准构建脚本
Write-Host "🔨 开始构建 MeshRay..." -ForegroundColor Cyan
# 1. 前端构建
Write-Host "`n📦 步骤 1: 构建前端..." -ForegroundColor Yellow
Set-Location web
npm run build
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ 前端构建失败!" -ForegroundColor Red
exit 1
}
Set-Location ..
# 2. 重新创建 embed.go
Write-Host "`n📝 步骤 2: 创建 embed.go..." -ForegroundColor Yellow
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline
if (-not (Test-Path "web\dist\embed.go")) {
Write-Host "❌ embed.go 创建失败!" -ForegroundColor Red
exit 1
}
# 3. 清理 Go 缓存
Write-Host "`n🧹 步骤 3: 清理 Go 缓存..." -ForegroundColor Yellow
go clean -cache
# 4. 编译后端
Write-Host "`n🔨 步骤 4: 编译后端..." -ForegroundColor Yellow
go build -o meshray.exe -ldflags "-s -w -H=windowsgui" ./cmd/meshray
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ 后端编译失败!" -ForegroundColor Red
exit 1
}
# 5. 重启服务
Write-Host "`n🔄 步骤 5: 重启服务..." -ForegroundColor Yellow
Get-Process -Name "meshray*" -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 2
Start-Process ".\meshray.exe"
# 6. 等待启动
Start-Sleep -Seconds 3
# 7. 测试访问
Write-Host "`n🧪 步骤 6: 测试访问..." -ForegroundColor Yellow
$response = curl.exe http://localhost:9531/ -s
if ($response -match "DOCTYPE") {
Write-Host "`n✅ 构建成功!前端页面可访问" -ForegroundColor Green
} else {
Write-Host "`n❌ 测试失败!请检查日志" -ForegroundColor Red
Get-Content "logs\meshray.log" -Tail 10
exit 1
}
Write-Host "`n✨ 完成!" -ForegroundColor Green
Write-Host "📱 访问地址:http://localhost:9531" -ForegroundColor Cyan
```
**使用方法**:
```bash
.\build.ps1
```
---
## 📊 **常见场景处理**
### 场景 1: 只修改了前端
```bash
cd web
npm run build
# 重新创建 embed.go
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "dist\embed.go" -Encoding utf8 -NoNewline
cd ..
go build
# 重启服务
```
---
### 场景 2: 只修改了后端
```bash
go clean -cache
go build
# 重启服务
```
---
### 场景 3: 前后端都修改了
```bash
# 完整流程
cd web; npm run build; cd ..
# 重新创建 embed.go
go clean -cache
go build
# 重启服务
```
---
### 场景 4: 快速迭代开发
**开发模式**(不嵌入静态资源):
```bash
# 终端 1: 前端开发服务器
cd web
npm run dev
# 终端 2: 后端开发(监听变化)
air # 或使用其他热重载工具
```
**生产构建**:
```bash
# 使用完整构建流程
.\build.ps1
```
---
## ⚠️ **常见错误与解决**
### 错误 1: embed.go 丢失
**症状**:
```
no required module provides package git.zkcoi.com/zkcoi/meshray/web/dist
```
**原因**: Vite 清空了 dist/ 目录
**解决**:
```bash
# 重新创建 embed.go
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline
```
---
### 错误 2: 前端修改不生效
**症状**: 页面还是旧的
**原因**: 没有重新编译前端
**解决**:
```bash
cd web
npm run build
# 然后重新创建 embed.go 并编译后端
```
---
### 错误 3: MIME 类型错误
**症状**:
```
Expected JavaScript but got text/html
```
**原因**: 路由顺序错误或浏览器缓存
**解决**:
1. 确认 `server.go` 中 StaticFS 在 NoRoute 之前
2. 清除浏览器缓存(Ctrl+Shift+R
3. Network 标签勾选 Disable cache
---
### 错误 4: 编译产物 hash 变化
**症状**:
- 这次是 `Login-ABC123.js`
- 下次是 `Login-XYZ789.js`
**原因**: Vite 的内容哈希策略
**解决**: 正常现象,无需处理。每次 build 都会生成新 hash
---
## 📋 **检查清单**
构建前检查:
- [ ] ✅ 前端代码已保存
- [ ] ✅ 后端代码已保存
- [ ] ✅ Git 状态干净(可选)
构建中检查:
- [ ]`npm run build` 成功
- [ ] ✅ embed.go 已重新创建
- [ ]`go build` 无错误
构建后检查:
- [ ] ✅ 服务正常启动
- [ ] ✅ curl 测试返回 HTML
- [ ] ✅ 浏览器访问正常
- [ ] ✅ Console 无错误
---
## 💡 **最佳实践**
### 1. 开发习惯
**每次修改前端后**:
```bash
npm run build
# 立即测试,不要等
```
**每次修改后端后**:
```bash
go build
# 重启服务测试
```
---
### 2. 版本控制
**.gitignore 配置**:
```gitignore
# 构建产物
web/dist/*
!web/dist/.gitkeep
*.exe
*.log
# 但保留 embed.go 模板
!web/dist/embed.go.template
```
**建议**: 创建 `embed.go.template` 作为模板
---
### 3. 自动化
**VS Code Tasks**:
`.vscode/tasks.json`:
```json
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Frontend",
"type": "shell",
"command": "npm run build",
"options": {
"cwd": "${workspaceFolder}/web"
}
},
{
"label": "Build Backend",
"type": "shell",
"command": "go build -o meshray.exe -ldflags \"-s -w -H=windowsgui\" ./cmd/meshray",
"group": "build"
}
]
}
```
---
### 4. CI/CD 集成
**GitHub Actions 示例**:
```yaml
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build Frontend
run: npm run build
working-directory: ./web
- name: Create embed.go
shell: pwsh
run: |
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline
- name: Build Backend
run: go build -o meshray.exe -ldflags "-s -w -H=windowsgui" ./cmd/meshray
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: meshray
path: meshray.exe
```
---
## 🎯 **总结**
### 核心口诀:
> **前端改,npm build**
> **Vite 清,embed 没**
> **重新建,莫要忘**
> **后端编,服务启**
---
### 关键记忆点:
1.**前端修改必 npm build**
2.**Vite 会清空 dist/**
3.**embed.go 需要重建**
4.**最后才能 go build**
---
### 一句话总结:
**修改前端 → npm run build → 重建 embed.go → go build → 重启服务**
---
**状态**: ✅ **正确的构建流程已明确**
**下次记住**: 前端修改后先 npm build,别忘了重建 embed.go
*MeshRay - 流程规范,事半功倍!* ✨🔧