// bootstrap.js —— 应用入口(引导加载器)。零第三方依赖,只用 electron + node 内置。 // 职责: // 1) 计算包内根 BUNDLE_ROOT 与有效根 APP_ROOT(可能是 userData/hot/)。 // 2) 注入模块解析,使从热更目录加载的代码仍能 require 到【包内】node_modules。 // 3) 健康门控选版本;try/catch 加载真正的 main.js,失败拉黑回退包内。 // 本文件始终从包内运行(package.json main 指向它,不随热更),因此修改它需发完整包。 "use strict"; const path = require("path"); const Module = require("module"); const { app } = require("electron"); const BUNDLE_ROOT = app.getAppPath(); // 打包后 = .../Resources/app.asar;dev = 项目根 const HOT_BASE = path.join(app.getPath("userData"), "hot"); // —— 让热更目录里的代码能解析到包内第三方依赖(isomorphic-git / sql.js / electron-updater)—— try { const bundleNM = path.join(BUNDLE_ROOT, "node_modules"); process.env.NODE_PATH = bundleNM + (process.env.NODE_PATH ? path.delimiter + process.env.NODE_PATH : ""); Module._initPaths(); // 把 NODE_PATH 灌进 Module.globalPaths,作为裸模块 require 的兜底搜索路径 } catch {} // —— 选择有效版本 —— let APP_ROOT = BUNDLE_ROOT; let chosenVer = null; if (app.isPackaged) { try { const hotstate = require("./lib/hotstate"); chosenVer = hotstate.chooseVersion(HOT_BASE); // 有副作用:pending 版本自增 attempts 并先落盘 if (chosenVer) APP_ROOT = path.join(HOT_BASE, chosenVer); } catch { APP_ROOT = BUNDLE_ROOT; // 热更状态读取失败 → 安全回退包内 } } global.__BUNDLE_ROOT__ = BUNDLE_ROOT; global.__APP_ROOT__ = APP_ROOT; global.__HOT_BASE__ = HOT_BASE; function loadMain(rootDir) { return require(path.join(rootDir, "electron", "main.js")); } try { loadMain(APP_ROOT); } catch (e) { if (APP_ROOT !== BUNDLE_ROOT) { // 该热更版本在 require 阶段就崩 → 拉黑 + 回退包内重载 try { require("./lib/hotstate").blacklistVersion(HOT_BASE, chosenVer, e && e.stack || e); } catch {} global.__APP_ROOT__ = BUNDLE_ROOT; loadMain(BUNDLE_ROOT); } else { throw e; // 包内都崩 = 真错误 } }