窗口加载模式
概述
本项目支持两种窗口加载模式,以适应不同的开发和部署场景:
- 远程模式 (Remote): 加载远程 URL 地址
- 本地模式 (Local): 启动本地 HTTP 服务器加载静态资源
模式配置
在 resources/config/config.ini 中配置加载模式:
ini
# 窗口加载模式: remote 或 local
loadMode = remote
# 远程 URL 地址(remote 模式使用)
electronUrl = http://localhost:5173远程模式 (Remote)
适用场景
- 开发环境: 连接 Vite 开发服务器,支持热更新
- 测试环境: 连接测试服务器进行集成测试
- 在线部署: 加载云端部署的应用
配置示例
ini
loadMode = remote
electronUrl = http://localhost:5173实现原理
javascript
async function windowLoadRemoteURL(win, url) {
try {
if (!url) throw new Error('远程URL不能为空');
logger.info(`开始加载远程URL: ${url}`);
await win.loadURL(url);
openDevToolsIfNeeded(win);
logger.info(`远程URL加载成功: ${url}`);
} catch (error) {
logger.error(`当前模式: remote模式; 加载URL地址为: ${url}`);
throw error;
}
}优点
- ✅ 开发时支持热更新 (HMR)
- ✅ 无需打包,开发体验好
- ✅ 可以连接任意 HTTP 服务器
- ✅ 适合快速迭代开发
缺点
- ❌ 依赖网络连接
- ❌ 启动需要额外运行开发服务器
- ❌ 不适合离线环境
本地模式 (Local)
适用场景
- 生产环境: 打包后的应用,完全离线运行
- 演示环境: 无需网络连接的演示
- 封闭网络: 内网环境或离线环境
配置示例
ini
loadMode = local
# electronUrl 可选,作为降级备用
electronUrl = http://localhost:5173实现原理
本地模式通过启动内置的 Express HTTP 服务器来提供静态资源:
javascript
async function windowLoadLocalServer(win) {
try {
// 获取 dist 目录路径
const distPath = path.dirname(LOCAL_WEB_INDEX_FILE);
// 检查目录和文件是否存在
if (!fs.existsSync(distPath)) {
throw new Error(`本地资源目录不存在: ${distPath}`);
}
if (!fs.existsSync(LOCAL_WEB_INDEX_FILE)) {
throw new Error(`index.html 文件不存在: ${LOCAL_WEB_INDEX_FILE}`);
}
logger.info(`本地资源目录: ${distPath}`);
// 启动本地 Express 服务器
const localServer = LocalServer.getInstance();
const serverUrl = await localServer.start(distPath);
logger.info(`开始通过本地服务器加载: ${serverUrl}`);
await win.loadURL(serverUrl);
openDevToolsIfNeeded(win);
logger.info('本地服务器页面加载成功');
} catch (error) {
logger.error('启动本地服务器失败:', error);
throw error;
}
}本地服务器实现
javascript
class LocalServer {
constructor() {
this.app = express();
this.server = null;
this.port = 0; // 使用随机端口
}
async start(distPath) {
// 配置静态资源目录
this.app.use(express.static(distPath));
// 启动服务器
await new Promise((resolve) => {
this.server = this.app.listen(0, () => {
this.port = this.server.address().port;
resolve();
});
});
return `http://localhost:${this.port}`;
}
async stop() {
if (this.server) {
await new Promise((resolve) => {
this.server.close(resolve);
});
this.server = null;
}
}
}优点
- ✅ 完全离线运行
- ✅ 不依赖外部服务器
- ✅ 启动更稳定可靠
- ✅ 适合生产环境
缺点
- ❌ 需要先打包渲染进程
- ❌ 不支持热更新
- ❌ 修改代码需要重新打包
加载流程
统一加载入口
javascript
async function windowLoadByMode(win, url) {
const loadMode = getConfigValue('loadMode', LOAD_MODE.REMOTE);
logger.info(`窗口加载模式: ${loadMode} - ${loadMode === LOAD_MODE.REMOTE ? '远程' : '本地'}模式`);
try {
if (loadMode === LOAD_MODE.REMOTE) {
// 远程模式:加载远程URL
await windowLoadRemoteURL(win, url);
} else {
// 本地模式:启动本地HTTP服务器并加载
await windowLoadLocalServer(win);
}
} catch (error) {
// 统一的降级处理
logger.warn(`${loadMode}模式加载失败,尝试降级处理`);
if (loadMode === LOAD_MODE.LOCAL && url) {
// 本地模式失败,尝试远程URL作为备用
logger.info(`尝试使用远程URL作为备用: ${url}`);
try {
await windowLoadRemoteURL(win, url);
} catch (fallbackError) {
logger.error('备用远程URL加载也失败:', fallbackError);
throw new Error('所有加载方式均失败');
}
} else {
// 远程模式失败或没有备用URL,加载错误兜底页面
logger.error('远端地址暂时无法加载,将使用内置错误页面进行显示');
throw new Error(`错误详细信息: ${error.message}`);
}
}
}降级策略
尝试主要加载方式
↓
失败?
↓
检查是否有备用方案
↓
有备用?
↓
尝试备用加载方式
↓
还是失败?
↓
加载错误兜底页面降级规则:
- 本地模式失败 + 有 electronUrl → 尝试加载远程 URL
- 远程模式失败 → 加载错误页面
- 所有方式失败 → 加载错误页面
使用建议
开发环境
ini
# 推荐:远程模式 + Vite 开发服务器
loadMode = remote
electronUrl = http://localhost:5173启动流程:
bash
# 1. 启动渲染进程开发服务器
pnpm dev:renderer
# 2. 启动 Electron 主进程
pnpm dev:electron生产环境
ini
# 推荐:本地模式
loadMode = local
# 可选:提供备用 URL(用于降级)
electronUrl = https://your-backup-server.com打包流程:
bash
# 1. 打包渲染进程
pnpm build:renderer
# 2. 打包整个应用
pnpm electron:dist测试环境
ini
# 方式1: 本地打包 + 本地模式
loadMode = local
# 方式2: 远程测试服务器
loadMode = remote
electronUrl = http://test-server:8080开发工具
自动打开开发工具
开发环境下(!app.isPackaged)会自动打开开发工具:
javascript
function openDevToolsIfNeeded(win) {
if (!app.isPackaged) {
win.webContents.openDevTools();
}
}生产环境
生产环境默认不打开开发工具,但可以通过托盘菜单手动打开:
右键托盘图标 → 开发工具 → 打开开发者工具常见问题
Q1: 本地模式找不到资源文件?
原因: 渲染进程未打包或路径配置错误
解决方案:
bash
# 先打包渲染进程
pnpm build:renderer
# 检查配置文件中的路径
# packages/main/src/config/reader-config.jsQ2: 远程模式连接失败?
原因: 开发服务器未启动或 URL 配置错误
解决方案:
bash
# 1. 确保 Vite 开发服务器已启动
pnpm dev:renderer
# 2. 检查配置文件中的 electronUrl
# resources/config/config.ini
electronUrl = http://localhost:5173Q3: 如何切换模式?
修改配置文件后重启应用:
ini
# resources/config/config.ini
# 切换到远程模式
loadMode = remote
# 或切换到本地模式
loadMode = localQ4: 生产环境能用远程模式吗?
可以,但需要注意:
- ⚠️ 依赖网络连接
- ⚠️ 需要确保远程服务器稳定性
- ⚠️ 建议配置本地模式作为降级方案
ini
# 主要使用远程,本地作为备用
loadMode = remote
electronUrl = https://your-server.com
# 确保 dist 目录有打包好的资源最佳实践
1. 开发阶段
- 使用远程模式连接 Vite 开发服务器
- 享受热更新带来的快速迭代
- 渲染进程和主进程分别启动
2. 测试阶段
- 使用本地模式测试打包效果
- 验证离线运行能力
- 确保资源路径正确
3. 生产部署
- 优先使用本地模式
- 如需在线更新,可配置远程模式
- 建议同时打包本地资源作为降级
4. 混合方案
ini
# 主要用本地,远程作为降级或更新通道
loadMode = local
electronUrl = https://update-server.com/latest相关文件
packages/main/src/core/window.js- 窗口加载逻辑packages/main/src/utils/local-server.js- 本地服务器实现packages/main/src/config/reader-config.js- 配置读取resources/config/config.ini- 配置文件