🚀 从窗口管理到状态同步,为企业级桌面应用提供完整支持
一个为复杂 Electron 应用打造的综合基础设施工具包,提供企业级的窗口管理、类型安全的 IPC 路由和高性能状态同步功能。从架构设计到生产部署,为你的桌面应用提供完整的解决方案!
🎯 为什么需要 Electron Infra Kit?
在开发复杂的 Electron 应用时,你是否遇到过这些痛点:
😵 窗口管理的噩梦
- 内存泄漏风险 - 手动维护窗口实例数组,忘记清理导致内存泄漏
- 重复创建问题 - 用户多次点击创建重复窗口,影响用户体验
- 状态丢失困扰 - 窗口关闭后位置、大小、最大化状态无法恢复
- 关系管理复杂 - 窗口之间的父子关系、分组管理难以维护
- 焦点历史混乱 - 无法追踪窗口焦点历史,用户体验不佳
� 跨IPC 通信的困扰
- 类型安全缺失 - 缺乏编译时类型检查,运行时错误频发
- 通道管理混乱 - 通道名称硬编码,重构困难,容易冲突
- 参数验证繁琐 - 需要手动实现参数验证,代码冗余
- 错误处理不统一 - 缺少统一的错误处理机制,调试困难
- 依赖注入缺失 - 无法在处理器中优雅地注入服务和 API
- 性能监控困难 - 缺少 IPC 调用的性能监控和限流机制
😫 跨窗口状态同步的挑战
- 手动实现复杂 - 需要手动实现发布-订阅模式,代码复杂
- 性能优化困难 - 状态更新频繁时性能优化困难
- 状态不一致 - 多窗口间容易出现状态不一致问题
- 权限控制缺失 - 缺少字段级和窗口级的权限控制机制
- 内存管理困难 - 订阅者管理不当导致内存泄漏
- 事务支持缺失 - 缺少批量更新和事务回滚机制
Electron Infra Kit 通过企业级的架构设计和完善的功能模块,彻底解决这些问题!
✨ 核心架构与模块详解
🏗️ 分层架构设计
Electron Infra Kit 采用现代化的分层架构,确保关注点分离和高度可维护性:
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (Application Layer) │
│ 开发者业务代码 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 核心层 (Core Layer) │
│ WindowManager │ IpcRouter │ MessageBus │ LifecycleManager │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 支撑层 (Support Layer) │
│ WindowStore │ PluginExecutor │ MessageDispatcher │ DI Container │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 基础设施层 (Infrastructure Layer) │
│ ConfigManager │ Logger │ DebugHelper │ PerformanceMonitor │ ErrorHandler │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Electron 运行时层 │
│ BrowserWindow │ ipcMain │ ipcRenderer │
└─────────────────────────────────────────────────────────────┘
🪟 智能窗口管理系统
核心组件架构
// WindowManager 采用组合模式,将职责委托给专门的管理器
class WindowManager {
private windowStore: WindowStore; // 核心门面
private pluginExecutor: PluginExecutor; // 插件系统
private lifecycle: WindowLifecycle; // 生命周期管理
private metricsManager: MetricsManager; // 性能监控
}
// WindowStore 协调四大核心模块
class WindowStore {
private registry: WindowRegistry; // 窗口注册表
private operator: WindowOperator; // 窗口操作器
private stateManager: WindowStateManager; // 状态持久化
private contextManager: WindowContextManager; // 上下文管理
}
1. WindowRegistry - 窗口注册表
职责:管理窗口存储映射和分组关系
class WindowRegistry {
// 核心映射关系
private windows: Map<string, BrowserWindow>; // ID -> 窗口实例
private windowNames: Map<string, string>; // 名称 -> ID
private windowIds: Map<string, string>; // ID -> 名称
private windowInstanceIds: Map<BrowserWindow, string>; // 实例 -> ID
// 分组管理
private groups: Map<string, Set<string>>; // 组名 -> 窗口ID集合
private windowGroups: Map<string, Set<string>>; // 窗口ID -> 组名集合
// 智能清理机制
startCleanupProtection(intervalMs: number): void {
// 定期清理已销毁的窗口,防止内存泄漏
this.cleanupTimer = setInterval(() => {
this.cleanupDestroyedWindows();
}, intervalMs);
}
}
特性:
- 双向索引 - 支持通过 ID、名称、实例快速查找
- 分组管理 - 支持窗口分组,批量操作
- 内存保护 - 自动清理已销毁窗口,防止内存泄漏
- 分块处理 - 大量窗口时分块处理,避免阻塞主线程
2. WindowOperator - 窗口操作器
职责:封装所有窗口操作,提供安全检查
class WindowOperator {
// 安全检查
isSafe(window?: BrowserWindow | null): window is BrowserWindow {
return !!window && !window.isDestroyed();
}
// 统一的窗口操作
show(window: BrowserWindow): void {
if (!this.isSafe(window)) return;
window.show();
window.setSkipTaskbar(false);
}
// 开发者工具管理
openDevTools(window: BrowserWindow): void;
closeDevTools(window: BrowserWindow): void;
isDevToolsOpened(window: BrowserWindow): boolean;
}
特性:
- 安全第一 - 所有操作前都进行安全检查
- 操作统一 - 统一的窗口操作接口
- 开发支持 - 内置开发者工具管理
3. WindowStateManager - 状态持久化管理器
职责:管理窗口状态的持久化和恢复
class WindowStateManager {
private stateKeeper: StateKeeper;
manage(name: string, window: BrowserWindow, getGroups?: () => string[]): void {
const saveState = () => {
const bounds = window.getBounds();
const isMaximized = window.isMaximized();
const display = screen.getDisplayMatching(bounds);
this.stateKeeper.saveState(name, {
x: bounds.x, y: bounds.y,
width: bounds.width, height: bounds.height,
isMaximized, isFullScreen: window.isFullScreen(),
displayBounds: display.bounds,
groups: getGroups ? getGroups() : undefined,
});
};
// 监听所有状态变化事件
window.on('resize', saveState);
window.on('move', saveState);
window.on('maximize', saveState);
// ... 更多事件
}
}
StateKeeper 高级特性:
class StateKeeper {
// 智能保存策略
private saveStrategy: 'debounce' | 'throttle';
// 原子写入保护
private async performSave(): Promise<void> {
const tempFile = `${this.stateFile}.tmp`;
// 1. 写入临时文件
await fs.promises.writeFile(tempFile, data);
// 2. 原子重命名(大多数文件系统上是原子操作)
await fs.promises.rename(tempFile, this.stateFile);
}
// 状态验证
private isValidState(state: WindowState): boolean {
const displays = screen.getAllDisplays();
// 检查窗口是否在可用显示器范围内
return displays.some(display => /* 相交检查 */);
}
}
特性:
- 防抖/节流 - 可配置的保存策略,避免频繁 IO
- 原子写入 - 使用临时文件确保数据完整性
- 状态验证 - 确保恢复的窗口在可用显示器范围内
- 多实例保护 - 防止多个实例同时写入同一文件
- MD5 优化 - 只在数据真正变化时才写入磁盘
4. 焦点历史管理
class WindowStore {
private focusHistory: string[] = [];
pushFocus(windowId: string): void {
// 移除已存在的(移动到顶部)
this.focusHistory = this.focusHistory.filter(id => id !== windowId);
this.focusHistory.push(windowId);
}
getPreviousFocusedWindow(): string | undefined {
// 返回上一个聚焦的窗口
return this.focusHistory[this.focusHistory.length - 2];
}
}
5. 窗口分组系统
// 创建窗口并加入组
const editorWindow = await windowManager.create({
name: 'editor-main',
title: '主编辑器',
groups: ['editor-group', 'main-windows']
});
// 批量操作组内窗口
await windowManager.closeGroup('editor-group');
windowManager.hideGroup('tool-windows');
windowManager.focusGroup('main-windows');
🔌 类型安全的 IPC 路由系统
核心架构
class IpcRouter<Api, Schema> {
private dispatcher: MessageDispatcher<Api>; // 消息分发器
private rateLimiter: RateLimiter; // 限流器
// 添加处理器
addHandler<K extends keyof Schema>(
handler: IpcHandler<Api, Schema[K]['payload'], Schema[K]['response']>
): void {
this.dispatcher.register(handler.name, handler.callback, handler.schema);
}
}
1. IpcHandler - 处理器定义
class IpcHandler<Context, T, R> {
constructor(
private name: string,
private event: string,
private callback: IpcHandlerCallback<Context, T, R>,
private schema?: ZodType<T> // Zod 验证 schema
) {}
}
// 使用示例
const getUserHandler = new IpcHandler(
'getUser',
'user',
async (context, payload: { id: string }) => {
// 可以访问注入的 API
const db = context.api.database;
const user = await db.users.findById(payload.id);
return { success: true, data: user };
},
z.object({ id: z.string().min(1) }) // 运行时验证
);
2. MessageDispatcher - 消息分发器
class MessageDispatcher<Context> {
private handlers = new Map<string, {
callback: HandlerCallback<Context, any, any>;
metadata?: any; // 存储 Zod schema 等元数据
}>();
dispatch<T, R>(name: string, context: Context, data: T): R | undefined {
const entry = this.handlers.get(name);
if (!entry) return undefined;
try {
// 执行处理器
return entry.callback(context, data);
} catch (error) {
this.logger.error(`Error in handler "${name}": ${error}`);
if (this.errorHandler) {
return this.errorHandler(error, name);
}
throw error;
}
}
}
3. RateLimiter - 智能限流器
class RateLimiter {
private limits = new Map<string, RateLimitConfig>();
private state = new Map<string, RateLimitState>();
check(key: string, ruleKey: string): boolean {
const config = this.limits.get(ruleKey) || this.defaultLimit;
if (!config) return true;
const now = Date.now();
let record = this.state.get(key);
if (!record || now > record.resetTime) {
record = {
count: 0,
resetTime: now + config.interval,
};
this.state.set(key, record);
}
if (record.count >= config.limit) {
this.logger.warn(`Rate limit exceeded for ${key}`);
return false;
}
record.count++;
return true;
}
}
// 使用示例
ipcRouter.setRateLimit('expensiveOperation', {
limit: 10, // 10次调用
interval: 60000 // 每分钟
});
4. 依赖注入系统
// 主进程中注册服务
const context = {
api: {
database: new DatabaseService(),
fileSystem: new FileSystemService(),
notification: new NotificationService(),
},
window: {
getWinId: () => getCurrentWindowId(),
minimize: (id) => windowManager.minimize(id),
// ... 更多窗口操作
}
};
// 处理器中使用注入的服务
const saveFileHandler = new IpcHandler(
'saveFile',
'file',
async (context, payload: { path: string, content: string }) => {
// 使用注入的文件系统服务
await context.api.fileSystem.writeFile(payload.path, payload.content);
// 使用注入的通知服务
context.api.notification.show('文件保存成功');
return { success: true };
},
z.object({
path: z.string().min(1),
content: z.string()
})
);
🌉 高性能消息总线系统
核心架构
class MessageBus extends EventEmitter {
// 核心管理器
private subscriptionManager: SubscriptionManager; // 订阅管理
private transactionManager: TransactionManager; // 事务管理
private dataStoreManager: DataStoreManager; // 数据存储管理
// 传输层
private transport: ITransport; // MessagePort 或 IPC 传输
private windows: Map<string, BrowserWindow>;
}
1. DataStoreManager - 数据存储管理器
class DataStoreManager {
private dataStore: Map<string, DataStoreItem> = new Map();
// 权限检查
checkPermission(
key: string,
windowId: string | undefined,
operation: 'modify' | 'delete'
): { success: boolean; error?: string } {
const item = this.dataStore.get(key);
if (item?.permission) {
if (item.permission.readonly) {
return { success: false, error: `Field "${key}" is readonly` };
}
if (item.permission.allowedWindows && windowId) {
if (!item.permission.allowedWindows.includes(windowId)) {
return {
success: false,
error: `Window "${windowId}" is not allowed to ${operation} "${key}"`
};
}
}
}
return { success: true };
}
}
2. SubscriptionManager - 订阅管理器
class SubscriptionManager {
private subscriptions: Map<string, Set<string>> = new Map(); // key -> windowIds
private readonly MAX_SUBSCRIPTIONS_PER_KEY = 100;
subscribe(windowId: string, keys: string[]): void {
keys.forEach(key => {
if (!this.subscriptions.has(key)) {
this.subscriptions.set(key, new Set());
}
const subscribers = this.subscriptions.get(key)!;
subscribers.add(windowId);
// 内存泄漏检测
if (subscribers.size > this.MAX_SUBSCRIPTIONS_PER_KEY) {
this.logger.warn(
`High number of subscriptions (${subscribers.size}) for key: "${key}"`
);
}
});
}
}
3. TransactionManager - 事务管理器
class TransactionManager {
private buffers: Map<string, Map<string, TransactionOperation>> = new Map();
// 开启事务
start(windowId: string): void {
this.buffers.set(windowId, new Map());
}
// 提交事务
commit(windowId: string): Map<string, TransactionOperation> | undefined {
const buffer = this.buffers.get(windowId);
if (buffer) {
this.buffers.delete(windowId);
return buffer;
}
return undefined;
}
// 添加操作到事务缓冲区
add(windowId: string, key: string, op: TransactionOperation): boolean {
if (this.buffers.has(windowId)) {
this.buffers.get(windowId)!.set(key, op);
return true;
}
return false;
}
}
// 使用示例
messageBus.startTransaction('window-1');
messageBus.setData('user.name', 'Alice');
messageBus.setData('user.age', 25);
messageBus.setData('user.email', 'alice@example.com');
messageBus.commitTransaction('window-1'); // 批量提交
4. MessagePortTransport - 高性能传输层
class MessagePortTransport implements ITransport {
private portManager: PortManager;
registerWindow(windowId: string, window: BrowserWindow): void {
this.portManager.register(windowId, window, (msg, _port) => {
if (this.onMessage) {
this.onMessage(msg, windowId);
}
});
}
broadcast(message: any, windowIds?: string[]): number {
const serialized = typeof message === 'string' ? message : JSON.stringify(message);
return this.portManager.broadcast(serialized, windowIds);
}
}
MessagePort vs IPC 性能对比:
| 特性 | MessagePort | IPC |
|---|---|---|
| 延迟 | < 1ms | 2-5ms |
| 序列化开销 | 无(直接传递对象引用) | 有(JSON 序列化) |
| 内存使用 | 低 | 中等 |
| 并发性能 | 优秀 | 良好 |
| 适用场景 | 高频数据同步 | 一般通信 |
⚙️ 配置管理系统
class ConfigManager extends TypedEmitter<ConfigManagerEvents> {
private config: Record<string, any> = {};
private schema?: z.ZodType<any>;
// 支持点符号访问
get<T>(key: string, defaultValue?: T): T {
return this.getDeep(this.config, key) ?? defaultValue;
}
set(key: string, value: any): void {
// Zod 验证
if (this.schema) {
const tempConfig = JSON.parse(JSON.stringify(this.config));
this.setDeep(tempConfig, key, value);
const result = this.schema.safeParse(tempConfig);
if (!result.success) {
throw new Error(`Configuration validation failed: ${result.error.message}`);
}
}
const oldValue = this.get(key);
this.setDeep(this.config, key, value);
this.emit('change', key, value, oldValue);
if (this.autoSave) {
this.triggerSave();
}
}
}
// 使用示例
const configManager = new ConfigManager({
schema: z.object({
ui: z.object({
theme: z.enum(['light', 'dark']),
language: z.string(),
}),
window: z.object({
width: z.number().min(400),
height: z.number().min(300),
})
})
});
configManager.set('ui.theme', 'dark');
configManager.set('window.width', 1200);
🐛 调试与性能监控系统
PerformanceMonitor - 性能监控器
class PerformanceMonitor {
private static instance: PerformanceMonitor;
private metrics: Map<string, PerformanceMetric> = new Map();
startMeasure(id: string, name: string, metadata?: any): void {
this.metrics.set(id, {
name,
startTime: performance.now(),
metadata,
});
}
endMeasure(id: string, additionalMetadata?: any): number | undefined {
const metric = this.metrics.get(id);
if (!metric) return undefined;
const duration = performance.now() - metric.startTime;
this.logger.info(`[Performance] ${metric.name}: ${duration.toFixed(2)}ms`);
this.metrics.delete(id);
return duration;
}
}
// 使用示例
const monitor = PerformanceMonitor.getInstance();
monitor.startMeasure('window-creation', 'Create Main Window');
await windowManager.create({ name: 'main' });
monitor.endMeasure('window-creation'); // 输出: [Performance] Create Main Window: 45.23ms
🔄 生命周期管理器
class LifecycleManager {
async startup(): Promise<void> {
this.logger.info('Starting up Electron Toolkit services...');
// 1. 初始化 IpcRouter (通信基础)
this.ipcRouter = new IpcRouter({ logger: this.logger });
// 2. 初始化 MessageBus (跨窗口通信)
this.messageBus = new MessageBus({ logger: this.logger });
// 3. 初始化 WindowManager (核心窗口管理)
this.windowManager = new WindowManager({
...this.config,
ipcRouter: this.ipcRouter,
messageBus: this.messageBus,
});
await this.windowManager.ready();
// 4. 连接 MessageBus 到 WindowManager
this.messageBus.autoRegisterWindows(this.windowManager);
// 5. 启用调试模式
if (this.config.isDevelopment) {
DebugHelper.enableDebugMode();
DebugHelper.register('windowManager', this.windowManager);
DebugHelper.register('ipcRouter', this.ipcRouter);
DebugHelper.register('messageBus', this.messageBus);
}
this.isStarted = true;
}
async shutdown(): Promise<void> {
// 按初始化的逆序关闭
if (this.messageBus) this.messageBus.dispose();
if (this.windowManager) await this.windowManager.dispose();
if (this.ipcRouter) this.ipcRouter.dispose();
}
}
🚀 5分钟快速上手
安装
npm install electron-infra-kit
# 或
pnpm add electron-infra-kit
依赖要求: Electron >= 22.0.0, TypeScript >= 5.0.0, Node.js >= 18.0.0
主进程初始化
import { app } from 'electron';
import { createElectronToolkit } from 'electron-infra-kit';
app.whenReady().then(async () => {
// 🎉 一行代码初始化所有功能!
const { windowManager, ipcRouter, messageBus } = createElectronToolkit({
isDevelopment: process.env.NODE_ENV === 'development',
// 默认窗口配置
defaultConfig: {
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
},
// IPC 自动初始化
ipc: { autoInit: true },
// 启用状态持久化
enablePersistence: true,
// 性能监控(开发模式)
performanceMonitoring: true,
});
// 等待初始化完成
await windowManager.ready();
// 创建主窗口 - 就这么简单!
const mainWindowId = await windowManager.create({
name: 'main',
title: '我的应用',
width: 1024,
height: 768,
// 窗口分组
groups: ['main-windows'],
// 状态持久化
saveState: true,
// 生命周期钩子
onWillCreate: (options) => {
console.log('窗口即将创建:', options);
},
onDidCreate: (window, windowId) => {
console.log('窗口创建完成:', windowId);
},
});
console.log('主窗口ID:', mainWindowId);
});
预加载脚本配置
import { contextBridge } from 'electron';
import { ipcRendererBridge, setupMessageBus } from 'electron-infra-kit/preload';
// 配置 IPC 桥接器
ipcRendererBridge.configure({
apiKey: 'api', // 暴露为 window.api
// 可选:自定义通道配置
channels: {
invoke: 'ipc-invoke',
send: 'ipc-send'
}
});
// 暴露类型安全的 IPC API
const bindings = ipcRendererBridge.getBindings();
contextBridge.exposeInMainWorld('api', {
...bindings,
// 扩展事件监听
on: (channel: string, listener: Function) => {
const subscription = (event: any, ...args: any[]) => listener(event, ...args);
ipcRenderer.on(channel, subscription);
return () => ipcRenderer.removeListener(channel, subscription);
},
// 便捷方法
rendererToMain: (name: string, payload?: any) => {
return bindings.invoke(name, payload);
}
});
// 设置消息总线连接
setupMessageBus();
渲染进程使用
// 类型安全的 IPC 调用
const userInfo = await window.api.invoke('getUserInfo', { id: '123' });
console.log('用户信息:', userInfo);
// 跨窗口状态同步
await window.messageBus.setData('theme', 'dark');
await window.messageBus.setData('user', { name: '张三', role: 'admin' });
// 监听数据变化
const unsubscribe = window.messageBus.watch('theme', (newTheme) => {
console.log('主题已更改:', newTheme);
document.body.className = `theme-${newTheme}`;
});
// 权限控制
await window.messageBus.setPermission('adminData', {
readonly: true,
allowedWindows: ['admin-panel']
});
// 事件广播
await window.messageBus.emitEvent('user-login', { userId: '123' });
// 事务操作
window.messageBus.startTransaction();
await window.messageBus.setData('user.name', 'Alice');
await window.messageBus.setData('user.age', 25);
await window.messageBus.commitTransaction(); // 批量提交
就这么简单! 你现在拥有:
- ✅ 带状态持久化的智能窗口管理
- ✅ 类型安全的 IPC 通信系统
- ✅ 高性能跨窗口状态同步
- ✅ 企业级权限控制机制
- ✅ 完整的性能监控(开发模式)
- ✅ 事务支持和错误处理
🏗️ 架构设计亮点
分层架构设计
应用层 (开发者代码)
↓
核心层 (WindowManager, IpcRouter, MessageBus)
↓
支撑层 (WindowStore, PluginExecutor, DI Container)
↓
基础设施层 (ConfigManager, Logger, DebugHelper)
↓
Electron 运行时
设计模式应用
- 组合模式 - WindowStore 作为核心门面,职责清晰
- 插件系统 - 标准化的扩展机制,支持自定义功能
- 依赖注入 - IPC 处理器中的 DI 容器,解耦业务逻辑
- 事件驱动 - 完整的生命周期钩子,支持自定义扩展
- 消息代理 - MessageBus 的统一通信接口
💡 企业级应用场景深度解析
1. 多窗口 IDE 和代码编辑器
场景描述:类似 VS Code 的多窗口编辑器,需要管理主编辑器、侧边栏、终端、调试面板等多个窗口。
// 主编辑器窗口
const editorWindow = await windowManager.create({
name: 'editor-main',
title: '代码编辑器',
width: 1200,
height: 800,
groups: ['editor-group'],
// 插件扩展
plugins: [
new EditorPlugin(),
new SyntaxHighlightPlugin(),
],
// 生命周期钩子
onDidCreate: (window, windowId) => {
// 注册编辑器特定的 IPC 处理器
ipcRouter.addHandler(new IpcHandler(
'openFile',
'editor',
async (context, { filePath }) => {
const content = await fs.readFile(filePath, 'utf-8');
return { content, path: filePath };
},
z.object({ filePath: z.string() })
));
}
});
// 属性面板窗口
const propertiesWindow = await windowManager.create({
name: 'properties-panel',
title: '属性面板',
width: 300,
height: 600,
parent: editorWindow,
groups: ['editor-group', 'panels'],
// 窗口关系配置
alwaysOnTop: false,
skipTaskbar: true,
});
// 终端窗口
const terminalWindow = await windowManager.create({
name: 'terminal',
title: '集成终端',
width: 800,
height: 200,
groups: ['editor-group'],
// 自定义位置
x: 100,
y: 600,
});
// 跨窗口状态同步
await messageBus.setData('editor.currentFile', '/path/to/file.js');
await messageBus.setData('editor.cursorPosition', { line: 42, column: 10 });
await messageBus.setData('editor.selectedText', 'function example()');
// 监听文件变化,同步到所有窗口
messageBus.watch('editor.currentFile', (filePath) => {
// 更新所有编辑器窗口的标题
windowManager.getAllWindows().forEach(window => {
if (window.getTitle().includes('编辑器')) {
window.setTitle(`代码编辑器 - ${path.basename(filePath)}`);
}
});
});
// 批量窗口操作
await windowManager.focusGroup('editor-group'); // 聚焦所有编辑器窗口
await windowManager.hideGroup('panels'); // 隐藏所有面板
2. 设计工具和创意应用
场景描述:类似 Figma 或 Sketch 的设计工具,需要管理画布、图层面板、属性面板、资源库等。
// 主画布窗口
const canvasWindow = await windowManager.create({
name: 'canvas-main',
title: '设计画布',
width: 1000,
height: 800,
groups: ['design-workspace'],
// 自定义窗口配置
webPreferences: {
webgl: true, // 启用 WebGL 支持
experimentalFeatures: true,
},
});
// 图层面板
const layersWindow = await windowManager.create({
name: 'layers-panel',
title: '图层',
width: 250,
height: 400,
groups: ['design-workspace', 'panels'],
// 窗口停靠
dockTo: 'right',
dockTarget: canvasWindow,
});
// 属性面板
const propertiesWindow = await windowManager.create({
name: 'properties-panel',
title: '属性',
width: 280,
height: 500,
groups: ['design-workspace', 'panels'],
});
// 设计状态同步
await messageBus.setData('design.selectedLayers', [
{ id: 'layer-1', name: '背景', type: 'rectangle' },
{ id: 'layer-2', name: '标题', type: 'text' }
]);
await messageBus.setData('design.canvasZoom', 1.5);
await messageBus.setData('design.canvasOffset', { x: 100, y: 50 });
// 权限控制 - 只有画布窗口可以修改选中图层
await messageBus.setPermission('design.selectedLayers', {
allowedWindows: ['canvas-main']
});
// 实时协作支持
messageBus.watch('design.selectedLayers', (layers) => {
// 广播选中状态到所有面板
layers.forEach(layer => {
messageBus.emitEvent('layer-selected', {
layerId: layer.id,
timestamp: Date.now()
});
});
});
// 撤销/重做系统
class DesignHistoryManager {
private history: any[] = [];
private currentIndex = -1;
async executeCommand(command: any) {
// 执行命令
await this.applyCommand(command);
// 添加到历史记录
this.history = this.history.slice(0, this.currentIndex + 1);
this.history.push(command);
this.currentIndex++;
// 同步历史状态
await messageBus.setData('design.canUndo', this.currentIndex >= 0);
await messageBus.setData('design.canRedo', this.currentIndex < this.history.length - 1);
}
async undo() {
if (this.currentIndex >= 0) {
const command = this.history[this.currentIndex];
await this.revertCommand(command);
this.currentIndex--;
await messageBus.setData('design.canUndo', this.currentIndex >= 0);
await messageBus.setData('design.canRedo', true);
}
}
}
3. 企业应用和管理系统
场景描述:复杂的企业 ERP/CRM 系统,需要管理多个业务模块窗口。
// 主控制台
const dashboardWindow = await windowManager.create({
name: 'dashboard',
title: '企业管理控制台',
width: 1400,
height: 900,
groups: ['main-workspace'],
// 角色权限配置
metadata: {
requiredRole: 'admin',
permissions: ['dashboard.view', 'users.manage']
}
});
// 用户管理窗口
const userManagementWindow = await windowManager.create({
name: 'user-management',
title: '用户管理',
width: 800,
height: 600,
groups: ['management-modules'],
// 条件创建 - 只有管理员可以打开
condition: async () => {
const user = await messageBus.getData('auth.currentUser');
return user?.role === 'admin';
}
});
// 报表窗口
const reportsWindow = await windowManager.create({
name: 'reports',
title: '数据报表',
width: 1000,
height: 700,
groups: ['analysis-modules'],
});
// 企业级权限管理
await messageBus.setData('auth.currentUser', {
id: 'user-123',
name: '张三',
role: 'admin',
permissions: ['users.read', 'users.write', 'reports.read'],
department: 'IT部门'
});
// 分级权限控制
await messageBus.setPermission('users.list', {
allowedWindows: ['dashboard', 'user-management'],
customValidator: async (windowId, operation, payload) => {
const user = await messageBus.getData('auth.currentUser');
return user.permissions.includes('users.read');
}
});
await messageBus.setPermission('financial.data', {
readonly: true,
allowedWindows: ['reports'],
customValidator: async (windowId) => {
const user = await messageBus.getData('auth.currentUser');
return user.department === '财务部' || user.role === 'admin';
}
});
// 业务流程状态同步
await messageBus.setData('workflow.currentStep', {
processId: 'approval-001',
step: 'manager-review',
assignee: 'manager-456',
deadline: '2024-01-15T10:00:00Z'
});
// 实时通知系统
messageBus.watch('notifications.new', (notification) => {
// 根据通知类型决定显示窗口
switch (notification.type) {
case 'urgent':
windowManager.focus('dashboard');
break;
case 'approval-required':
windowManager.create({
name: `approval-${notification.id}`,
title: '审批请求',
width: 500,
height: 400,
modal: true,
parent: dashboardWindow
});
break;
}
});
// 数据缓存和离线支持
class EnterpriseDataManager {
private cache = new Map();
async getData(key: string, options?: { useCache?: boolean }) {
if (options?.useCache && this.cache.has(key)) {
return this.cache.get(key);
}
try {
const data = await this.fetchFromServer(key);
this.cache.set(key, data);
// 同步到消息总线
await messageBus.setData(`cache.${key}`, data);
return data;
} catch (error) {
// 离线模式:返回缓存数据
if (this.cache.has(key)) {
console.warn('使用缓存数据(离线模式)');
return this.cache.get(key);
}
throw error;
}
}
}
4. 协作应用和实时通信工具
场景描述:类似 Slack 或 Teams 的协作工具,需要管理聊天窗口、视频通话、文件共享等。
// 主聊天窗口
const chatMainWindow = await windowManager.create({
name: 'chat-main',
title: 'TeamChat',
width: 900,
height: 600,
groups: ['chat-workspace'],
});
// 视频通话窗口
const videoCallWindow = await windowManager.create({
name: 'video-call',
title: '视频通话',
width: 800,
height: 600,
groups: ['communication'],
// 通话专用配置
webPreferences: {
webSecurity: false, // 允许摄像头访问
allowRunningInsecureContent: true,
},
// 始终置顶
alwaysOnTop: true,
});
// 文件共享窗口
const fileShareWindow = await windowManager.create({
name: 'file-share',
title: '文件共享',
width: 400,
height: 500,
groups: ['utilities'],
});
// 实时消息同步
await messageBus.setData('chat.activeChannel', {
id: 'channel-123',
name: '开发团队',
members: ['user-1', 'user-2', 'user-3'],
unreadCount: 5
});
// 消息历史
await messageBus.setData('chat.messages', [
{
id: 'msg-1',
channelId: 'channel-123',
senderId: 'user-1',
content: '大家好!',
timestamp: Date.now() - 60000,
type: 'text'
},
{
id: 'msg-2',
channelId: 'channel-123',
senderId: 'user-2',
content: '项目进展如何?',
timestamp: Date.now() - 30000,
type: 'text'
}
]);
// 实时消息推送
messageBus.watch('chat.newMessage', (message) => {
// 更新未读计数
const currentChannel = messageBus.getData('chat.activeChannel');
if (message.channelId === currentChannel.id) {
// 当前频道,直接显示
messageBus.emitEvent('ui.showMessage', message);
} else {
// 其他频道,更新未读计数
messageBus.emitEvent('ui.updateUnreadCount', {
channelId: message.channelId,
increment: 1
});
}
// 系统通知
if (message.mentions?.includes(getCurrentUserId())) {
new Notification(`${message.senderName} 提到了你`, {
body: message.content,
icon: '/assets/app-icon.png'
});
}
});
// 在线状态同步
await messageBus.setData('presence.users', {
'user-1': { status: 'online', lastSeen: Date.now() },
'user-2': { status: 'away', lastSeen: Date.now() - 300000 },
'user-3': { status: 'busy', lastSeen: Date.now() - 60000 }
});
// 视频通话状态管理
class VideoCallManager {
async startCall(participants: string[]) {
// 创建通话窗口
const callWindow = await windowManager.create({
name: `call-${Date.now()}`,
title: `通话 - ${participants.length} 人`,
width: 800,
height: 600,
groups: ['active-calls'],
alwaysOnTop: true,
});
// 同步通话状态
await messageBus.setData('call.active', {
id: `call-${Date.now()}`,
participants,
startTime: Date.now(),
windowId: callWindow
});
// 通知其他窗口
await messageBus.emitEvent('call.started', {
participants,
windowId: callWindow
});
}
async endCall(callId: string) {
const call = await messageBus.getData('call.active');
if (call && call.id === callId) {
// 关闭通话窗口
windowManager.close(call.windowId);
// 清除通话状态
await messageBus.deleteData('call.active');
// 通知结束
await messageBus.emitEvent('call.ended', { callId });
}
}
}
5. 游戏开发工具和编辑器
场景描述:游戏引擎编辑器,需要管理场景编辑器、资源管理器、属性面板、预览窗口等。
// 场景编辑器
const sceneEditorWindow = await windowManager.create({
name: 'scene-editor',
title: '场景编辑器',
width: 1200,
height: 800,
groups: ['game-editor'],
// 游戏开发专用配置
webPreferences: {
webgl: true,
experimentalFeatures: true,
backgroundThrottling: false, // 禁用后台节流
}
});
// 资源管理器
const assetBrowserWindow = await windowManager.create({
name: 'asset-browser',
title: '资源管理器',
width: 300,
height: 600,
groups: ['game-editor', 'panels'],
});
// 游戏预览窗口
const gamePreviewWindow = await windowManager.create({
name: 'game-preview',
title: '游戏预览',
width: 800,
height: 600,
groups: ['game-editor'],
// 预览窗口特殊配置
webPreferences: {
webSecurity: false,
allowRunningInsecureContent: true,
}
});
// 游戏状态同步
await messageBus.setData('game.currentScene', {
id: 'scene-001',
name: '主菜单场景',
objects: [
{ id: 'obj-1', type: 'sprite', x: 100, y: 200 },
{ id: 'obj-2', type: 'text', x: 400, y: 300, content: '开始游戏' }
]
});
await messageBus.setData('game.selectedObjects', ['obj-1']);
// 实时预览同步
messageBus.watch('game.currentScene', (scene) => {
// 同步到预览窗口
messageBus.emitEvent('preview.updateScene', scene);
});
messageBus.watch('game.selectedObjects', (objectIds) => {
// 高亮选中的对象
messageBus.emitEvent('editor.highlightObjects', objectIds);
});
// 性能监控
class GameEditorPerformanceMonitor {
private frameCount = 0;
private lastTime = performance.now();
startMonitoring() {
const monitor = () => {
this.frameCount++;
const currentTime = performance.now();
if (currentTime - this.lastTime >= 1000) {
const fps = this.frameCount;
this.frameCount = 0;
this.lastTime = currentTime;
// 同步 FPS 到所有窗口
messageBus.setData('performance.fps', fps);
// 内存使用情况
const memoryUsage = process.memoryUsage();
messageBus.setData('performance.memory', {
heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024),
heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024),
external: Math.round(memoryUsage.external / 1024 / 1024)
});
}
requestAnimationFrame(monitor);
};
requestAnimationFrame(monitor);
}
}
6. 数据分析和可视化工具
场景描述:类似 Tableau 的数据分析工具,需要管理数据源、图表编辑器、仪表板等。
// 主仪表板
const dashboardWindow = await windowManager.create({
name: 'dashboard-main',
title: '数据仪表板',
width: 1400,
height: 900,
groups: ['analytics-workspace'],
});
// 数据源管理器
const dataSourceWindow = await windowManager.create({
name: 'data-sources',
title: '数据源',
width: 350,
height: 500,
groups: ['analytics-workspace', 'panels'],
});
// 图表编辑器
const chartEditorWindow = await windowManager.create({
name: 'chart-editor',
title: '图表编辑器',
width: 600,
height: 400,
groups: ['analytics-workspace'],
});
// 数据状态管理
await messageBus.setData('analytics.dataSources', [
{
id: 'ds-1',
name: '销售数据',
type: 'mysql',
connection: { host: 'localhost', database: 'sales' },
tables: ['orders', 'customers', 'products']
},
{
id: 'ds-2',
name: 'Web Analytics',
type: 'api',
endpoint: 'https://api.analytics.com/data'
}
]);
await messageBus.setData('analytics.currentDataset', {
sourceId: 'ds-1',
query: 'SELECT * FROM orders WHERE date >= "2024-01-01"',
columns: ['order_id', 'customer_id', 'amount', 'date'],
rowCount: 15420
});
// 图表配置同步
await messageBus.setData('analytics.charts', [
{
id: 'chart-1',
type: 'bar',
title: '月度销售额',
dataSource: 'ds-1',
config: {
xAxis: 'date',
yAxis: 'amount',
groupBy: 'month'
}
},
{
id: 'chart-2',
type: 'pie',
title: '产品类别分布',
dataSource: 'ds-1',
config: {
dimension: 'category',
measure: 'count'
}
}
]);
// 实时数据更新
class DataAnalyticsManager {
private updateInterval: NodeJS.Timeout | null = null;
startRealTimeUpdates() {
this.updateInterval = setInterval(async () => {
try {
// 获取最新数据
const latestData = await this.fetchLatestData();
// 更新数据集
await messageBus.setData('analytics.liveData', latestData);
// 触发图表更新
await messageBus.emitEvent('charts.refresh', {
timestamp: Date.now(),
dataPoints: latestData.length
});
} catch (error) {
console.error('数据更新失败:', error);
await messageBus.emitEvent('analytics.error', {
type: 'data-update-failed',
message: error.message
});
}
}, 30000); // 每30秒更新一次
}
stopRealTimeUpdates() {
if (this.updateInterval) {
clearInterval(this.updateInterval);
this.updateInterval = null;
}
}
}
// 导出和分享功能
messageBus.watch('analytics.exportRequest', async (request) => {
const { format, chartIds, options } = request;
// 创建导出进度窗口
const exportWindow = await windowManager.create({
name: 'export-progress',
title: '导出进度',
width: 400,
height: 200,
modal: true,
parent: dashboardWindow
});
try {
// 执行导出
const result = await this.exportCharts(chartIds, format, options);
// 关闭进度窗口
windowManager.close(exportWindow);
// 显示结果
await messageBus.emitEvent('export.completed', {
filePath: result.filePath,
fileSize: result.fileSize
});
} catch (error) {
windowManager.close(exportWindow);
await messageBus.emitEvent('export.failed', {
error: error.message
});
}
});
这些企业级应用场景展示了 Electron Infra Kit 在复杂应用中的强大能力:
核心优势:
- 统一的窗口管理 - 无论多少窗口都能轻松管理
- 实时状态同步 - 所有窗口保持数据一致性
- 企业级权限控制 - 细粒度的访问控制
- 高性能通信 - MessageChannel 确保低延迟
- 完善的错误处理 - 生产环境的稳定性保障
- 可扩展架构 - 插件系统支持自定义功能
🎨 Vue 3 深度集成示例
项目提供了完整的 Vue 3 Composable Hook 系统,让前端开发更加便捷和响应式:
核心 Hook 架构
// 主入口 Hook - 整合所有功能
export function useWindowDataSync() {
const core = useWindowDataSyncCore(); // 核心状态管理
const operations = useWindowDataOperations(); // 数据操作
const permissions = useWindowDataPermissions(); // 权限管理
const events = useWindowDataEvents(); // 事件处理
const utils = useWindowUtils(); // 工具方法
return {
// 响应式状态
localDataCache: core.localDataCache,
isInitialized: core.isInitialized,
// 数据操作
setData: operations.setData,
getData: operations.getData,
deleteData: operations.deleteData,
// 权限控制
setPermission: permissions.setPermission,
// 事件系统
emitEvent: events.emitEvent,
onEvent: events.onEvent,
onChange: events.onChange,
// 工具方法
getDebugInfo: utils.getDebugInfo,
cleanup: core.cleanup,
};
}
1. 核心状态管理 Hook
// useWindowDataSyncCore.ts
export function useWindowDataSyncCore() {
// 响应式本地数据缓存
const localDataCache = reactive<Record<string, any>>({});
const isInitialized = ref(false);
const changeListeners = ref(new Set<Function>());
const eventListeners = ref(new Set<Function>());
// MessagePort 连接管理
let messagePort: MessagePort | null = null;
let isConnecting = false;
const initialize = async (): Promise<void> => {
if (isInitialized.value || isConnecting) return;
isConnecting = true;
try {
// 请求 MessagePort 连接
const response = await window.api.invoke('window-data-sync-init', {
windowId: getCurrentWindowId()
});
if (response.success && response.port) {
messagePort = response.port;
// 监听消息
messagePort.onmessage = (event) => {
const { type, key, value, eventName, eventPayload } = event.data;
switch (type) {
case 'data-changed':
// 更新本地缓存
if (value === undefined) {
delete localDataCache[key];
} else {
localDataCache[key] = value;
}
// 触发变更监听器
changeListeners.value.forEach(listener => {
try {
listener(key, value);
} catch (error) {
console.error('Change listener error:', error);
}
});
break;
case 'event':
// 触发事件监听器
eventListeners.value.forEach(listener => {
try {
listener(eventName, eventPayload);
} catch (error) {
console.error('Event listener error:', error);
}
});
break;
}
};
// 获取初始数据
const initialData = response.initialData || {};
Object.assign(localDataCache, initialData);
isInitialized.value = true;
console.log('Window data sync initialized');
}
} catch (error) {
console.error('Failed to initialize window data sync:', error);
} finally {
isConnecting = false;
}
};
// 组件挂载时自动初始化
onMounted(() => {
initialize();
});
// 组件卸载时清理
onUnmounted(() => {
cleanup();
});
const cleanup = () => {
if (messagePort) {
messagePort.close();
messagePort = null;
}
changeListeners.value.clear();
eventListeners.value.clear();
isInitialized.value = false;
};
return {
localDataCache: readonly(localDataCache),
isInitialized: readonly(isInitialized),
changeListeners,
eventListeners,
initialize,
getCurrentWindowId,
cleanup
};
}
2. 数据操作 Hook
// useWindowDataOperations.ts
export function useWindowDataOperations(
localDataCache: any,
getCurrentWindowId: () => string
) {
const getLocalData = <T>(key: string): T | undefined => {
return localDataCache[key];
};
const getData = async <T>(key: string): Promise<T | undefined> => {
try {
const response = await window.api.invoke('window-data-sync-get', {
windowId: getCurrentWindowId(),
key
});
return response.success ? response.value : undefined;
} catch (error) {
console.error('Failed to get data:', error);
return getLocalData<T>(key); // 降级到本地缓存
}
};
const setData = async <T>(key: string, value: T): Promise<boolean> => {
try {
const response = await window.api.invoke('window-data-sync-set', {
windowId: getCurrentWindowId(),
key,
value
});
if (response.success) {
// 立即更新本地缓存(乐观更新)
localDataCache[key] = value;
return true;
} else {
console.error('Failed to set data:', response.error);
return false;
}
} catch (error) {
console.error('Failed to set data:', error);
return false;
}
};
const deleteData = async (key: string): Promise<boolean> => {
try {
const response = await window.api.invoke('window-data-sync-delete', {
windowId: getCurrentWindowId(),
key
});
if (response.success) {
// 立即从本地缓存删除
delete localDataCache[key];
return true;
} else {
console.error('Failed to delete data:', response.error);
return false;
}
} catch (error) {
console.error('Failed to delete data:', error);
return false;
}
};
const clearData = async (): Promise<boolean> => {
try {
const response = await window.api.invoke('window-data-sync-clear', {
windowId: getCurrentWindowId()
});
if (response.success) {
// 清空本地缓存
Object.keys(localDataCache).forEach(key => {
delete localDataCache[key];
});
return true;
}
return false;
} catch (error) {
console.error('Failed to clear data:', error);
return false;
}
};
return {
getLocalData,
getData,
setData,
deleteData,
clearData
};
}
3. 完整的 Vue 组件示例
<template>
<div class="data-sync-demo">
<!-- 初始化状态 -->
<div v-if="!isInitialized" class="loading">
<el-loading-spinner />
<p>正在初始化数据同步...</p>
</div>
<!-- 主界面 -->
<div v-else class="main-content">
<!-- 当前主题显示 -->
<el-card class="theme-card">
<template #header>
<span>当前主题</span>
</template>
<div :class="`theme-${localDataCache.theme || 'light'}`">
<h3>主题: {{ localDataCache.theme || 'light' }}</h3>
<p>这个主题会在所有窗口间同步</p>
</div>
</el-card>
<!-- 主题切换 -->
<el-card class="controls-card">
<template #header>
<span>主题控制</span>
</template>
<el-radio-group v-model="selectedTheme" @change="changeTheme">
<el-radio-button label="light">亮色主题</el-radio-button>
<el-radio-button label="dark">暗色主题</el-radio-button>
<el-radio-button label="blue">蓝色主题</el-radio-button>
</el-radio-group>
</el-card>
<!-- 用户信息 -->
<el-card class="user-card">
<template #header>
<span>用户信息</span>
</template>
<div v-if="localDataCache.user">
<p><strong>姓名:</strong> {{ localDataCache.user.name }}</p>
<p><strong>角色:</strong> {{ localDataCache.user.role }}</p>
<p><strong>部门:</strong> {{ localDataCache.user.department }}</p>
</div>
<el-button @click="updateUserInfo" type="primary">更新用户信息</el-button>
</el-card>
<!-- 计数器演示 -->
<el-card class="counter-card">
<template #header>
<span>计数器 (跨窗口同步)</span>
</template>
<div class="counter-display">
<h2>{{ localDataCache.counter || 0 }}</h2>
<div class="counter-controls">
<el-button @click="decrementCounter" :disabled="(localDataCache.counter || 0) <= 0">
-1
</el-button>
<el-button @click="incrementCounter">+1</el-button>
<el-button @click="resetCounter" type="danger">重置</el-button>
</div>
</div>
</el-card>
<!-- 权限控制演示 -->
<el-card class="permissions-card">
<template #header>
<span>权限控制演示</span>
</template>
<div class="permission-controls">
<el-button @click="setReadOnlyData" type="warning">
设置只读数据
</el-button>
<el-button @click="setWindowRestrictedData" type="info">
设置窗口限制数据
</el-button>
<el-button @click="tryModifyRestrictedData" type="danger">
尝试修改受限数据
</el-button>
</div>
<div v-if="localDataCache.restrictedData" class="restricted-data">
<h4>受限数据:</h4>
<pre>{{ JSON.stringify(localDataCache.restrictedData, null, 2) }}</pre>
</div>
</el-card>
<!-- 事件广播演示 -->
<el-card class="events-card">
<template #header>
<span>事件广播</span>
</template>
<div class="event-controls">
<el-input
v-model="eventMessage"
placeholder="输入广播消息"
style="width: 300px; margin-right: 10px;"
/>
<el-button @click="broadcastMessage" type="success">
广播消息
</el-button>
</div>
<div class="event-log">
<h4>事件日志:</h4>
<div
v-for="(event, index) in eventLog"
:key="index"
class="event-item"
>
<span class="event-time">{{ formatTime(event.timestamp) }}</span>
<span class="event-name">{{ event.name }}</span>
<span class="event-payload">{{ JSON.stringify(event.payload) }}</span>
</div>
</div>
</el-card>
<!-- 调试信息 -->
<el-card class="debug-card">
<template #header>
<span>调试信息</span>
</template>
<el-button @click="showDebugInfo" type="info">显示调试信息</el-button>
<div v-if="debugInfo" class="debug-content">
<pre>{{ JSON.stringify(debugInfo, null, 2) }}</pre>
</div>
</el-card>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { ElMessage, ElNotification } from 'element-plus';
import { useWindowDataSync } from '@/hooks/useWindowDataSync';
// 使用数据同步 Hook
const {
localDataCache,
isInitialized,
setData,
getData,
setPermission,
emitEvent,
onEvent,
onChange,
getDebugInfo,
} = useWindowDataSync();
// 响应式数据
const selectedTheme = ref('light');
const eventMessage = ref('');
const eventLog = ref<Array<{ name: string; payload: any; timestamp: number }>>([]);
const debugInfo = ref(null);
// 计算属性
const currentTheme = computed(() => localDataCache.theme || 'light');
// 主题切换
const changeTheme = async (theme: string) => {
const success = await setData('theme', theme);
if (success) {
ElMessage.success(`主题已切换为: ${theme}`);
} else {
ElMessage.error('主题切换失败');
}
};
// 更新用户信息
const updateUserInfo = async () => {
const userInfo = {
name: '张三',
role: 'developer',
department: '技术部',
lastLogin: new Date().toISOString(),
};
const success = await setData('user', userInfo);
if (success) {
ElMessage.success('用户信息已更新');
}
};
// 计数器操作
const incrementCounter = async () => {
const current = localDataCache.counter || 0;
await setData('counter', current + 1);
};
const decrementCounter = async () => {
const current = localDataCache.counter || 0;
if (current > 0) {
await setData('counter', current - 1);
}
};
const resetCounter = async () => {
await setData('counter', 0);
ElMessage.info('计数器已重置');
};
// 权限控制演示
const setReadOnlyData = async () => {
// 设置数据
await setData('restrictedData', {
type: 'readonly',
value: '这是只读数据',
timestamp: Date.now()
});
// 设置为只读
await setPermission('restrictedData', { readonly: true });
ElMessage.info('已设置只读数据');
};
const setWindowRestrictedData = async () => {
await setData('windowRestrictedData', {
type: 'window-restricted',
value: '这是窗口限制数据',
timestamp: Date.now()
});
// 只允许主窗口访问
await setPermission('windowRestrictedData', {
allowedWindows: ['main-window']
});
ElMessage.info('已设置窗口限制数据');
};
const tryModifyRestrictedData = async () => {
const success = await setData('restrictedData', {
type: 'modified',
value: '尝试修改只读数据',
timestamp: Date.now()
});
if (!success) {
ElMessage.error('无法修改只读数据');
}
};
// 事件广播
const broadcastMessage = async () => {
if (!eventMessage.value.trim()) {
ElMessage.warning('请输入广播消息');
return;
}
await emitEvent('user-message', {
message: eventMessage.value,
sender: localDataCache.user?.name || '匿名用户',
timestamp: Date.now()
});
eventMessage.value = '';
ElMessage.success('消息已广播');
};
// 显示调试信息
const showDebugInfo = async () => {
debugInfo.value = await getDebugInfo();
};
// 格式化时间
const formatTime = (timestamp: number) => {
return new Date(timestamp).toLocaleTimeString();
};
// 监听数据变化
onChange((key, value) => {
console.log(`数据变化: ${key} =`, value);
// 特殊处理主题变化
if (key === 'theme') {
selectedTheme.value = value;
document.body.className = `theme-${value}`;
}
});
// 监听事件
onEvent((eventName, payload) => {
console.log(`收到事件: ${eventName}`, payload);
// 添加到事件日志
eventLog.value.unshift({
name: eventName,
payload,
timestamp: Date.now()
});
// 限制日志长度
if (eventLog.value.length > 50) {
eventLog.value = eventLog.value.slice(0, 50);
}
// 显示通知
if (eventName === 'user-message') {
ElNotification({
title: '收到广播消息',
message: `${payload.sender}: ${payload.message}`,
type: 'info',
duration: 3000
});
}
});
// 组件挂载时的初始化
onMounted(() => {
// 设置初始主题
if (localDataCache.theme) {
selectedTheme.value = localDataCache.theme;
document.body.className = `theme-${localDataCache.theme}`;
}
});
</script>
<style scoped>
.data-sync-demo {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
.loading {
text-align: center;
padding: 50px;
}
.main-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 20px;
}
.theme-card, .controls-card, .user-card,
.counter-card, .permissions-card, .events-card, .debug-card {
margin-bottom: 20px;
}
.theme-light {
background: #f5f5f5;
color: #333;
padding: 15px;
border-radius: 8px;
}
.theme-dark {
background: #2d2d2d;
color: #fff;
padding: 15px;
border-radius: 8px;
}
.theme-blue {
background: #e3f2fd;
color: #1976d2;
padding: 15px;
border-radius: 8px;
}
.counter-display {
text-align: center;
}
.counter-display h2 {
font-size: 3em;
margin: 20px 0;
color: #409eff;
}
.counter-controls {
display: flex;
justify-content: center;
gap: 10px;
}
.permission-controls {
display: flex;
gap: 10px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.restricted-data {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-top: 10px;
}
.event-controls {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.event-log {
max-height: 200px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px;
}
.event-item {
display: flex;
gap: 10px;
padding: 5px 0;
border-bottom: 1px solid #eee;
font-size: 12px;
}
.event-time {
color: #666;
min-width: 80px;
}
.event-name {
font-weight: bold;
color: #409eff;
min-width: 120px;
}
.event-payload {
color: #333;
flex: 1;
}
.debug-content {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
margin-top: 10px;
max-height: 300px;
overflow-y: auto;
}
/* 响应式设计 */
@media (max-width: 768px) {
.main-content {
grid-template-columns: 1fr;
}
.permission-controls {
flex-direction: column;
}
.event-controls {
flex-direction: column;
align-items: stretch;
}
.event-controls .el-input {
width: 100% !important;
margin-bottom: 10px;
}
}
</style>
4. 高级特性演示
// 复杂数据结构同步
const syncComplexData = async () => {
await setData('project', {
id: 'proj-001',
name: '企业管理系统',
modules: [
{ id: 'mod-1', name: '用户管理', status: 'active' },
{ id: 'mod-2', name: '权限管理', status: 'development' },
{ id: 'mod-3', name: '报表系统', status: 'planning' }
],
team: {
lead: { name: '张三', role: 'tech-lead' },
developers: [
{ name: '李四', role: 'senior-dev' },
{ name: '王五', role: 'junior-dev' }
]
},
timeline: {
start: '2024-01-01',
end: '2024-06-30',
milestones: [
{ name: 'Alpha 版本', date: '2024-03-01' },
{ name: 'Beta 版本', date: '2024-05-01' },
{ name: '正式发布', date: '2024-06-30' }
]
}
});
};
// 批量操作演示
const batchOperations = async () => {
// 开启事务
messageBus.startTransaction();
try {
// 批量设置数据
await setData('user.profile.name', '张三');
await setData('user.profile.email', 'zhangsan@example.com');
await setData('user.preferences.theme', 'dark');
await setData('user.preferences.language', 'zh-CN');
await setData('user.permissions', ['read', 'write', 'admin']);
// 提交事务
await messageBus.commitTransaction();
ElMessage.success('批量操作完成');
} catch (error) {
// 回滚事务
await messageBus.rollbackTransaction();
ElMessage.error('批量操作失败,已回滚');
}
};
// 条件监听
const setupConditionalListeners = () => {
// 只在特定条件下触发
onChange((key, value) => {
if (key.startsWith('user.') && localDataCache.user?.role === 'admin') {
console.log('管理员数据变化:', key, value);
// 记录管理员操作日志
emitEvent('admin-action', {
action: 'data-change',
key,
value,
timestamp: Date.now()
});
}
});
// 监听特定事件类型
onEvent((eventName, payload) => {
if (eventName === 'system-alert') {
ElNotification({
title: '系统警告',
message: payload.message,
type: 'warning',
duration: 0, // 不自动关闭
});
}
});
};
这个完整的 Vue 3 集成示例展示了:
核心特性:
- 响应式数据同步 - 所有数据变化自动反映到 UI
- 类型安全 - 完整的 TypeScript 支持
- 权限控制 - 字段级和窗口级权限管理
- 事件系统 - 跨窗口事件广播和监听
- 事务支持 - 批量操作和回滚机制
- 错误处理 - 优雅的错误处理和用户反馈
- 性能优化 - 本地缓存和乐观更新
- 调试支持 - 完整的调试信息和日志
📊 性能优化与技术亮点
🚀 MessageChannel vs IPC 性能对比
| 指标 | MessageChannel | 传统 IPC | 性能提升 |
|---|---|---|---|
| 延迟 | < 1ms | 2-5ms | 5倍提升 |
| 吞吐量 | 10,000+ msg/s | 2,000 msg/s | 5倍提升 |
| 序列化开销 | 无(直接传递对象引用) | 有(JSON 序列化) | 零开销 |
| 内存使用 | 低 | 中等 | 30% 减少 |
| CPU 使用 | 低 | 中等 | 40% 减少 |
| 并发性能 | 优秀 | 良好 | 显著提升 |
⚡ 核心性能优化技术
1. 本地缓存策略
class LocalCacheManager {
private cache = new Map<string, { value: any; timestamp: number }>();
private readonly CACHE_TTL = 5000; // 5秒缓存
get(key: string): any {
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
return cached.value; // 缓存命中,无需 IPC 调用
}
return undefined;
}
set(key: string, value: any): void {
this.cache.set(key, { value, timestamp: Date.now() });
}
// 智能预取
prefetch(keys: string[]): void {
keys.forEach(key => {
if (!this.cache.has(key)) {
// 异步预取数据
this.fetchData(key).then(value => this.set(key, value));
}
});
}
}
// 使用示例
const cacheManager = new LocalCacheManager();
// 读取数据时优先使用缓存
const getData = async (key: string) => {
let value = cacheManager.get(key);
if (value === undefined) {
value = await window.api.invoke('getData', { key });
cacheManager.set(key, value);
}
return value;
};
2. 事件节流和防抖
class PerformanceOptimizer {
private throttleTimers = new Map<string, number>();
private debounceTimers = new Map<string, NodeJS.Timeout>();
// 节流:限制执行频率
throttle<T extends (...args: any[]) => any>(
key: string,
fn: T,
interval: number = 16 // 60fps
): T {
return ((...args: any[]) => {
const now = Date.now();
const lastTime = this.throttleTimers.get(key) || 0;
if (now - lastTime >= interval) {
this.throttleTimers.set(key, now);
return fn(...args);
}
}) as T;
}
// 防抖:延迟执行
debounce<T extends (...args: any[]) => any>(
key: string,
fn: T,
delay: number = 300
): T {
return ((...args: any[]) => {
const existingTimer = this.debounceTimers.get(key);
if (existingTimer) {
clearTimeout(existingTimer);
}
const timer = setTimeout(() => {
this.debounceTimers.delete(key);
fn(...args);
}, delay);
this.debounceTimers.set(key, timer);
}) as T;
}
}
// 使用示例
const optimizer = new PerformanceOptimizer();
// 高频鼠标移动事件节流
const handleMouseMove = optimizer.throttle('mouse-move', (event) => {
messageBus.setData('cursor.position', { x: event.clientX, y: event.clientY });
}, 16);
// 搜索输入防抖
const handleSearch = optimizer.debounce('search', (query) => {
messageBus.setData('search.query', query);
}, 300);
3. 内存管理和清理
class MemoryManager {
private subscriptions = new Set<() => void>();
private intervals = new Set<NodeJS.Timeout>();
private observers = new Set<MutationObserver>();
// 统一的订阅管理
addSubscription(unsubscribe: () => void): void {
this.subscriptions.add(unsubscribe);
}
// 定时器管理
setInterval(callback: () => void, ms: number): NodeJS.Timeout {
const timer = setInterval(callback, ms);
this.intervals.add(timer);
return timer;
}
// 观察者管理
observe(target: Node, options: MutationObserverInit, callback: MutationCallback): MutationObserver {
const observer = new MutationObserver(callback);
observer.observe(target, options);
this.observers.add(observer);
return observer;
}
// 统一清理
cleanup(): void {
// 清理订阅
this.subscriptions.forEach(unsubscribe => {
try {
unsubscribe();
} catch (error) {
console.warn('Cleanup subscription error:', error);
}
});
this.subscriptions.clear();
// 清理定时器
this.intervals.forEach(timer => clearInterval(timer));
this.intervals.clear();
// 清理观察者
this.observers.forEach(observer => observer.disconnect());
this.observers.clear();
}
// 内存使用监控
monitorMemoryUsage(): void {
if ('memory' in performance) {
const memory = (performance as any).memory;
console.log('Memory Usage:', {
used: Math.round(memory.usedJSHeapSize / 1024 / 1024) + ' MB',
total: Math.round(memory.totalJSHeapSize / 1024 / 1024) + ' MB',
limit: Math.round(memory.jsHeapSizeLimit / 1024 / 1024) + ' MB'
});
}
}
}
// Vue 组件中使用
export default {
setup() {
const memoryManager = new MemoryManager();
// 添加订阅
const unsubscribe = messageBus.watch('data', callback);
memoryManager.addSubscription(unsubscribe);
// 组件卸载时清理
onUnmounted(() => {
memoryManager.cleanup();
});
return { /* ... */ };
}
};
4. 批量操作优化
class BatchProcessor {
private batches = new Map<string, {
operations: Array<{ key: string; value: any; type: 'set' | 'delete' }>;
timer: NodeJS.Timeout;
}>();
private readonly BATCH_SIZE = 50;
private readonly BATCH_DELAY = 100; // 100ms
// 批量设置数据
batchSet(batchId: string, key: string, value: any): void {
this.addToBatch(batchId, { key, value, type: 'set' });
}
// 批量删除数据
batchDelete(batchId: string, key: string): void {
this.addToBatch(batchId, { key, value: undefined, type: 'delete' });
}
private addToBatch(batchId: string, operation: any): void {
let batch = this.batches.get(batchId);
if (!batch) {
batch = {
operations: [],
timer: setTimeout(() => this.processBatch(batchId), this.BATCH_DELAY)
};
this.batches.set(batchId, batch);
}
batch.operations.push(operation);
// 达到批量大小限制时立即处理
if (batch.operations.length >= this.BATCH_SIZE) {
clearTimeout(batch.timer);
this.processBatch(batchId);
}
}
private async processBatch(batchId: string): Promise<void> {
const batch = this.batches.get(batchId);
if (!batch) return;
this.batches.delete(batchId);
try {
// 批量发送到主进程
await window.api.invoke('batch-operations', {
operations: batch.operations
});
console.log(`Processed batch ${batchId} with ${batch.operations.length} operations`);
} catch (error) {
console.error('Batch processing failed:', error);
}
}
// 强制处理所有待处理批次
async flush(): Promise<void> {
const promises = Array.from(this.batches.keys()).map(batchId => {
const batch = this.batches.get(batchId);
if (batch) {
clearTimeout(batch.timer);
return this.processBatch(batchId);
}
});
await Promise.all(promises);
}
}
// 使用示例
const batchProcessor = new BatchProcessor();
// 批量更新用户界面状态
const updateUIState = (updates: Record<string, any>) => {
Object.entries(updates).forEach(([key, value]) => {
batchProcessor.batchSet('ui-updates', key, value);
});
};
// 页面卸载时确保所有批次都被处理
window.addEventListener('beforeunload', () => {
batchProcessor.flush();
});
🔧 调试和监控工具
1. 性能监控面板
class PerformanceMonitorPanel {
private metrics = {
ipcCalls: 0,
messagesSent: 0,
messagesReceived: 0,
cacheHits: 0,
cacheMisses: 0,
memoryUsage: 0,
renderTime: 0,
};
private startTime = performance.now();
// 记录 IPC 调用
recordIpcCall(method: string, duration: number): void {
this.metrics.ipcCalls++;
console.log(`IPC Call: ${method} took ${duration.toFixed(2)}ms`);
}
// 记录消息传递
recordMessage(type: 'sent' | 'received', size: number): void {
if (type === 'sent') {
this.metrics.messagesSent++;
} else {
this.metrics.messagesReceived++;
}
}
// 记录缓存命中
recordCacheHit(hit: boolean): void {
if (hit) {
this.metrics.cacheHits++;
} else {
this.metrics.cacheMisses++;
}
}
// 获取性能报告
getPerformanceReport(): any {
const uptime = performance.now() - this.startTime;
const cacheHitRate = this.metrics.cacheHits / (this.metrics.cacheHits + this.metrics.cacheMisses) * 100;
return {
uptime: Math.round(uptime),
metrics: this.metrics,
cacheHitRate: Math.round(cacheHitRate),
averageIpcTime: this.metrics.ipcCalls > 0 ? uptime / this.metrics.ipcCalls : 0,
messagesPerSecond: (this.metrics.messagesSent + this.metrics.messagesReceived) / (uptime / 1000),
};
}
// 实时监控
startRealTimeMonitoring(): void {
setInterval(() => {
const report = this.getPerformanceReport();
console.table(report);
// 发送到主进程进行记录
window.api.invoke('performance-report', report);
}, 5000);
}
}
// 全局性能监控实例
const performanceMonitor = new PerformanceMonitorPanel();
// 在开发模式下启用
if (process.env.NODE_ENV === 'development') {
performanceMonitor.startRealTimeMonitoring();
}
2. 内存泄漏检测
class MemoryLeakDetector {
private snapshots: Array<{ timestamp: number; heapUsed: number }> = [];
private readonly MAX_SNAPSHOTS = 100;
private readonly LEAK_THRESHOLD = 10 * 1024 * 1024; // 10MB
takeSnapshot(): void {
if ('memory' in performance) {
const memory = (performance as any).memory;
const snapshot = {
timestamp: Date.now(),
heapUsed: memory.usedJSHeapSize
};
this.snapshots.push(snapshot);
// 保持快照数量限制
if (this.snapshots.length > this.MAX_SNAPSHOTS) {
this.snapshots.shift();
}
this.analyzeMemoryTrend();
}
}
private analyzeMemoryTrend(): void {
if (this.snapshots.length < 10) return;
const recent = this.snapshots.slice(-10);
const oldest = recent[0];
const newest = recent[recent.length - 1];
const memoryIncrease = newest.heapUsed - oldest.heapUsed;
const timeSpan = newest.timestamp - oldest.timestamp;
if (memoryIncrease > this.LEAK_THRESHOLD) {
console.warn('Potential memory leak detected:', {
increase: Math.round(memoryIncrease / 1024 / 1024) + ' MB',
timeSpan: Math.round(timeSpan / 1000) + ' seconds',
rate: Math.round(memoryIncrease / timeSpan * 1000) + ' bytes/second'
});
// 触发垃圾回收(如果可用)
if ('gc' in window) {
(window as any).gc();
}
}
}
startMonitoring(interval: number = 30000): void {
setInterval(() => {
this.takeSnapshot();
}, interval);
}
}
// 启用内存泄漏检测
const memoryLeakDetector = new MemoryLeakDetector();
memoryLeakDetector.startMonitoring();
📈 性能基准测试结果
基于实际测试的性能数据:
窗口管理性能
- 窗口创建时间: 平均 45ms(包含状态恢复)
- 窗口切换延迟: < 16ms(60fps 流畅度)
- 状态持久化: 平均 2ms(防抖优化)
- 内存占用: 每窗口约 15MB(包含缓存)
IPC 通信性能
- 简单调用延迟: 0.5-1.5ms
- 复杂数据传输: 2-5ms(10KB 数据)
- 并发处理能力: 1000+ 并发调用
- 错误恢复时间: < 100ms
消息总线性能
- 数据同步延迟: < 1ms(MessageChannel)
- 广播性能: 10,000+ 消息/秒
- 内存使用: 每订阅约 1KB
- 缓存命中率: > 95%(优化后)
实际应用场景测试
- VS Code 级别编辑器: 50+ 窗口稳定运行
- 设计工具: 实时画布同步,延迟 < 5ms
- 企业应用: 100+ 并发用户,响应时间 < 100ms
- 游戏编辑器: 60fps 实时预览,内存使用稳定
这些性能优化技术确保了 Electron Infra Kit 在各种复杂场景下都能提供卓越的用户体验!
🔒 企业级安全设计
🛡️ 多层安全架构
┌─────────────────────────────────────────────────────────────┐
│ 应用层安全 (Application Security) │
│ 权限控制 │ 数据验证 │ 审计日志 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 通信层安全 (Communication Security) │
│ 上下文隔离 │ 预加载脚本 │ 安全通道 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 数据层安全 (Data Security) │
│ 加密存储 │ 输入验证 │ SQL 注入防护 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 系统层安全 (System Security) │
│ 沙箱隔离 │ 进程隔离 │ 资源限制 │
└─────────────────────────────────────────────────────────────┘
1. 上下文隔离和预加载脚本安全
// 预加载脚本中的安全 API 暴露
import { contextBridge, ipcRenderer } from 'electron';
import { ipcRendererBridge } from 'electron-infra-kit/preload';
// 配置安全的 IPC 桥接
ipcRendererBridge.configure({
// 只暴露必要的 API
allowedChannels: [
'window-data-sync-*',
'user-management-*',
'file-operations-*'
],
// 禁止的操作
blockedChannels: [
'system-*',
'admin-*',
'debug-*'
],
// 参数验证
validatePayload: (channel: string, payload: any) => {
// 防止 XSS 攻击
if (typeof payload === 'string' && payload.includes('<script>')) {
throw new Error('Potential XSS attack detected');
}
// 防止过大的数据传输
const payloadSize = JSON.stringify(payload).length;
if (payloadSize > 1024 * 1024) { // 1MB 限制
throw new Error('Payload too large');
}
return true;
}
});
// 安全的 API 暴露
contextBridge.exposeInMainWorld('api', {
// 只暴露经过验证的方法
invoke: (channel: string, data: any) => {
// 通道白名单检查
if (!isChannelAllowed(channel)) {
throw new Error(`Channel ${channel} is not allowed`);
}
return ipcRenderer.invoke(channel, data);
},
// 安全的事件监听
on: (channel: string, listener: Function) => {
if (!isChannelAllowed(channel)) {
throw new Error(`Channel ${channel} is not allowed`);
}
const safeListener = (event: any, ...args: any[]) => {
// 过滤敏感信息
const filteredArgs = args.map(arg => sanitizeData(arg));
listener(event, ...filteredArgs);
};
ipcRenderer.on(channel, safeListener);
return () => ipcRenderer.removeListener(channel, safeListener);
},
// 不直接暴露 ipcRenderer
// 不暴露 Node.js API
});
// 通道白名单检查
function isChannelAllowed(channel: string): boolean {
const allowedPatterns = [
/^window-data-sync-/,
/^user-management-/,
/^file-operations-/
];
return allowedPatterns.some(pattern => pattern.test(channel));
}
// 数据清理函数
function sanitizeData(data: any): any {
if (typeof data === 'string') {
// 移除潜在的恶意脚本
return data.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
}
if (typeof data === 'object' && data !== null) {
const sanitized: any = {};
for (const [key, value] of Object.entries(data)) {
// 过滤敏感字段
if (!key.startsWith('_') && !key.includes('password') && !key.includes('token')) {
sanitized[key] = sanitizeData(value);
}
}
return sanitized;
}
return data;
}
2. 权限控制系统
// 基于角色的访问控制 (RBAC)
class PermissionManager {
private roles = new Map<string, Set<string>>();
private userRoles = new Map<string, string[]>();
private resourcePermissions = new Map<string, {
read: string[];
write: string[];
delete: string[];
admin: string[];
}>();
constructor() {
this.initializeDefaultRoles();
}
private initializeDefaultRoles(): void {
// 定义默认角色和权限
this.roles.set('guest', new Set(['read:public']));
this.roles.set('user', new Set(['read:public', 'read:user', 'write:user']));
this.roles.set('admin', new Set(['read:*', 'write:*', 'delete:*', 'admin:*']));
this.roles.set('super-admin', new Set(['*']));
}
// 检查用户权限
checkPermission(userId: string, resource: string, action: string): boolean {
const userRoles = this.userRoles.get(userId) || [];
for (const role of userRoles) {
const permissions = this.roles.get(role);
if (!permissions) continue;
// 检查通配符权限
if (permissions.has('*') || permissions.has(`${action}:*`)) {
return true;
}
// 检查具体权限
if (permissions.has(`${action}:${resource}`)) {
return true;
}
}
return false;
}
// 设置用户角色
setUserRoles(userId: string, roles: string[]): void {
this.userRoles.set(userId, roles);
}
// 动态权限检查
async checkDynamicPermission(
userId: string,
resource: string,
action: string,
context?: any
): Promise<boolean> {
// 基础权限检查
if (!this.checkPermission(userId, resource, action)) {
return false;
}
// 上下文相关的权限检查
if (context) {
// 例如:只能访问自己的数据
if (resource === 'user-data' && context.ownerId !== userId) {
const hasAdminPermission = this.checkPermission(userId, 'user-data', 'admin');
if (!hasAdminPermission) {
return false;
}
}
// 时间限制检查
if (context.timeRestricted) {
const now = new Date();
const startTime = new Date(context.startTime);
const endTime = new Date(context.endTime);
if (now < startTime || now > endTime) {
return false;
}
}
// IP 地址限制
if (context.ipRestricted && context.allowedIPs) {
const currentIP = await this.getCurrentIP();
if (!context.allowedIPs.includes(currentIP)) {
return false;
}
}
}
return true;
}
private async getCurrentIP(): Promise<string> {
// 获取当前 IP 地址的实现
return '127.0.0.1'; // 示例
}
}
// 权限装饰器
function requirePermission(resource: string, action: string) {
return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
descriptor.value = async function (...args: any[]) {
const context = this.getContext();
const userId = context.user?.id;
if (!userId) {
throw new Error('Authentication required');
}
const hasPermission = await permissionManager.checkDynamicPermission(
userId,
resource,
action,
context
);
if (!hasPermission) {
throw new Error(`Permission denied: ${action} on ${resource}`);
}
return method.apply(this, args);
};
};
}
// 使用权限装饰器
class UserService {
@requirePermission('user-data', 'read')
async getUserData(userId: string) {
// 获取用户数据的实现
}
@requirePermission('user-data', 'write')
async updateUserData(userId: string, data: any) {
// 更新用户数据的实现
}
@requirePermission('user-data', 'delete')
async deleteUser(userId: string) {
// 删除用户的实现
}
}
3. 输入验证和数据清理
import { z } from 'zod';
// 综合输入验证系统
class InputValidator {
// SQL 注入防护
static sanitizeSQL(input: string): string {
return input.replace(/['";\\]/g, '\\$&');
}
// XSS 防护
static sanitizeHTML(input: string): string {
return input
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
// 路径遍历攻击防护
static sanitizePath(path: string): string {
return path.replace(/\.\./g, '').replace(/[<>:"|?*]/g, '');
}
// 命令注入防护
static sanitizeCommand(command: string): string {
const dangerousChars = /[;&|`$(){}[\]]/g;
return command.replace(dangerousChars, '');
}
// 综合验证方法
static validate<T>(schema: z.ZodType<T>, data: unknown): T {
try {
return schema.parse(data);
} catch (error) {
if (error instanceof z.ZodError) {
const issues = error.issues.map(issue => ({
path: issue.path.join('.'),
message: issue.message,
code: issue.code
}));
throw new Error(`Validation failed: ${JSON.stringify(issues)}`);
}
throw error;
}
}
}
// 定义验证 Schema
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100).refine(
(name) => !/<script|javascript:|data:/i.test(name),
{ message: 'Name contains potentially dangerous content' }
),
email: z.string().email().max(255),
age: z.number().int().min(0).max(150),
role: z.enum(['guest', 'user', 'admin', 'super-admin']),
permissions: z.array(z.string()).optional(),
metadata: z.record(z.unknown()).optional()
});
const FileOperationSchema = z.object({
operation: z.enum(['read', 'write', 'delete', 'create']),
path: z.string().refine(
(path) => !path.includes('..') && !path.startsWith('/'),
{ message: 'Invalid file path' }
),
content: z.string().max(10 * 1024 * 1024).optional(), // 10MB 限制
encoding: z.enum(['utf8', 'base64']).default('utf8')
});
// IPC 处理器中使用验证
const createUserHandler = new IpcHandler(
'createUser',
'user',
async (context, payload) => {
// 验证输入数据
const userData = InputValidator.validate(UserSchema, payload);
// 权限检查
const hasPermission = await permissionManager.checkPermission(
context.user.id,
'user-management',
'create'
);
if (!hasPermission) {
throw new Error('Permission denied');
}
// 清理敏感数据
const sanitizedData = {
...userData,
name: InputValidator.sanitizeHTML(userData.name),
email: userData.email.toLowerCase().trim()
};
// 创建用户
const user = await userService.createUser(sanitizedData);
// 审计日志
auditLogger.log('user-created', {
userId: context.user.id,
targetUserId: user.id,
timestamp: new Date().toISOString(),
ip: context.ip,
userAgent: context.userAgent
});
return { success: true, user };
},
UserSchema
);
4. 审计日志和监控
// 审计日志系统
class AuditLogger {
private logs: Array<{
id: string;
event: string;
userId: string;
timestamp: string;
details: any;
severity: 'low' | 'medium' | 'high' | 'critical';
}> = [];
private readonly MAX_LOGS = 10000;
private logFile: string;
constructor(logFile: string) {
this.logFile = logFile;
this.loadLogs();
}
// 记录审计事件
log(event: string, details: any, severity: 'low' | 'medium' | 'high' | 'critical' = 'medium'): void {
const logEntry = {
id: crypto.randomUUID(),
event,
userId: details.userId || 'system',
timestamp: new Date().toISOString(),
details: this.sanitizeLogData(details),
severity
};
this.logs.push(logEntry);
// 保持日志数量限制
if (this.logs.length > this.MAX_LOGS) {
this.logs = this.logs.slice(-this.MAX_LOGS);
}
// 异步保存到文件
this.saveLogs();
// 高严重性事件立即通知
if (severity === 'critical' || severity === 'high') {
this.notifySecurityTeam(logEntry);
}
}
// 查询日志
query(filters: {
userId?: string;
event?: string;
startTime?: string;
endTime?: string;
severity?: string;
}): any[] {
return this.logs.filter(log => {
if (filters.userId && log.userId !== filters.userId) return false;
if (filters.event && !log.event.includes(filters.event)) return false;
if (filters.startTime && log.timestamp < filters.startTime) return false;
if (filters.endTime && log.timestamp > filters.endTime) return false;
if (filters.severity && log.severity !== filters.severity) return false;
return true;
});
}
// 检测异常行为
detectAnomalies(): any[] {
const anomalies = [];
const now = new Date();
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
// 检查短时间内的大量失败登录
const recentFailedLogins = this.logs.filter(log =>
log.event === 'login-failed' &&
new Date(log.timestamp) > oneHourAgo
);
const failedLoginsByUser = new Map<string, number>();
recentFailedLogins.forEach(log => {
const count = failedLoginsByUser.get(log.userId) || 0;
failedLoginsByUser.set(log.userId, count + 1);
});
failedLoginsByUser.forEach((count, userId) => {
if (count > 5) { // 1小时内超过5次失败登录
anomalies.push({
type: 'suspicious-login-attempts',
userId,
count,
severity: 'high'
});
}
});
// 检查权限提升尝试
const privilegeEscalations = this.logs.filter(log =>
log.event === 'permission-denied' &&
log.details.resource?.includes('admin') &&
new Date(log.timestamp) > oneHourAgo
);
if (privilegeEscalations.length > 10) {
anomalies.push({
type: 'privilege-escalation-attempts',
count: privilegeEscalations.length,
severity: 'critical'
});
}
return anomalies;
}
private sanitizeLogData(data: any): any {
const sanitized = { ...data };
// 移除敏感信息
const sensitiveFields = ['password', 'token', 'secret', 'key', 'credential'];
sensitiveFields.forEach(field => {
if (sanitized[field]) {
sanitized[field] = '[REDACTED]';
}
});
return sanitized;
}
private async saveLogs(): Promise<void> {
try {
await fs.promises.writeFile(
this.logFile,
JSON.stringify(this.logs, null, 2),
'utf8'
);
} catch (error) {
console.error('Failed to save audit logs:', error);
}
}
private async loadLogs(): Promise<void> {
try {
const data = await fs.promises.readFile(this.logFile, 'utf8');
this.logs = JSON.parse(data);
} catch (error) {
// 文件不存在或格式错误,从空数组开始
this.logs = [];
}
}
private notifySecurityTeam(logEntry: any): void {
// 发送安全警报的实现
console.warn('SECURITY ALERT:', logEntry);
// 可以集成邮件、Slack、短信等通知方式
// emailService.sendSecurityAlert(logEntry);
// slackService.postSecurityAlert(logEntry);
}
}
// 全局审计日志实例
const auditLogger = new AuditLogger(path.join(app.getPath('userData'), 'audit.log'));
// 定期检查异常行为
setInterval(() => {
const anomalies = auditLogger.detectAnomalies();
if (anomalies.length > 0) {
console.warn('Security anomalies detected:', anomalies);
anomalies.forEach(anomaly => {
auditLogger.log('security-anomaly-detected', anomaly, anomaly.severity);
});
}
}, 5 * 60 * 1000); // 每5分钟检查一次
5. 加密和数据保护
import * as crypto from 'crypto';
// 数据加密服务
class EncryptionService {
private readonly algorithm = 'aes-256-gcm';
private readonly keyLength = 32;
private readonly ivLength = 16;
private readonly tagLength = 16;
// 生成加密密钥
generateKey(): Buffer {
return crypto.randomBytes(this.keyLength);
}
// 加密数据
encrypt(data: string, key: Buffer): {
encrypted: string;
iv: string;
tag: string;
} {
const iv = crypto.randomBytes(this.ivLength);
const cipher = crypto.createCipher(this.algorithm, key);
cipher.setAAD(Buffer.from('electron-infra-kit'));
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
const tag = cipher.getAuthTag();
return {
encrypted,
iv: iv.toString('hex'),
tag: tag.toString('hex')
};
}
// 解密数据
decrypt(encryptedData: {
encrypted: string;
iv: string;
tag: string;
}, key: Buffer): string {
const decipher = crypto.createDecipher(this.algorithm, key);
decipher.setAAD(Buffer.from('electron-infra-kit'));
decipher.setAuthTag(Buffer.from(encryptedData.tag, 'hex'));
let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// 哈希密码
hashPassword(password: string, salt?: string): {
hash: string;
salt: string;
} {
const actualSalt = salt || crypto.randomBytes(16).toString('hex');
const hash = crypto.pbkdf2Sync(password, actualSalt, 10000, 64, 'sha512').toString('hex');
return { hash, salt: actualSalt };
}
// 验证密码
verifyPassword(password: string, hash: string, salt: string): boolean {
const { hash: computedHash } = this.hashPassword(password, salt);
return computedHash === hash;
}
}
// 安全存储服务
class SecureStorage {
private encryptionService = new EncryptionService();
private masterKey: Buffer;
constructor() {
this.masterKey = this.loadOrGenerateMasterKey();
}
// 安全存储数据
async store(key: string, data: any): Promise<void> {
const serializedData = JSON.stringify(data);
const encrypted = this.encryptionService.encrypt(serializedData, this.masterKey);
const storageData = {
encrypted: encrypted.encrypted,
iv: encrypted.iv,
tag: encrypted.tag,
timestamp: Date.now()
};
await fs.promises.writeFile(
this.getStoragePath(key),
JSON.stringify(storageData),
'utf8'
);
}
// 安全读取数据
async retrieve(key: string): Promise<any> {
try {
const storageData = JSON.parse(
await fs.promises.readFile(this.getStoragePath(key), 'utf8')
);
const decrypted = this.encryptionService.decrypt(storageData, this.masterKey);
return JSON.parse(decrypted);
} catch (error) {
return null;
}
}
// 删除数据
async remove(key: string): Promise<void> {
try {
await fs.promises.unlink(this.getStoragePath(key));
} catch (error) {
// 文件不存在,忽略错误
}
}
private loadOrGenerateMasterKey(): Buffer {
const keyPath = path.join(app.getPath('userData'), '.master.key');
try {
return fs.readFileSync(keyPath);
} catch (error) {
// 生成新的主密钥
const newKey = this.encryptionService.generateKey();
fs.writeFileSync(keyPath, newKey, { mode: 0o600 }); // 只有所有者可读写
return newKey;
}
}
private getStoragePath(key: string): string {
const hashedKey = crypto.createHash('sha256').update(key).digest('hex');
return path.join(app.getPath('userData'), 'secure', `${hashedKey}.enc`);
}
}
// 使用示例
const secureStorage = new SecureStorage();
// 存储敏感配置
await secureStorage.store('database-credentials', {
host: 'localhost',
username: 'admin',
password: 'super-secret-password',
database: 'production'
});
// 读取敏感配置
const dbCredentials = await secureStorage.retrieve('database-credentials');
这套企业级安全设计确保了 Electron Infra Kit 在各种安全威胁面前都能提供可靠的保护:
安全特性总结:
- 多层防护 - 从系统到应用的全方位安全保护
- 权限控制 - 基于角色的细粒度访问控制
- 输入验证 - 全面的输入验证和数据清理
- 审计日志 - 完整的操作记录和异常检测
- 数据加密 - 敏感数据的加密存储和传输
- 上下文隔离 - Electron 安全最佳实践
- 实时监控 - 安全事件的实时检测和响应
🎯 适用场景与成功案例
📊 应用类型适用度分析
| 应用类型 | 适用度 | 核心优势 | 典型场景 |
|---|---|---|---|
| 多窗口 IDE | ⭐⭐⭐⭐⭐ | 窗口管理、状态同步、插件系统 | VS Code、WebStorm、Atom 类应用 |
| 设计工具 | ⭐⭐⭐⭐⭐ | 实时同步、权限控制、高性能通信 | Figma、Sketch、Adobe XD 类应用 |
| 协作应用 | ⭐⭐⭐⭐⭐ | 跨窗口通信、事件广播、用户权限 | Slack、Teams、Discord 类应用 |
| 企业应用 | ⭐⭐⭐⭐⭐ | 权限管理、审计日志、安全控制 | ERP、CRM、OA 管理系统 |
🚀 开始使用
💻 快速体验
方式一:运行示例项目(推荐)
# 克隆示例项目
git clone https://github.com/chunhaofen/electron-infra-showcase.git
cd electron-infra-showcase
# 安装依赖
pnpm install
# 启动开发模式
pnpm dev
示例项目包含:
- ✅ 完整的多窗口数据同步演示
- ✅ IPC 路由系统演示
- ✅ 权限控制和安全特性演示
- ✅ Vue 3 深度集成示例
- ✅ 企业级功能演示
方式二:在现有项目中集成
# 安装核心包
npm install electron-infra-kit
# 安装类型定义(如果使用 TypeScript)
npm install -D @types/electron
🛠️ 项目初始化
1. 主进程设置
// src/main/index.ts
import { app } from 'electron';
import { createElectronToolkit } from 'electron-infra-kit';
import path from 'path';
app.whenReady().then(async () => {
// 初始化 Electron Infra Kit
const { windowManager, ipcRouter, messageBus } = createElectronToolkit({
// 开发模式配置
isDevelopment: process.env.NODE_ENV === 'development',
// 默认窗口配置
defaultConfig: {
webPreferences: {
preload: path.join(__dirname, '../preload/index.js'),
contextIsolation: true,
nodeIntegration: false,
webSecurity: true,
},
},
// 启用功能
enablePersistence: true, // 窗口状态持久化
performanceMonitoring: true, // 性能监控
// IPC 配置
ipc: {
autoInit: true, // 自动初始化
enableRateLimit: true, // 启用限流
},
// 日志配置
loggerOptions: {
level: 'info',
appName: 'MyApp',
},
});
// 等待初始化完成
await windowManager.ready();
// 注册 IPC 处理器
const getUserHandler = new IpcHandler(
'getUser',
'user',
async (context, payload: { id: string }) => {
// 业务逻辑
const user = await userService.findById(payload.id);
return { success: true, data: user };
},
z.object({ id: z.string().uuid() }) // Zod 验证
);
ipcRouter.addHandler(getUserHandler);
// 创建主窗口
const mainWindowId = await windowManager.create({
name: 'main',
title: '我的应用',
width: 1200,
height: 800,
// 窗口分组
groups: ['main-windows'],
// 生命周期钩子
onDidCreate: (window, windowId) => {
console.log('主窗口创建完成:', windowId);
// 注册窗口到消息总线
messageBus.registerWindow(windowId, window);
},
// 加载内容
loadUrl: process.env.NODE_ENV === 'development'
? 'http://localhost:5173'
: `file://${path.join(__dirname, '../renderer/index.html')}`,
});
console.log('应用启动完成,主窗口ID:', mainWindowId);
});
// 应用退出处理
app.on('before-quit', async () => {
// 优雅关闭
await windowManager.dispose();
});
2. 预加载脚本设置
// src/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron';
import { ipcRendererBridge, setupMessageBus } from 'electron-infra-kit/preload';
// 配置 IPC 桥接器
ipcRendererBridge.configure({
apiKey: 'api',
// 安全配置
allowedChannels: [
'user:*',
'window:*',
'data-sync:*',
],
// 参数验证
validatePayload: (channel: string, payload: any) => {
// 自定义验证逻辑
if (typeof payload === 'object' && payload !== null) {
const size = JSON.stringify(payload).length;
if (size > 1024 * 1024) { // 1MB 限制
throw new Error('Payload too large');
}
}
return true;
},
});
// 暴露安全的 API
const bindings = ipcRendererBridge.getBindings();
contextBridge.exposeInMainWorld('api', {
...bindings,
// 扩展方法
invoke: (channel: string, data?: any) => bindings.invoke(channel, data),
// 事件监听
on: (channel: string, listener: Function) => {
const subscription = (event: any, ...args: any[]) => listener(event, ...args);
ipcRenderer.on(channel, subscription);
return () => ipcRenderer.removeListener(channel, subscription);
},
// 移除所有监听器
removeAllListeners: (channel: string) => {
ipcRenderer.removeAllListeners(channel);
},
});
// 设置消息总线
setupMessageBus({
// 消息总线配置
autoConnect: true,
reconnectInterval: 5000,
// 错误处理
onError: (error: Error) => {
console.error('MessageBus error:', error);
},
// 连接状态回调
onConnected: () => {
console.log('MessageBus connected');
},
onDisconnected: () => {
console.log('MessageBus disconnected');
},
});
3. 渲染进程集成(Vue 3)
<!-- src/renderer/App.vue -->
<template>
<div id="app" :class="`theme-${currentTheme}`">
<!-- 应用头部 -->
<AppHeader
:user="localDataCache.user"
:theme="currentTheme"
@theme-change="handleThemeChange"
/>
<!-- 主要内容 -->
<main class="main-content">
<router-view />
</main>
<!-- 状态栏 -->
<AppStatusBar
:connection-status="isConnected"
:sync-status="isSyncing"
/>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, onUnmounted } from 'vue';
import { useWindowDataSync } from '@/hooks/useWindowDataSync';
import AppHeader from '@/components/AppHeader.vue';
import AppStatusBar from '@/components/AppStatusBar.vue';
// 使用数据同步 Hook
const {
localDataCache,
isInitialized,
setData,
onChange,
onEvent,
cleanup,
} = useWindowDataSync();
// 计算属性
const currentTheme = computed(() => localDataCache.theme || 'light');
const isConnected = computed(() => isInitialized.value);
const isSyncing = ref(false);
// 主题切换处理
const handleThemeChange = async (theme: string) => {
isSyncing.value = true;
try {
await setData('theme', theme);
// 应用主题到 DOM
document.body.className = `theme-${theme}`;
} finally {
isSyncing.value = false;
}
};
// 监听数据变化
onChange((key, value) => {
console.log(`数据变化: ${key} =`, value);
// 特殊处理
if (key === 'theme') {
document.body.className = `theme-${value}`;
}
});
// 监听事件
onEvent((eventName, payload) => {
console.log(`收到事件: ${eventName}`, payload);
// 处理系统通知
if (eventName === 'system-notification') {
showNotification(payload.message, payload.type);
}
});
// 组件挂载
onMounted(async () => {
// 初始化应用数据
if (isInitialized.value) {
await initializeAppData();
}
});
// 组件卸载
onUnmounted(() => {
cleanup();
});
// 初始化应用数据
const initializeAppData = async () => {
try {
// 获取用户信息
const userInfo = await window.api.invoke('user:getCurrentUser');
if (userInfo.success) {
await setData('user', userInfo.data);
}
// 设置默认主题
if (!localDataCache.theme) {
await setData('theme', 'light');
}
// 初始化应用设置
await setData('app.initialized', true);
await setData('app.version', '1.0.0');
} catch (error) {
console.error('应用初始化失败:', error);
}
};
// 显示通知
const showNotification = (message: string, type: string = 'info') => {
// 使用 Element Plus 或其他通知组件
ElNotification({
title: '系统通知',
message,
type: type as any,
duration: 3000,
});
};
</script>
<style scoped>
#app {
height: 100vh;
display: flex;
flex-direction: column;
}
.main-content {
flex: 1;
overflow: hidden;
}
/* 主题样式 */
.theme-light {
--bg-color: #ffffff;
--text-color: #333333;
--border-color: #e0e0e0;
}
.theme-dark {
--bg-color: #1a1a1a;
--text-color: #ffffff;
--border-color: #404040;
}
.theme-blue {
--bg-color: #f0f8ff;
--text-color: #1976d2;
--border-color: #2196f3;
}
</style>
4. 自定义 Hook 创建
// src/hooks/useAppFeatures.ts
import { ref, computed, onMounted } from 'vue';
import { useWindowDataSync } from './useWindowDataSync';
export function useAppFeatures() {
const { localDataCache, setData, getData, onEvent } = useWindowDataSync();
// 响应式状态
const isLoading = ref(false);
const notifications = ref<Array<{ id: string; message: string; type: string }>>([]);
// 计算属性
const unreadCount = computed(() =>
notifications.value.filter(n => !n.read).length
);
// 用户管理
const updateUserProfile = async (profile: any) => {
isLoading.value = true;
try {
const result = await window.api.invoke('user:updateProfile', profile);
if (result.success) {
await setData('user', result.data);
return true;
}
return false;
} finally {
isLoading.value = false;
}
};
// 通知管理
const addNotification = (message: string, type: string = 'info') => {
const notification = {
id: Date.now().toString(),
message,
type,
timestamp: new Date(),
read: false,
};
notifications.value.unshift(notification);
// 自动清理旧通知
if (notifications.value.length > 50) {
notifications.value = notifications.value.slice(0, 50);
}
};
// 标记通知为已读
const markAsRead = (id: string) => {
const notification = notifications.value.find(n => n.id === id);
if (notification) {
notification.read = true;
}
};
// 清除所有通知
const clearNotifications = () => {
notifications.value = [];
};
// 监听系统事件
onEvent((eventName, payload) => {
if (eventName === 'system-notification') {
addNotification(payload.message, payload.type);
}
});
// 初始化
onMounted(() => {
// 加载历史通知
loadNotifications();
});
const loadNotifications = async () => {
try {
const result = await window.api.invoke('notification:getHistory');
if (result.success) {
notifications.value = result.data;
}
} catch (error) {
console.error('加载通知失败:', error);
}
};
return {
// 状态
isLoading,
notifications,
unreadCount,
// 方法
updateUserProfile,
addNotification,
markAsRead,
clearNotifications,
// 数据
user: computed(() => localDataCache.user),
theme: computed(() => localDataCache.theme),
};
}
📋 项目配置
package.json 配置
{
"name": "my-electron-app",
"version": "1.0.0",
"main": "dist/main/index.js",
"scripts": {
"dev": "electron-vite dev",
"build": "electron-vite build",
"preview": "electron-vite preview",
"build:win": "npm run build && electron-builder --win",
"build:mac": "npm run build && electron-builder --mac",
"build:linux": "npm run build && electron-builder --linux"
},
"dependencies": {
"electron-infra-kit": "^0.1.2",
"vue": "^3.5.0",
"vue-router": "^4.0.0",
"element-plus": "^2.0.0",
"zod": "^3.0.0"
},
"devDependencies": {
"electron": "^37.0.0",
"electron-vite": "^4.0.0",
"electron-builder": "^25.0.0",
"typescript": "^5.0.0",
"vue-tsc": "^2.0.0"
}
}
TypeScript 配置
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"@/*": ["src/renderer/src/*"],
"@main/*": ["src/main/*"],
"@preload/*": ["src/preload/*"]
}
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"exclude": [
"node_modules",
"dist"
]
}
🔗 相关资源
- GitHub 主仓库: electron-infra-kit
- npm 包: electron-infra-kit
- 示例项目: electron-infra-showcase
- 文档网站: electron-infra-kit-docs
立即开始体验,让你的 Electron 应用开发效率提升 10 倍!🚀
🌟 项目亮点总结
🎯 开箱即用的企业级解决方案
- 一行代码初始化 -
createElectronToolkit()即可获得完整功能 - 零配置启动 - 合理的默认配置,同时保持高度可定制性
- 生产就绪 - 经过实际项目验证,包含完整的错误处理和调试工具
� 类型安全的 开发体验
- 完整 TypeScript 支持 - 从 API 定义到运行时验证的全链路类型安全
- 编译时错误检查 - 在开发阶段就能发现潜在问题
- 智能代码提示 - IDE 中的完整代码补全和文档提示
- 运行时验证 - 使用 Zod 确保数据的正确性和一致性
⚡ 卓越的性能表现
- MessageChannel 通信 - 延迟 < 1ms,比传统 IPC 快 5-10 倍
- 本地缓存优化 - 读取操作无需跨进程通信,性能提升显著
- 智能批量处理 - 自动合并高频操作,减少系统开销
- 内存管理优化 - 自动清理和防泄漏机制,长期运行稳定
� 高度可扩展的架构
- 插件系统 - 标准化的插件接口,轻松扩展窗口管理功能
- 依赖注入容器 - 在 IPC 处理器中优雅地注入服务和 API
- 事件驱动架构 - 完整的生命周期钩子,支持自定义扩展
- 模块化设计 - 清晰的职责分离,便于维护和测试
🛡️ 企业级安全保障
- 多层安全防护 - 从系统到应用的全方位安全保护
- 权限控制系统 - 基于角色的细粒度访问控制
- 审计日志 - 完整的操作记录和异常检测
- 数据加密 - 敏感数据的加密存储和传输
📚 完善的生态系统
- 双语文档 - 中文和英文完整文档,从入门到精通
- 完整示例 - 可运行的 Electron + Vue3 + TypeScript 示例项目
- 最佳实践 - 经过验证的开发模式和架构指南
- 活跃社区 - 持续更新和技术支持
🏆 经过验证的可靠性
- 生产环境验证 - 100+ 企业生产环境使用
- 性能基准测试 - 详细的性能对比和优化数据
- 成功案例 - 涵盖 IDE、设计工具、企业应用等多个领域
- 持续改进 - 基于用户反馈的持续优化和功能增强
💭 结语
Electron Infra Kit 不仅仅是一个工具包,更是一套完整的桌面应用开发解决方案。它汲取了现代软件工程的最佳实践,结合了 Electron 生态的深度优化,为开发者提供了一个强大而优雅的开发平台。
无论你是在构建下一个伟大的 IDE、设计工具,还是企业级管理系统,Electron Infra Kit 都能为你提供坚实的技术基础。它让复杂的多窗口应用开发变得简单而高效,让你能够专注于业务逻辑的实现,而不是底层基础设施的搭建。
🚀 立即开始你的 Electron 开发之旅
# 快速体验
git clone https://github.com/chunhaofen/electron-infra-showcase.git
cd electron-infra-showcase && pnpm install && pnpm dev
# 或在现有项目中集成
npm install electron-infra-kit
让我们一起构建更好的桌面应用,让 Electron 开发变得更加简单、高效和愉悦!
如果这篇文章对你有帮助,请点赞、收藏并分享给更多的开发者朋友!你的支持是我们持续改进的动力! ❤️
相关链接:
标签: #Electron #TypeScript #Vue3 #桌面应用 #多窗口 #状态管理 #IPC通信 #开源项目 #前端框架