v5
核心变更
- TypeScript 全面重构:所有 API 均有完整类型定义。
- 双模块格式输出:同时支持 CJS 和 ESM 两种格式。
- Node.js 版本提升:最低要求 Node.js >= 20.19.0。
- Pino 日志体系:更强大的日志记录功能。
- Bundle 注册表机制:启动更快。
- 异步控制器加载:支持 ESM 动态导入,避免同步/异步并发竞争。
- 主进程打包: 主进程代码可以像前端 bundle 。
- 构建注册表插件:复现运行时属性名映射逻辑。
- 构建配置全面增强:新增大量精细控制项。
- 构建后独立转译:对不可打包文件独立转译。
- 加密系统升级: 更安全。
- 资源原子化移动:防止数据丢失。
- ee-bin 全面升级:新增完整 TypeScript 类型体系。
- EventBus 事件隔离:生命周期事件优化。
- 配置加载 ESM 兼容:自动解包
__esModule格式,支持函数/类导出。 - 控制器并发安全:明确保证并发请求间无状态污染。
- Cross 跨进程改进:优化。
一、核心架构变更
1. TypeScript 全面重构
v4 的 ee-core 和 ee-bin 完全由 JavaScript 编写(.js),类型定义仅通过 tsconfig.json 的 emitDeclarationOnly + allowJs 自动生成 .d.ts,源码本身无类型约束。
v5 对两个核心包进行了全量 TypeScript 重写,所有源文件为 .ts,并采用极度严格的编译配置。
影响:
- 所有 API 均有完整的类型定义,IDE 智能提示大幅提升
- 编译期即可捕获隐式
any、未检查索引访问、可选属性误用等常见错误 - ESM 源码中
import必须带.js扩展名(NodeNext规范)
2. 双模块格式输出(CJS + ESM)
v4 仅输出 CommonJS(require('ee-core')),v5 同时输出 CJS 和 ESM 两种格式:
dist/cjs/ → CommonJS (module: CommonJS)
dist/esm/ → ESM (module: NodeNext)package.json 的 exports 字段为每个子路径提供了条件导出:
{
"./app": {
"import": "./dist/esm/app/index.js",
"require": "./dist/cjs/app/index.js"
}
}影响:
- 开发者可在 ESM 项目中直接
import { ElectronEgg } from 'ee-core' - CJS 项目继续使用
const { ElectronEgg } = require('ee-core') ee-core的exports映射由scripts/gen-exports.js自动生成,新增子路径模块后执行npm run gen-exports即可更新,无需手动编辑
3. Node.js 版本要求提升
v5 要求 Node.js >= 20.19.0。
二、ee-core 功能更新
4. 日志系统:Pino 替代 egg-logger
v4 使用 egg-logger(EggLoggers),日志文件按日追加 -YYYYMMDD 后缀,通过 Object.defineProperty 惰性初始化。
v5 全面切换至 Pino 日志体系:
| 特性 | v4 (egg-logger) | v5 (Pino) |
|---|---|---|
| 日志库 | egg-logger | pino + pino-roll + pino-pretty |
| 滚动策略 | 按日追加后缀 | pino-roll:按日/按小时滚动 |
| 开发输出 | 自定义格式 | pino-pretty:可配置颜色、深度、时间戳 |
| 时区 | UTC 固定 | IANA 时区支持(如 Asia/Shanghai) |
| 日志脱敏 | 无 | Pino redaction(字段遮蔽) |
| 自定义级别 | 固定 | 可配置自定义 level |
| 调用风格 | 标准方法调用 | Proxy 包装:支持 {obj, msg}、printf ('count: %d', 42)、拼接 ('msg:', val) 三种风格 |
| 安全模式 | 无 | safe 模式防止序列化崩溃 |
影响:
- 日志配置项从
config.logger的 egg-logger 格式迁移为 pino 格式 coreLogger、logger、errorLogger三个实例保留,但底层实现完全不同- 开发者需更新自定义日志配置
5. Bundle 模式:注册表机制
这是 v5 最核心的架构新增。v4 在运行时通过 globby 扫描文件系统加载控制器和配置,打包后的应用也依赖文件系统路径。
影响:
- 打包后所有控制器和配置被注册到全局变量,无需文件系统扫描,启动更快
- 惰性 getter 避免初始化顺序问题——控制器不会在注册阶段就执行
- 开发模式(未 bundle)自动回退到文件系统扫描,行为与 v4 一致
process.env.EE_BUNDLED = "true"标识 bundle 模式
6. 异步控制器加载
v4 的 ControllerLoader 仅支持同步 require() 加载。v5 新增异步加载路径:
Application.runAsync()→loadControllerAsync()→FileLoader.parseAsync()→import()动态加载- 加载过程有
loading标志防止同步/异步并发竞争
影响:
- ESM 项目可使用
runAsync()确保异步模块正确加载 - 异步加载模式下控制器文件可以是 ESM 格式
7. IPC 双模型
v5 明确了 IPC 双模型:
| 模型 | 渲染器调用 | 主进程注册 | 特性 |
|---|---|---|---|
| send/on | webContents.send / ipcRenderer.send | ipcMain.on | 同步,event.returnValue + event.reply |
| invoke/handle | ipcRenderer.invoke | ipcMain.handle | 异步,Promise 返回值,推荐使用 |
错误传播新增 {__EE_ERROR__: true, message} 结构化标记。
8. HTTP 服务:Koa 中间件链规范化
v5 对中间件链进行了明确排序:
errorHandler → preMiddleware → CORS → koa-body → dispatch → postMiddleware新增 koaConfig 配置节,开发者可独立配置 preMiddleware、postMiddleware 数组。
9. 子进程配置传递:argv 替代文件系统
v5 改为通过 process.argv[2] 传递 eeConfig(JSON 字符化后由 JobProcess 注入),子进程内 setConfig() 解析并缓存,无需读取文件系统。
影响:
- 打包后的应用中
child_process.fork()场景更可靠 - 子进程不再依赖配置文件路径
10. 端口分配:双级锁机制
v5 引入 old + young 双级锁集合(15 秒轮转),防止并发进程抢占同一端口。
同时检测所有本地网络接口,避免分配已被占用的端口。
11. systemSleep:真正同步阻塞
v5 新增 systemSleep(ms) 工具函数,使用 Atomics.wait + SharedArrayBuffer 实现真正同步阻塞(不占用 CPU),带 busy-wait 回退。
12. 零 lodash 依赖
v5 全面去除了以下 npm 依赖,用自研轻量实现替代:
| v4 依赖 | v5 替代 | 位置 |
|---|---|---|
| lodash.merge | extend.ts(自研深合并) | ee-core, ee-bin 共用 |
| chalk | ANSI 转义码轻量实现 | ee-bin lib/helpers.ts |
| is-type-of | is.function() / is.class() | ee-bin lib/helpers.ts |
| fs-extra | copyDirSync() 自实现 | ee-bin lib/helpers.ts |
| debug | createDebug() 环境变量驱动 | ee-bin lib/helpers.ts |
| egg-logger | pino 体系 | ee-core log/ |
| adm-zip | compressing | ee-bin incrUpdater |
影响:
- 包体积和安全风险大幅降低
三、ee-bin 功能更新
13. 构建注册表插件(核心新增)
v4 的 ee-bin 没有 esbuild 插件机制,控制器和配置文件直接打包进 main.js(或 copy 模式原样复制)。
v5 新增 bundle_registry_plugin.ts,这是 v5 打包架构的关键组件:
- 虚拟模块
app:controller-registry:扫描控制器目录,生成注册表 - 虚拟模块
app:config-registry:扫描配置目录,生成注册表 - 虚拟模块
app:bundle-entry:按序加载注册表 + main.js 的入口
computeProperties() 函数复现了 ee-core 的 defaultCamelize(caseStyle: 'lower') 逻辑,确保构建时和运行时的属性名映射一致。
14. 构建配置全面增强
v5 的 build.electron(BundleConfig 类型)新增大量精细控制项:
| 配置项 | v4 | v5 | 说明 |
|---|---|---|---|
external | 无 | ✅ | 用户自定义外部包 |
sourcemap | false (固定) | false → 自动逻辑 | dev→inline, prod→off;可显式设 inline/external |
minify | 无 | ✅ | 生产压缩 |
drop | 无 | ✅ | 移除 console/debugger |
keepNames | 无 | ✅ | 压缩时保留函数/类名 |
legalComments | 无 | ✅ | inline/eof/none |
define | 无 | ✅ | 编译期常量注入 |
copy | 无 | ✅ | 额外文件/目录复制 |
format | 无 | ✅ | cjs/esm;默认 cjs |
| 框架外部包 | 无明确列表 | ✅ | ee-core, ee-bin, electron, better-sqlite3, proxy-agent, pino-roll, pino-pretty |
影响:
- 生产构建可精细控制 sourcemap、压缩、常量注入等
sourcemap: false不再是"永远关闭",而是"自动按环境决定"format: 'esm'模式要求业务代码(控制器、服务、配置)全部 ESM 兼容
15. 构建后处理:独立文件转译
v5 的 bundle 模式在打包后,对不可打包的文件(preload/bridge.js、jobs/ 目录、用户 copy 配置项)执行独立 esbuild 转译:
- 脚本文件(
.js/.ts)以bundle: false编译为 Node 可加载的 CJS.js,保留运行时require()调用 - 非脚本文件原样复制
- 所有转译使用
_resolveBaseBuildOptions()共享设置,保证与主包格式一致
影响:
preload/bridge.js和jobs/文件在打包环境下也能正确运行- 不再需要手动处理
child_process.fork()路径问题
16. 加密系统升级
| 特性 | v4 | v5 | |
|---|---|---|---|
entryFiles | 无 | ✅ | 入口文件(如 main.js)编译为 .jsc 后覆写 .js 为 bytenode loader shell |
bytecodeOptions | 固定 electron: true | ✅ | 可配置 bytenode 编译参数 |
| 安全校验 | 无 | ✅ | 编译后验证 .jsc 存在才删除 .js;不存在则抛错保留源文件 |
silent 模式 | 无 | ✅ | 隐藏 javascript-obfuscator 的 Pro 广告输出 |
cleanFiles | 无 | ✅ | 指定需要清理的加密产物 |
encryptDir | 无 | ✅ | 自定义加密输出目录 |
17. 资源移动:原子化操作
v5 的 move.ts 改为 原子化操作:
备份目标 → .bak → 复制源到目标 → 删除备份复制失败时恢复 .bak,防止数据丢失。
18. 其他 ee-bin 变更
| 项目 | v4 | v5 |
|---|---|---|
| esbuild | 0.21.5 | 0.28 |
| commander | 11.0.0 | 14 |
| 压缩库 | adm-zip | compressing |
| 测试框架 | 无 | Vitest(覆盖率 90%/85%) |
pargv.js | minimist 风格解析器 | 保留但重构为 TS |
| TypeScript 类型 | 无 | 完整 BinConfig 类型体系 |
| 配置加载 | .js/.cjs/.ts/.json/.json5 | 同上 + ESM 默认导出解包 + 函数/类配置工厂 |
四、通用变更
19. EventBus 改进
v5 的 EventBus 将生命周期事件和自定义事件分为两个独立内部 Map:
- 生命周期事件(
register/emitLifecycle):重复注册会覆盖并警告,异步错误重新抛出 - 自定义事件(
on/emit):异步错误捕获并记录日志,不中断流程
v4 的 EventBus 两种事件共用同一机制,无覆盖警告。
20. 配置加载 ESM 兼容
v5 的 loadFile() / loadFileAsync() 新增 ESM 兼容:
- 自动解包
{__esModule: true, default: fn}格式 - 配置文件导出函数时自动调用(传入
appInfo) - 配置文件导出类时直接使用(不调用)
- 异步版本使用
import()加载
21. 控制器并发安全
v5 明确标注:每个 middleware 调用创建新的控制器实例,确保并发请求间无状态污染。类型系统也在 ControllerLoader 中强化了这一约束。
22. Cross 跨进程管理改进
v5 的 Cross 类在 run() 时新增:
- 动态端口分配(双级锁机制)
- 重名服务自动追加 pid 后缀避免冲突
五、迁移注意事项
必须调整
- Node.js 版本:确保 >= 20.19.0
- 日志配置:从 egg-logger 格式迁移为 pino 格式(
pino-roll滚动、pino-pretty输出等) - ESM import 扩展名:ee-core 源码中的
import必须带.js(NodeNext 规范)
建议调整
- 构建配置:利用新增的
minify、drop、define、sourcemap自动逻辑等提升生产包质量 - 加密配置:新增
entryFiles、bytecodeOptions、silent等选项,可更精细控制加密行为 - 异步控制器:ESM 项目使用
runAsync()+loadControllerAsync()
无需调整
- 开发模式下控制器/配置加载回退到文件系统扫描,行为与 v4 一致
ElectronEgg入口类、Application单例、启动流程顺序未变- 三通道通信(Socket.IO、HTTP、IPC)架构不变
- 子进程(ChildJob、ChildPoolJob)API 不变
- SqliteStorage API 不变
