你用 Java 写了一个 Spring Boot 后端,前端用 Vue 开发了一个管理界面。现在你需要把这个前后端组合打包成一个桌面应用,分发给客户使用。你开始研究 Electron、Tauri、pkg、launch4j……折腾了几天,终于搞定了。
过了几天,产品经理说:我们还有一个 Python Flask 的数据分析工具,也要打包成桌面应用。你又得从头来一遍。
再过几天,运维同事说:那个 Go 写的监控脚本,能不能也做成桌面版?你崩溃了。
每个后端应用都要单独写一套启动逻辑、打包配置、健康检查……这不合理。
这篇文章不是理论介绍,而是一份"跟着做"的实操教程。你会从零开始,一步一步完成一个真实的桌面应用打包。无论你的后端是 Java、Node.js、Python 还是 Go,只需要一份 YAML 配置文件,就能打包成一个漂亮的桌面应用。

图 1:本文实操流程概览
在开始之前,你需要确保电脑上已经安装好必要的工具。这一章会带你逐一检查并安装。
打开终端(Windows 按 Win+R 输入 cmd,macOS/Linux 打开 Terminal),输入以下命令:
node --version
如果显示 v18.x.x 或更高版本,说明已安装,跳到下一步。如果没有安装或版本低于 18,按以下方式安装:
访问 https://nodejs.org ,下载 LTS(长期支持)版本并安装。安装完成后重新打开终端,再次运行 node --version 确认。
在终端输入:
rustc --version
如果显示版本号,说明已安装。如果没有,访问 https://rustup.rs ,按页面提示安装。Windows 用户直接下载 rustup-init.exe 运行即可。
⚠️ 注意: Windows 用户需要先安装 Visual Studio Build Tools(C++ 构建工具)。访问 https://visualstudio.microsoft.com/visual-cpp-build-tools/ 下载安装,勾选"使用 C++ 的桌面开发"工作负载。
不同操作系统还需要安装额外的系统依赖:
xcode-select --install
sudo apt update
sudo apt install -y libwebkit2gtk-4.0-dev build-essential \
curl wget file libssl-dev libgtk-3-dev \
libayatana-appindicator3-dev librsvg2-dev
sudo dnf install -y webkit2gtk4.0-devel openssl-devel \
curl wget file libappindicator-gtk3-devel librsvg2-devel
sudo pacman -S --needed webkit2gtk-4.0 base-devel \
curl wget file openssl appmenu-gtk-module \
libappindicator-gtk3 librsvg
💡 提示: 安装完所有依赖后,建议重启终端,确保环境变量生效。
在动手之前,先花两分钟理解启动器是怎么工作的。知道原理后,后面配置起来会更有底气。
传统方式下,每种后端技术需要不同的打包方案:

图 2:不同后端技术的传统打包方案对比
而通用启动器的思路是:一个启动器 + 多份配置文件,覆盖所有后端类型。

图 3:传统方式 vs 通用启动器方式
启动器分为三层,各司其职:

图 4:启动器三层架构
层级 | 技术栈 | 职责 |
|---|---|---|
第一层(用户界面层) | Vue 3 | 负责显示启动画面、加载动画、错误提示。最终在 WebView 中加载你的前端页面。 |
第二层(核心控制层) | Rust | 负责解析配置文件、启动后端进程、执行健康检查、管理端口和环境变量。这是启动器的大脑。 |
第三层(后端进程层) | 任意语言 | 你的实际业务代码。启动器不关心它是什么语言,只关心怎么启动它。 |
双击启动器后,内部会按以下顺序执行:

图 5:启动器完整启动流程
步骤 | 动作 | 说明 |
|---|---|---|
1 | 读取 launcher.yml 配置文件 | 解析所有配置项 |
2 | 启动后端进程 | 根据 backend.command 和 backend.args 启动 |
3 | 执行健康检查 | 按照 health_check 配置,反复检查后端是否就绪 |
4 | 加载前端页面 | 后端就绪后,在 WebView 中加载前端页面 |
5 | 应用就绪 | 用户看到完整的应用界面,可以正常使用 |
💡 提示: 如果健康检查超时(后端迟迟没起来),启动器会在界面上显示错误信息和日志路径,不会直接闪退。

图 6:Tauri vs Electron 技术对比
简单说:Tauri 打出来的包只有 5MB 左右,Electron 要 100MB+。对于启动器这种工具,轻量是第一优先级。
这一章告诉你打包后的文件长什么样、每个文件干什么用。理解了目录结构,后面的配置就不会迷路。

图 7:标准项目目录结构
MyApp/
├── MyApp.exe # 启动器的可执行文件(Windows)
├── launcher.yml # 核心配置文件
├── frontend/ # 前端文件目录
│ └── index.html
├── backend/ # 后端文件目录
│ └── app.jar
├── runtime/ # 运行时目录(可选)
└── logs/ # 日志目录(自动创建)
文件/目录 | 作用 |
|---|---|
MyApp.exe(或 MyApp.app / my-app) | 启动器的可执行文件。用户双击它就能启动整个应用。不同平台的文件名不同:Windows 是 .exe,macOS 是 .app,Linux 是无后缀的可执行文件。 |
launcher.yml | 核心配置文件。启动器的一切行为都由它控制:启动什么命令、检查什么端口、前端在哪、窗口多大……改这个文件就够了,不需要改任何代码。 |
frontend/ | 放你的前端文件。启动器会在 WebView 中加载这个目录下的 index.html。如果你用的是 Vue/React,这里放的是 npm run build 后的输出(通常是 dist/ 或 build/ 目录的内容)。 |
backend/ | 放你的后端文件。Java 应用放 .jar 文件,Node.js 放 server.js 和 node_modules,Python 放 .py 文件和虚拟环境,Go 放编译好的二进制文件。 |
**runtime/**(可选) | 如果你不想让用户自己安装 Java/Python/Node.js,可以把运行时打包进来。比如放一个 JRE 目录,配置文件里指向它。代价是体积变大(JRE 约 150MB)。 |
logs/ | 启动器自动创建。运行日志写在这里,排查问题时看 launcher.log。 |
如果你的应用很简单,文件可以全部放根目录,不需要子文件夹:
MyApp/
├── MyApp.exe # 启动器
├── launcher.yml # 配置文件
├── index.html # 前端(直接放根目录)
└── app.jar # 后端(直接放根目录)
只要在 launcher.yml 里把路径写成 ./index.html 和 ./app.jar 就行。
这一章是全文的核心。跟着做,你会在 5 分钟内完成第一个桌面应用的打包。
从 GitHub Releases 页面下载对应平台的启动器。假设项目地址是 github.com/your-org/universal-launcher:
平台 | 下载文件 |
|---|---|
Windows | launcher-1.0.0-windows.msi |
macOS (Intel) | launcher-1.0.0-macos-intel.dmg |
macOS (Apple Silicon M1/M2/M3/M4) | launcher-1.0.0-macos-arm64.dmg |
Linux | launcher-1.0.0-linux.AppImage |
安装方式:
Windows:双击 .msi 文件安装
macOS:双击 .dmg 文件,把启动器拖到 Applications
Linux:给 AppImage 加执行权限后双击:
chmod +x launcher-1.0.0-linux.AppImage
在任意位置创建一个文件夹,比如桌面上的 MyApp:
# Windows
mkdir C:\Users\你的用户名\Desktop\MyApp
# macOS / Linux
mkdir ~/Desktop/MyApp
cd ~/Desktop/MyApp
把下载的启动器复制到这个目录里。Windows 用户把安装后的 .exe 复制过来,或者直接在这个目录安装。
在 MyApp 目录下创建 launcher.yml 文件。用任何文本编辑器(VS Code、记事本、Sublime Text)都可以。

图 8:用文本编辑器创建配置文件
输入以下内容(这是一个 Spring Boot 应用的配置,后面会讲其他后端的配置):
# launcher.yml
app:
name:"我的应用"
version:"1.0.0"
window:
width:1200
height:800
title:"我的应用 v1.0.0"
backend:
enabled:true
command:"java"
args:
-"-jar"
-"backend/app.jar"
working_dir:"./"
env:
JAVA_HOME:"C:/Program Files/Java/jdk-17"
port:8080
health_check:
type:"http"
url:"http://localhost:8080/actuator/health"
timeout:60
interval:2
frontend:
path:"./frontend"
⚠️ 注意: YAML 对缩进非常敏感!必须用空格缩进(不能用 Tab),每级缩进 2 个空格。如果缩进错误,启动器会解析失败。
按照配置文件中的路径,组织你的文件:
MyApp/
├── MyApp.exe # 启动器
├── launcher.yml # 刚才创建的配置
├── frontend/ # 前端文件
│ └── index.html
└── backend/ # 后端文件
└── app.jar
如果你还没有现成的前后端代码,可以先用最简单的文件测试:
创建 frontend/index.html:
<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body><h1>Hello from Launcher!</h1></body>
</html>
创建一个最简单的后端(以 Python 为例,因为最快):
# backend/app.py
from http.server import HTTPServer, SimpleHTTPRequestHandler
import json
class Handler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/health':
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'status':'ok'}).encode())
else:
super().do_GET()
HTTPServer(('127.0.0.1', 8080), Handler).serve_forever()
然后修改 launcher.yml 中的 backend 部分为:
backend:
enabled:true
command:"python"
args:
-"backend/app.py"
working_dir:"./"
port:8080
health_check:
type:"http"
url:"http://localhost:8080/health"
timeout:10
interval:1
双击启动器(Windows 双击 .exe,macOS 双击 .app,Linux 双击 AppImage 或 ./my-app)。
你会看到:
💡 提示: 如果启动失败,检查
logs/launcher.log文件,里面有详细的错误信息。最常见的原因是:配置文件路径不对、后端命令找不到、端口被占用。
launcher.yml 是整个系统的控制中心。这一章逐项讲解每个配置的含义、可选值和实际效果。

图 9:配置文件是启动器的控制中心
支持两种格式,推荐 YAML:
# YAML 格式(推荐,支持注释)
app:
name: "我的应用"
// JSON 格式(备选,方便程序生成)
{ "app": { "name": "我的应用" } }
启动器按以下顺序查找配置文件:
launcher.yml(优先)launcher.json(其次)配置文件必须和启动器(.exe/.app)放在同一个目录下。
控制窗口的外观和行为:
app:
name:"我的应用" # 应用名称
version:"1.0.0" # 版本号
window:
title:"我的应用 v1.0.0"# 窗口标题栏文字
width:1200 # 窗口宽度(像素)
height:800 # 窗口高度(像素)
resizable:true # 是否允许拖拽调整大小
fullscreen:false # 是否全屏启动
min_width:800 # 最小宽度
min_height:600 # 最小高度
center:true # 启动时窗口居中
always_on_top:false # 是否始终置顶
控制后端进程的启动方式:
backend:
enabled:true # 是否启用后端(false=纯前端应用)
command:"java" # 启动命令
args: # 命令参数(列表)
-"-jar"
-"backend/app.jar"
-"--server.port=8080"
working_dir:"./" # 后端进程的工作目录
env: # 环境变量
JAVA_HOME:"C:/Program Files/Java/jdk-17"
SPRING_PROFILES_ACTIVE:"prod"
port:8080 # 后端监听端口
💡 提示:
command也可以写成完整命令字符串(不推荐,因为路径中有空格时容易出错):command: "java -jar backend/app.jar"。推荐用command + args的列表形式。
控制如何判断后端已经启动完成:
health_check:
type:"http" # 检查类型:http/tcp/file/none
url:"http://localhost:8080/actuator/health"# HTTP检查URL
host:"localhost" # TCP检查的主机
port:8080 # TCP检查的端口
file_path:"./.ready" # FILE检查的文件路径
timeout:60 # 最大等待秒数
interval:2 # 每次检查间隔秒数
startup_delay:0 # 启动后延迟几秒再检查
retries:0 # 重试次数(0=无限)
frontend:
path:"./frontend" # 前端文件目录
entry:"index.html" # 入口文件名
dev_server: # 开发模式(仅开发时用)
enabled:false
command:"npm"
args:["run","dev"]
port:3000
这一章是全文最实用的部分。每个场景都是真实工作中会遇到的,配置直接复制就能用。

图 10:不同后端类型的配置差异
这是最常见的场景。假设你有一个 Spring Boot 后端(打包成 app.jar)和 Vue 前端(npm run build 后输出到 frontend/dist)。
步骤 1:准备文件
把 app.jar 放到 backend/ 目录,把 Vue 构建产物放到 frontend/dist/ 目录。
确保 app.jar 是 Fat JAR(包含所有依赖),可以用 mvn package 或 gradle build 生成。
步骤 2:编写配置
创建 launcher.yml,内容如下:
app:
name:"企业管理系统"
version:"2.1.0"
window:
title:"企业管理系统 v2.1.0"
width:1400
height:900
min_width:1024
min_height:768
backend:
enabled:true
command:"java"
args:
-"-Xms256m"
-"-Xmx512m"
-"-jar"
-"backend/app.jar"
-"--spring.profiles.active=prod"
working_dir:"./"
env:
JAVA_HOME:"${JAVA_HOME}"
SPRING_PROFILES_ACTIVE:"prod"
port:8080
health_check:
type:"http"
url:"http://localhost:8080/actuator/health"
timeout:120
interval:3
frontend:
path:"./frontend/dist"
步骤 3:验证
双击启动器,等待窗口出现。Java 启动较慢,耐心等 30-60 秒。
如果超时,把 timeout 改大(比如 180),或者检查 JAVA_HOME 路径是否正确。
💡 提示: 生产环境中,建议把 JRE 打包到
runtime/jre/目录,然后修改command为./runtime/jre/bin/java,这样用户不需要自己装 Java。
Express 后端 + React 前端。注意必须包含 node_modules 目录。
步骤 1:准备文件
在 backend/ 目录放 server.js 和 package.json,运行 npm install 生成 node_modules/。
在 frontend/ 目录放 React 构建产物(npm run build 后的 build/ 目录内容)。
步骤 2:编写配置
app:
name:"数据看板"
version:"1.0.0"
window:
width:1600
height:1000
backend:
enabled:true
command:"node"
args:["backend/server.js"]
working_dir:"./"
env:
NODE_ENV:"production"
PORT:"3001"
port:3001
health_check:
type:"http"
url:"http://localhost:3001/api/health"
timeout:30
interval:2
frontend:
path:"./frontend/build"
⚠️ 注意:
node_modules目录必须完整复制过来!如果缺少依赖,require()会报错。建议在打包前运行npm ci --production只安装生产依赖,减小体积。
步骤 1:准备文件
在 backend/ 目录放 app.py 和 requirements.txt。
创建虚拟环境并安装依赖:
python -m venv backend/venv
backend/venv/bin/pip install -r requirements.txt
步骤 2:编写配置
app:
name:"数据分析工具"
version:"3.2.1"
backend:
enabled:true
# Windows:
command:"./backend/venv/Scripts/python.exe"
# macOS/Linux:
# command: "./backend/venv/bin/python"
args:
-"-m"
-"flask"
-"run"
-"--host=127.0.0.1"
-"--port=5000"
-"--no-reload"
working_dir:"./backend"
env:
FLASK_APP:"app.py"
FLASK_ENV:"production"
PYTHONUNBUFFERED:"1"
port:5000
health_check:
type:"http"
url:"http://localhost:5000/api/ping"
timeout:30
frontend:
path:"./frontend"
💡 提示:
PYTHONUNBUFFERED设为1很重要!否则 Python 的输出会被缓冲,你看不到实时日志,排查问题时会抓瞎。
Go 最简单,编译出来就是一个二进制文件,不需要运行时。
# 先编译(在开发机上执行)
# Windows:
GOOS=windows GOARCH=amd64 go build -o backend/monitor.exe ./cmd/server
# macOS:
GOOS=darwin GOARCH=arm64 go build -o backend/monitor ./cmd/server
# Linux:
GOOS=linux GOARCH=amd64 go build -o backend/monitor ./cmd/server
app:
name:"系统监控"
version:"1.0.0"
backend:
enabled:true
command:"./backend/monitor"
args:[]
working_dir:"./backend"
env:
GIN_MODE:"release"
port:9090
health_check:
type:"http"
url:"http://localhost:9090/healthz"
timeout:10
interval:1
frontend:
path:"./frontend/dist"
💡 提示: Go 启动只要几十毫秒,
timeout设 10 秒绰绰有余。如果想进一步减小二进制体积,编译时加-ldflags="-s -w"去掉调试信息。
有些应用只有前端,比如计算器、离线文档查看器、Markdown 编辑器。
app:
name:"离线文档查看器"
version:"1.0.0"
backend:
enabled:false
health_check:
type:"none"
frontend:
path:"./frontend"
就这么简单。启动器会直接加载前端页面,不启动任何后端进程。
有些后端没有 HTTP 接口,只监听 TCP 端口。这时候用 TCP 检查:
health_check:
type:"tcp"
host:"localhost"
port:5672
timeout:30
interval:2
有些后端启动后需要初始化数据(比如导入大量数据),完成后创建一个标记文件。这时候用文件检查:
health_check:
type: "file"
file_path: "./backend/.ready"
timeout: 300
interval: 5
后端代码中,初始化完成后创建标记文件:
# Python 示例
import os
# ... 数据初始化代码 ...
with open('.ready', 'w') as f:
f.write('ok')
后端启动极快,或者前端不依赖后端,直接启动:
health_check:
type: "none"
健康检查是启动器最关键的功能之一。这一章深入讲解它的工作原理和参数调优。

图 11:健康检查机制
桌面应用启动时,需要先启动后端,再打开前端。如果后端还没准备好就打开前端,前端会收到"连接被拒绝"的错误。健康检查的作用就是确保后端完全就绪后,再加载前端页面。

图 12:四种健康检查方式对比
类型 | 适用场景 | 说明 |
|---|---|---|
HTTP | Web 应用、REST API | 发送 HTTP GET 请求,收到 200 状态码即就绪 |
TCP | gRPC、WebSocket、数据库 | 检测端口是否可连接 |
FILE | 数据初始化场景 | 检测标记文件是否存在 |
NONE | 纯前端或后端启动极快 | 跳过检查,直接加载前端 |
最常用的方式。向后端发送 HTTP GET 请求,收到 200 状态码就认为后端就绪。

图 13:HTTP 健康检查流程
各框架默认健康检查端点:

图 14:常见框架的健康检查端点
如果你的后端没有现成的健康检查端点,加一个很简单。以 Express 为例:
// server.js
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', uptime: process.uptime() });
});
不同后端的启动速度差异很大,需要调整参数:
# Java(启动慢)
timeout:120
interval:3
startup_delay:5
# Node.js(启动中等)
timeout:30
interval:2
# Go(启动极快)
timeout:10
interval:1
# Python(取决于依赖加载)
timeout:60
interval:2
startup_delay:3

图 15:健康检查失败排查指南
实际排查步骤:
步骤 1:查看日志
打开 logs/launcher.log,搜索 ERROR 或 FAILED 关键字。
步骤 2:手动测试后端
在终端手动启动后端命令,看能不能正常启动。
步骤 3:手动测试健康检查
后端启动后,在浏览器访问 health_check.url,看返回什么。
步骤 4:检查端口占用
netstat -ano | findstr 8080lsof -i :8080如果你不想用预构建版本,或者需要修改启动器本身,可以从源码构建。

图 16:从源码构建流程
git clone https://github.com/your-org/universal-launcher.git
cd universal-launcher
npm install
npm run tauri dev
这会同时启动 Vite 开发服务器和 Tauri 窗口。修改前端代码后会自动刷新,修改 Rust 代码后会自动重新编译。适合开发调试。
npm run tauri build
构建完成后,安装包在 src-tauri/target/release/bundle/ 目录下。
各平台的输出文件:

图 17:各平台构建输出文件
Tauri 支持交叉编译,但需要额外配置。以在 macOS 上构建 Windows 版为例:
# 安装 Windows 目标
rustup target add x86_64-pc-windows-msvc
# 构建
npm run tauri build -- --target x86_64-pc-windows-msvc
⚠️ 注意: 交叉编译需要对应平台的链接器。实际操作中,建议在 GitHub Actions 中为每个平台单独构建(下一章会讲)。
手动在不同平台上构建太麻烦。配置好 GitHub Actions 后,推送一个 Git 标签就能自动构建所有平台的安装包。

图 18:GitHub Actions 自动化构建
在项目根目录创建 .github/workflows/release.yml:
name: Release
on:
push:
tags:
-'v*'
jobs:
release:
permissions:
contents:write
strategy:
fail-fast:false
matrix:
include:
-platform:windows-latest
args:'--target x86_64-pc-windows-msvc'
asset_name:launcher-windows
-platform:macos-latest
args:'--target aarch64-apple-darwin'
asset_name:launcher-macos-arm64
-platform:macos-latest
args:'--target x86_64-apple-darwin'
asset_name:launcher-macos-intel
-platform:ubuntu-latest
args:''
asset_name:launcher-linux
runs-on:${{matrix.platform}}
steps:
-uses:actions/checkout@v4
-uses:actions/setup-node@v4
with:
node-version:20
-uses:dtolnay/rust-toolchain@stable
-name:InstallLinuxdeps
if:matrix.platform=='ubuntu-latest'
run:sudoaptinstall-ylibwebkit2gtk-4.0-dev\
libappindicator3-devlibrsvg2-devpatchelf
-run:npminstall
-run:npmruntauribuild${{matrix.args}}
-uses:actions/upload-artifact@v4
with:
name:${{matrix.asset_name}}
path:|
src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/dmg/*.dmg
src-tauri/target/release/bundle/appimage/*.AppImage
-uses:softprops/action-gh-release@v1
with:
files: |
src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/dmg/*.dmg
src-tauri/target/release/bundle/appimage/*.AppImage
配置好之后,发布新版本只需要三步:
# 1. 修改版本号(在 package.json 和 tauri.conf.json 中)
# 2. 提交并打标签
git add .
git commit -m "chore: bump version to 1.2.0"
git tag v1.2.0
git push origin main --tags
# 3. 等待 GitHub Actions 完成(约 10-15 分钟)
# 4. 从 GitHub Releases 页面下载各平台安装包
构建完成后,Releases 页面会包含以下文件:

图 19:GitHub Actions 构建产物

图 20:跨平台支持

图 21:跨平台特性支持矩阵
路径用反斜杠或正斜杠都行,推荐正斜杠。环境变量用 %JAVA_HOME% 或 ${JAVA_HOME}。
如果遇到"缺少 MSVCP140.dll"错误,需要安装 Visual C++ Redistributable。
首次打开会提示"无法验证开发者"。解决方法:右键点击应用 → 选择"打开" → 点击"打开"确认。
如果要正式分发,需要 Apple Developer 账号进行代码签名和公证($99/年)。
AppImage 需要加执行权限:chmod +x my-app。
某些 Linux 发行版需要安装 FUSE:sudo apt install fuse。
如果 AppImage 无法运行,尝试解压运行:./my-app --appimage-extract && ./squashfs-root/AppRun
通用启动器采用最朴素的更新策略——直接替换文件。用户操作步骤:
步骤 1:关闭正在运行的应用
步骤 2:用新文件替换旧文件
替换 .exe/.app、launcher.yml、frontend/、backend/ 目录
步骤 3:重新启动
创建一个 update.bat(Windows)或 update.sh(Linux/macOS),用户双击就能更新:
Windows (update.bat):
@echo off
echo 正在更新应用...
taskkill /F /IM MyApp.exe 2>nul
timeout /t 2 /nobreak >nul
xcopy /Y /E new_version\*.* .\
echo 更新完成!
start MyApp.exe
Linux/macOS (update.sh):
#!/bin/bash
echo "正在更新应用..."
pkill -f MyApp 2>/dev/null
sleep 2
cp -r new_version/* ./
echo "更新完成!"
open MyApp.app # macOS
# ./MyApp # Linux
方式 | 说明 |
|---|---|
内网分发 | 把安装包放在内网文件服务器,用户自行下载 |
U盘分发 | 拷贝到U盘,在目标机器上安装。适合离线环境 |
网盘分发 | 上传到百度网盘、阿里云盘,分享链接 |

图 22:技术栈

图 23:技术栈协作关系
Tauri 是启动器的核心框架。它负责:窗口管理、WebView 嵌入、进程启动和管理、系统集成(系统托盘、通知、文件操作)、跨平台构建。
选择 Tauri 的原因:包体积小(~5MB)、内存占用低(~30MB)、启动快(<1秒)、安全性高(Rust 内存安全)。
启动器的用户界面用 Vue 3 开发,包括:启动画面(应用启动时显示)、加载动画(等待后端就绪时显示)、错误页面(健康检查失败时显示)。
选择 Vue 3 的原因:上手快、组合式 API 代码组织好、TypeScript 支持优秀。
Vite 是前端构建工具。开发时提供极快的热更新,构建时生成优化的静态文件。选择它的原因:启动速度快、HMR 快、插件生态丰富。
这一章收集了实际使用中最常遇到的问题和解决方案。
问题 | 解答 |
|---|---|
Q1:启动器双击后闪退,什么都没看到 | 查看 logs/launcher.log。最常见原因:YAML 缩进错误(必须用空格不能用 Tab)、后端命令路径不对、端口被占用。 |
Q2:后端启动了但前端显示连接错误 | 健康检查通过了但前端请求的 API 地址不对。检查前端的 API baseURL 配置,确保指向正确的后端端口。 |
Q3:Java 应用启动超时 | Java 启动慢是正常的。把 timeout 改到 120-180 秒。如果用了 Spring Boot,确认 spring.profiles.active 设置正确。 |
Q4:macOS 提示"无法验证开发者" | 右键点击应用 → 打开 → 点击打开确认。如果要正式分发,需要 Apple Developer 账号签名。 |
Q5:Linux AppImage 双击没反应 | 终端执行 chmod +x my-app 添加执行权限。如果还不行,终端运行 ./my-app 看报错信息。 |
Q6:如何减小应用体积 | 不打包运行时(要求用户自行安装)、前端用 npm run build 生产构建、Go 加 -ldflags="-s -w"、Java 排除不需要的依赖。 |
Q7:如何让应用开机自启动 | Windows:把快捷方式放到 shell:startup 目录。macOS:系统设置 → 通用 → 登录项。Linux:创建 ~/.config/autostart/myapp.desktop。 |
Q8:配置文件中如何使用环境变量 | 用 ${变量名} 语法,比如 JAVA_HOME: "${JAVA_HOME}"。启动器会自动替换为系统环境变量的值。 |
Q9:如何同时运行多个实例 | 目前不支持。每个应用使用独立的目录和配置文件即可。 |
Q10:如何自定义启动画面 | 替换 frontend/ 目录下的启动页面文件。启动画面是一个普通的 HTML 页面,你可以自由设计样式。 |