Skip to content

配置系统

配置文件

1. config.ini - 主配置文件

位置:resources/config/config.ini

ini
# 应用标题
electronTitle="vue3-simple-electron"

# 加载模式: remote(远程) 或 local(本地)
loadMode="remote"

# 本地资源路径
localWebPath="/resources/web"

# 远程URL地址
electronUrl="https://liumingxin.site"

# 应用版本
version="V1.0.0"

# 标题栏样式: default, hidden, hiddenInset, customButtonsOnHover
titleBarStyle="default"

# 自动隐藏菜单栏
autoHideMenuBar="true"

# 是否显示窗口边框
frame="true"

# 是否显示工具栏
toolbar="false"

# 子窗口是否最大化
childWindowMax="true"

# 是否启用 EXE 安装器
enableExeInstall="true"

# 启动时检查更新
checkForUpdatesOnStart="false"

# 更新服务器地址
updateVersionInfoUrl="http://127.0.0.1:30000/versions_info/"

# 启用子窗口菜单
enableChildWindowMenus="true"

# 显示主窗口右键菜单
showWindowRightMenu="true"

# 显示子窗口右键菜单
showChildWindowRightMenu="true"

# 显示缩放指示器
showZoomIndicator="true"

# 启用插件系统
enablePluginSystem="true"

# 插件自动加载
pluginAutoLoad="false"

# 插件沙箱超时时间(毫秒)
pluginSandboxTimeout="30000"

# 启用日志清理
enableLogCleanup="true"

# 日志保留天数
logRetentionDays="15"

# 定时清理日志时间
scheduleLogCleanupTime="18:00"

2. proxy-rules.yaml - 代理配置

位置:resources/config/proxy-rules.yaml

yaml
# 是否启用代理
enabled: false

# 代理规则列表
rules:
  # API 代理规则
  - context: /api
    target: http://localhost:8080
    changeOrigin: true
    pathRewrite:
      ^/api: /api/v1
    logLevel: debug

  # WebSocket 代理
  - context: /socket
    target: ws://localhost:9000
    ws: true
    changeOrigin: true

  # 静态资源代理
  - context: /assets
    target: http://cdn.example.com
    changeOrigin: true
    headers:
      X-Custom-Header: value

3. apps-install.yaml - 应用安装配置

位置:resources/config/apps-install.yaml

用于配置需要自动安装的第三方应用程序。

yaml
# 应用安装列表
apps:
  - name: '应用名称'
    path: 'installers/app-installer.exe'
    version: '1.0.0'
    silent: true # 静默安装
    autoStart: false # 安装后自动启动

配置读取

配置读取器

javascript
// packages/main/src/config/reader-config.js
const ini = require('ini');
const fs = require('fs');
const path = require('path');

/**
 * 读取配置文件
 */
function readConfig() {
  const configPath = path.join(CONFIG_DIR_PATH, 'config.ini');

  try {
    const configContent = fs.readFileSync(configPath, 'utf-8');
    return ini.parse(configContent);
  } catch (error) {
    logger.error('读取配置文件失败:', error);
    return {};
  }
}

/**
 * 获取配置项值
 * @param {string} key - 配置项名称
 * @param {any} defaultValue - 默认值
 */
function getConfigValue(key, defaultValue = null) {
  const config = readConfig();

  if (config[key] === undefined) {
    return defaultValue;
  }

  // 处理布尔值
  if (config[key] === 'true') return true;
  if (config[key] === 'false') return false;

  // 处理数字
  if (!isNaN(config[key]) && config[key] !== '') {
    return Number(config[key]);
  }

  // 去除引号
  return String(config[key]).replace(/^["']|["']$/g, '');
}

module.exports = {
  readConfig,
  getConfigValue,
  APP_TITLE: getConfigValue('electronTitle', 'Electron App'),
  CURRENT_VERSION: getConfigValue('version', 'V1.0.0'),
};

使用示例

javascript
const { getConfigValue } = require('./config/reader-config');

// 读取加载模式
const loadMode = getConfigValue('loadMode', 'remote');

// 读取远程 URL
const electronUrl = getConfigValue('electronUrl');

// 读取布尔值
const checkForUpdates = getConfigValue('checkForUpdatesOnStart'); // true/false

// 读取数字
const logRetentionDays = getConfigValue('logRetentionDays', 30); // 15

配置项详解

窗口配置

ini
# 标题栏样式
titleBarStyle="default"
# 可选值:
# - default: 默认样式
# - hidden: 隐藏标题栏
# - hiddenInset: 隐藏标题栏(macOS traffic lights)
# - customButtonsOnHover: 悬停显示按钮

# 自动隐藏菜单栏
autoHideMenuBar="true"

# 窗口边框
frame="true"

# 工具栏
toolbar="false"

加载模式配置

ini
# 加载模式
loadMode="remote"
# remote: 远程模式,加载 electronUrl
# local: 本地模式,使用本地HTTP服务器

# 远程URL(remote模式使用)
electronUrl="https://liumingxin.site"

# 本地资源路径(local模式使用)
localWebPath="/resources/web"

详见 加载模式文档

更新配置

ini
# 启动时检查更新
checkForUpdatesOnStart="false"

# 更新服务器地址
updateVersionInfoUrl="http://127.0.0.1:30000/versions_info/"

详见 更新系统文档

插件系统配置

ini
# 启用插件系统
enablePluginSystem="true"

# 插件自动加载
pluginAutoLoad="false"

# 插件沙箱超时时间(毫秒)
pluginSandboxTimeout="30000"

详见 插件通信文档

日志配置

ini
# 启用日志清理
enableLogCleanup="true"

# 日志保留天数
logRetentionDays="15"

# 定时清理日志时间(HH:mm格式)
scheduleLogCleanupTime="18:00"

详见 日志系统文档

界面配置

ini
# 显示主窗口右键菜单
showWindowRightMenu="true"

# 显示子窗口右键菜单
showChildWindowRightMenu="true"

# 显示缩放指示器
showZoomIndicator="true"

# 启用子窗口菜单
enableChildWindowMenus="true"

# 子窗口默认最大化
childWindowMax="true"

应用安装配置

ini
# 启用 EXE 安装器
enableExeInstall="true"

代理配置

代理规则说明

yaml
enabled: true # 启用代理

rules:
  - context: /api # 匹配路径
    target: http://localhost:8080 # 目标服务器
    changeOrigin: true # 改变请求源
    pathRewrite: # 路径重写
      ^/api: /api/v1 # 将 /api 替换为 /api/v1
    logLevel: debug # 日志级别

代理选项

选项类型说明默认值
contextstring匹配路径前缀必填
targetstring目标服务器地址必填
changeOriginboolean改变请求源false
wsboolean是否为 WebSocketfalse
pathRewriteobject路径重写规则{}
logLevelstring日志级别'info'
headersobject自定义请求头{}
timeoutnumber超时时间(ms)30000

WebSocket 代理

yaml
rules:
  - context: /socket
    target: ws://localhost:9000
    ws: true # 启用 WebSocket
    changeOrigin: true

路径重写

yaml
rules:
  - context: /api
    target: http://localhost:8080
    pathRewrite:
      # 移除 /api 前缀
      ^/api: ''

      # 替换为新路径
      ^/api: /v1/api

      # 多个规则
      ^/old-path: /new-path
      ^/legacy: /v2

自定义请求头

yaml
rules:
  - context: /api
    target: http://localhost:8080
    headers:
      Authorization: Bearer token123
      X-Custom-Header: value
      X-API-Key: your-api-key

配置编辑

通过快捷键编辑

Ctrl+Alt+Shift+P (Windows/Linux) 或 Cmd+Alt+Shift+P (macOS) 打开配置编辑窗口。

详见 快捷键文档

配置编辑窗口

javascript
// packages/main/src/shortcut/update-config.html
// 提供可视化界面编辑 config.ini 文件

功能:

  • 可视化编辑配置项
  • 实时验证配置值
  • 保存后提示重启应用

编程方式修改

javascript
const fs = require('fs');
const ini = require('ini');

// 读取配置
const configPath = path.join(CONFIG_DIR_PATH, 'config.ini');
const config = ini.parse(fs.readFileSync(configPath, 'utf-8'));

// 修改配置
config.loadMode = 'local';
config.checkForUpdatesOnStart = 'true';

// 保存配置
fs.writeFileSync(configPath, ini.stringify(config));

// 重启应用使配置生效
app.relaunch();
app.exit(0);

配置验证

配置项验证

javascript
/**
 * 验证配置项
 */
function validateConfig(config) {
  const errors = [];

  // 验证加载模式
  if (!['remote', 'local'].includes(config.loadMode)) {
    errors.push('loadMode 必须是 remote 或 local');
  }

  // 验证远程 URL
  if (config.loadMode === 'remote' && !config.electronUrl) {
    errors.push('remote 模式需要配置 electronUrl');
  }

  // 验证数字配置
  if (isNaN(config.logRetentionDays) || config.logRetentionDays < 1) {
    errors.push('logRetentionDays 必须是正整数');
  }

  // 验证时间格式
  if (!/^\d{2}:\d{2}$/.test(config.scheduleLogCleanupTime)) {
    errors.push('scheduleLogCleanupTime 格式必须是 HH:mm');
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}

使用验证

javascript
const config = readConfig();
const validation = validateConfig(config);

if (!validation.valid) {
  logger.error('配置验证失败:', validation.errors);
  // 使用默认配置或提示用户
}

环境变量

环境变量支持

ini
# 使用环境变量
electronUrl="${ELECTRON_URL}"
updateVersionInfoUrl="${UPDATE_SERVER}"
javascript
// 解析环境变量
function parseEnvVars(value) {
  return value.replace(/\$\{(\w+)\}/g, (match, key) => {
    return process.env[key] || match;
  });
}

const url = parseEnvVars(config.electronUrl);

.env 文件支持

bash
# .env
ELECTRON_URL=https://production.com
UPDATE_SERVER=https://updates.com
LOG_LEVEL=debug
javascript
require('dotenv').config();

// 现在可以使用 process.env.ELECTRON_URL

配置优先级

配置加载优先级(从高到低):

  1. 环境变量 - process.env.XXX
  2. 命令行参数 - --config-key=value
  3. 配置文件 - config.ini
  4. 默认值 - 代码中的默认值
javascript
function getConfigValue(key, defaultValue) {
  // 1. 环境变量
  if (process.env[key.toUpperCase()]) {
    return process.env[key.toUpperCase()];
  }

  // 2. 命令行参数
  const argValue = getCommandLineArg(key);
  if (argValue !== undefined) {
    return argValue;
  }

  // 3. 配置文件
  const config = readConfig();
  if (config[key] !== undefined) {
    return config[key];
  }

  // 4. 默认值
  return defaultValue;
}

配置热更新

监听配置文件变化

javascript
const chokidar = require('chokidar');

// 监听配置文件
const watcher = chokidar.watch(configPath, {
  persistent: true,
});

watcher.on('change', (path) => {
  logger.info('配置文件已更改:', path);

  // 重新加载配置
  reloadConfig();

  // 通知渲染进程
  BrowserWindow.getAllWindows().forEach((win) => {
    win.webContents.send('config-changed');
  });
});

部分配置热更新

某些配置可以在运行时生效,无需重启:

javascript
// 可热更新的配置
const HOT_RELOAD_CONFIGS = ['showZoomIndicator', 'showWindowRightMenu', 'logLevel'];

function handleConfigChange(key, newValue) {
  if (HOT_RELOAD_CONFIGS.includes(key)) {
    // 立即应用新配置
    applyConfig(key, newValue);
  } else {
    // 提示需要重启
    dialog
      .showMessageBox({
        message: '配置已更改,需要重启应用才能生效',
        buttons: ['立即重启', '稍后重启'],
      })
      .then((result) => {
        if (result.response === 0) {
          app.relaunch();
          app.exit(0);
        }
      });
  }
}

最佳实践

1. 使用类型安全的配置读取

javascript
// 定义配置类型
const CONFIG_TYPES = {
  loadMode: 'string',
  checkForUpdatesOnStart: 'boolean',
  logRetentionDays: 'number',
};

function getTypedConfig(key, defaultValue) {
  const value = getConfigValue(key, defaultValue);
  const type = CONFIG_TYPES[key];

  if (type === 'boolean') {
    return value === 'true' || value === true;
  } else if (type === 'number') {
    return Number(value);
  }

  return value;
}

2. 配置缓存

javascript
let configCache = null;
let cacheTime = 0;
const CACHE_TTL = 5000; // 5秒

function getCachedConfig() {
  const now = Date.now();

  if (!configCache || now - cacheTime > CACHE_TTL) {
    configCache = readConfig();
    cacheTime = now;
  }

  return configCache;
}

3. 配置备份

javascript
function backupConfig() {
  const configPath = path.join(CONFIG_DIR_PATH, 'config.ini');
  const backupPath = path.join(CONFIG_DIR_PATH, `config.ini.backup.${Date.now()}`);

  fs.copyFileSync(configPath, backupPath);
  logger.info('配置已备份:', backupPath);
}

// 修改配置前备份
function updateConfig(newConfig) {
  backupConfig();
  saveConfig(newConfig);
}

4. 配置版本管理

ini
# config.ini
configVersion="1.0.0"
javascript
function migrateConfig(config) {
  const currentVersion = config.configVersion || '0.0.0';

  // 从 0.x 迁移到 1.0
  if (compareVersions(currentVersion, '1.0.0') < 0) {
    config.newFeature = 'default';
    config.configVersion = '1.0.0';
    saveConfig(config);
  }
}

相关文件

  • resources/config/config.ini - 主配置文件
  • resources/config/proxy-rules.yaml - 代理配置
  • resources/config/apps-install.yaml - 应用安装配置
  • packages/main/src/config/reader-config.js - 配置读取器
  • packages/main/src/shortcut/update-config.html - 配置编辑界面

相关文档

基于 MIT 许可发布