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

10 KiB
Raw Permalink Blame History

MeshRay - 标准构建流程指南

最后更新: 2026-03-24
关键认识: 前端必须先 npm buildembed.go 会被 Vite 清空!


🎯 核心要点

⚠️ 重要认识

  1. 前端修改后 → 必须执行 npm run build
  2. Vite 编译时 → 会清空 dist/ 目录
  3. embed.go 被删 → 需要重新创建
  4. 最后编译后端go build

错误做法 :

# ❌ 一直编译后端,前端不重新构建
go build
go build
go build

正确做法 :

# ✅ 先构建前端,再构建后端
npm run build
# 重新创建 embed.go
go build

📋 完整构建流程

流程图:

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: 前端构建

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 单行命令(推荐)

@"
package dist

import "embed"

//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline

方法 B: 使用 cat 命令Linux/Mac

cat > web/dist/embed.go << 'EOF'
package dist

import "embed"

//go:embed *
var WebAssets embed.FS
EOF

方法 C: 手动创建文件

文件路径:web/dist/embed.go

内容:

package dist

import "embed"

//go:embed *
var WebAssets embed.FS

验证:

Test-Path "web\dist\embed.go"
# 返回:True ✅

Step 3: 清理 Go 缓存

go clean -cache

作用:

  • 清理编译器构建缓存
  • 确保重新编译所有包
  • 避免奇怪的编译错误

Step 4: 编译后端

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: 重启服务

# 停止旧服务
Get-Process -Name "meshray*" -ErrorAction SilentlyContinue | Stop-Process -Force

# 启动新服务
.\meshray.exe

验证启动:

Get-Content "logs\meshray.log" -Tail 3

期望输出:

{"message": "Starting MeshRay", "address": ":9531"}

Step 6: 测试访问

curl.exe http://localhost:9531/

期望返回:

<!DOCTYPE html>
<html lang="zh-CN">
  <title>MeshRay - 简单、高效异地组网</title>
  <script src="/assets/index-AIAUiq89.js"></script>

🛠️ 一键构建脚本

创建文件:build.ps1

#!/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

使用方法:

.\build.ps1

📊 常见场景处理

场景 1: 只修改了前端

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: 只修改了后端

go clean -cache
go build
# 重启服务

场景 3: 前后端都修改了

# 完整流程
cd web; npm run build; cd ..
# 重新创建 embed.go
go clean -cache
go build
# 重启服务

场景 4: 快速迭代开发

开发模式(不嵌入静态资源):

# 终端 1: 前端开发服务器
cd web
npm run dev

# 终端 2: 后端开发(监听变化)
air  # 或使用其他热重载工具

生产构建:

# 使用完整构建流程
.\build.ps1

⚠️ 常见错误与解决

错误 1: embed.go 丢失

症状:

no required module provides package git.zkcoi.com/zkcoi/meshray/web/dist

原因: Vite 清空了 dist/ 目录

解决:

# 重新创建 embed.go
@"
package dist
import "embed"
//go:embed *
var WebAssets embed.FS
"@ | Out-File -FilePath "web\dist\embed.go" -Encoding utf8 -NoNewline

错误 2: 前端修改不生效

症状: 页面还是旧的

原因: 没有重新编译前端

解决:

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. 开发习惯

每次修改前端后:

npm run build
# 立即测试,不要等

每次修改后端后:

go build
# 重启服务测试

2. 版本控制

.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:

{
  "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 示例:

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 - 流程规范,事半功倍! 🔧