From a9de1ec525d01c496b9f5405917682064a00ded4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BA=9A=E6=98=95?= <1549469775@qq.com> Date: Wed, 4 Jun 2025 08:59:00 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E5=B9=B6=E4=BC=98=E5=8C=96=E7=83=AD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 `.vscode/settings.json` 中的 TypeScript 默认格式化工具为 Prettier,统一代码风格 - 在 `config/index.ts` 中添加 `update.hoturl` 配置项,用于指定热更新包下载地址 - 在 `package.json` 中新增 `base` 和 `helper` 工作区依赖,实现模块化拆分 - 移除 `src/common/lib/_Base.ts` 并将单例基类迁移至 `packages/base` 独立模块 - 重构热更新模块到 `packages/helper/updater`,增加下载进度事件通知功能 - 清理废弃的更新相关事件定义文件和冗余代码,保持代码整洁 - 将日志模块从 debug 切换为 logger 命名空间,统一日志管理 - 添加调试初始化脚本 `src/main/debug.ts`,优化日志记录机制 --- .vscode/settings.json | 2 +- config/index.ts | 2 + package.json | 2 + packages/base/index.ts | 27 ++++++ packages/base/package.json | 13 +++ packages/helper/package.json | 13 +++ packages/helper/updater/common.ts | 7 ++ packages/helper/updater/main/handler.ts | 8 ++ packages/helper/updater/main/hot/download.ts | 74 +++++++++++++++ packages/helper/updater/main/hot/index.ts | 118 +++++++++++++++++++++++ packages/helper/updater/main/index.ts | 137 +++++++++++++++++++++++++++ packages/helper/updater/renderer.ts | 0 packages/logger/main.ts | 1 - packages/setting/main.ts | 8 +- pnpm-lock.yaml | 10 ++ src/common/_ioc.main.ts | 7 +- src/common/event/PlatForm/index.ts | 4 +- src/common/event/Snippet/hook.ts | 2 +- src/common/event/Snippet/index.ts | 4 +- src/common/event/Tabs/index.ts | 4 +- src/common/event/Updater/index.ts | 15 +++ src/common/event/Updater/main/command.ts | 15 +++ src/common/event/common.ts | 5 - src/common/event/update/index.ts | 14 --- src/common/event/update/main/command.ts | 10 -- src/common/event/update/main/index.ts | 8 -- src/common/lib/_Base.ts | 12 --- src/common/readme.md | 7 ++ src/main/App.ts | 14 +-- src/main/base/base.ts | 3 - src/main/debug.ts | 60 ++++++++++++ src/main/index.ts | 66 +------------ src/main/modules/_ioc.ts | 3 - src/main/modules/db/index.ts | 6 +- src/main/modules/tabs/Tab.ts | 8 +- src/main/modules/tabs/index.ts | 2 +- src/main/modules/updater/hot/index.ts | 118 ----------------------- src/main/modules/updater/index.ts | 133 -------------------------- src/main/modules/window-manager/index.ts | 3 +- src/main/modules/zephyr/index.ts | 35 ++++--- src/main/utils/index.ts | 2 +- tsconfig.node.json | 10 +- tsconfig.web.json | 9 +- 43 files changed, 572 insertions(+), 429 deletions(-) create mode 100644 packages/base/index.ts create mode 100644 packages/base/package.json create mode 100644 packages/helper/package.json create mode 100644 packages/helper/updater/common.ts create mode 100644 packages/helper/updater/main/handler.ts create mode 100644 packages/helper/updater/main/hot/download.ts create mode 100644 packages/helper/updater/main/hot/index.ts create mode 100644 packages/helper/updater/main/index.ts create mode 100644 packages/helper/updater/renderer.ts create mode 100644 src/common/event/Updater/index.ts create mode 100644 src/common/event/Updater/main/command.ts delete mode 100644 src/common/event/common.ts delete mode 100644 src/common/event/update/index.ts delete mode 100644 src/common/event/update/main/command.ts delete mode 100644 src/common/event/update/main/index.ts delete mode 100644 src/common/lib/_Base.ts create mode 100644 src/common/readme.md create mode 100644 src/main/debug.ts delete mode 100644 src/main/modules/updater/hot/index.ts delete mode 100644 src/main/modules/updater/index.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 2571d5c..457ab0c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "[typescript]": { - "editor.defaultFormatter": "vscode.typescript-language-features" + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" diff --git a/config/index.ts b/config/index.ts index f574a69..def92fb 100644 --- a/config/index.ts +++ b/config/index.ts @@ -12,6 +12,7 @@ export interface IDefaultConfig { "common.theme": ThemeType debug: LogLevel "desktop:wallpaper": string + "update.hoturl": string "update.repo"?: string "update.owner"?: string "update.allowDowngrade": boolean @@ -40,6 +41,7 @@ export default { "editor.bg": "", "editor.logoType": "logo", "editor.fontFamily": "Cascadia Mono, Consolas, 'Courier New', monospace", + "update.hoturl": "https://alist.xieyaxin.top/d/%E8%B5%84%E6%BA%90/%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.zip?sign=eqy35CR-J1SOQZz0iUN2P3B0BiyZPdYH0362nLXbUhE=:1749085071", "update.repo": "wood-desktop", "update.owner": "npmrun", "update.allowDowngrade": false, diff --git a/package.json b/package.json index 0b1844d..000b82e 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^13.0.0", "@vueuse/core": "^12.7.0", + "base": "workspace:*", "debug": "^4.4.0", "electron": "^31.7.7", "electron-builder": "^24.13.3", @@ -57,6 +58,7 @@ "eslint": "^8.57.1", "eslint-plugin-vue": "^9.32.0", "extract-zip": "^2.0.1", + "helper": "workspace:*", "locales": "workspace:*", "lodash-es": "^4.17.21", "logger": "workspace:^", diff --git a/packages/base/index.ts b/packages/base/index.ts new file mode 100644 index 0000000..12cab57 --- /dev/null +++ b/packages/base/index.ts @@ -0,0 +1,27 @@ +// 抽象基类,使用泛型来正确推导子类类型 +abstract class BaseSingleton { + private static _instance: any + + public constructor() { + if (this.constructor === BaseSingleton) { + throw new Error("禁止直接实例化 BaseOne 抽象类") + } + + if ((this.constructor as any)._instance) { + throw new Error("构造函数私有化失败,禁止重复 new") + } + + // this.constructor 是子类,所以这里设为 instance + ;(this.constructor as any)._instance = this + } + + public static getInstance(this: new () => T): T { + const clazz = this as any as typeof BaseSingleton + if (!clazz._instance) { + clazz._instance = new this() + } + return clazz._instance as T + } +} + +export { BaseSingleton } diff --git a/packages/base/package.json b/packages/base/package.json new file mode 100644 index 0000000..6c535af --- /dev/null +++ b/packages/base/package.json @@ -0,0 +1,13 @@ +{ + "name": "base", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.4.1" +} diff --git a/packages/helper/package.json b/packages/helper/package.json new file mode 100644 index 0000000..b9f3e4e --- /dev/null +++ b/packages/helper/package.json @@ -0,0 +1,13 @@ +{ + "name": "helper", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.4.1" +} diff --git a/packages/helper/updater/common.ts b/packages/helper/updater/common.ts new file mode 100644 index 0000000..14f45df --- /dev/null +++ b/packages/helper/updater/common.ts @@ -0,0 +1,7 @@ +export const enum EventEnum { + UPDATE_PROGRESS = "update-progress", +} + +export type EventMaps = { + [EventEnum.UPDATE_PROGRESS]: () => void +} diff --git a/packages/helper/updater/main/handler.ts b/packages/helper/updater/main/handler.ts new file mode 100644 index 0000000..b01b5ed --- /dev/null +++ b/packages/helper/updater/main/handler.ts @@ -0,0 +1,8 @@ +import { broadcast } from "main/utils" +import { EventEnum } from "../common" + +export { EventEnum } + +export function emit(key: EventEnum, ...args: any[]) { + broadcast(key, ...args) +} diff --git a/packages/helper/updater/main/hot/download.ts b/packages/helper/updater/main/hot/download.ts new file mode 100644 index 0000000..fc87964 --- /dev/null +++ b/packages/helper/updater/main/hot/download.ts @@ -0,0 +1,74 @@ +type DownloadPercent = { + url: string + option?: object + onprocess?: (now: number, all: number) => void + onsuccess?: (data: any) => void + onerror?: (res: Response) => void +} +const RequestPercent = async ({ + url = "", + option = { + headers: { + responseType: "arraybuffer", + }, + }, + onsuccess, + onerror, + onprocess, +}: DownloadPercent) => { + const response = (await fetch(url, option)) as any + if (!response.ok) { + onerror?.(response) + throw new Error(`下载失败`) + } + const reader = response?.body.getReader() + + // 文件总长度 + const contentLength = +response.headers.get("content-length") + + let receivedLength = 0 + const chunks: any[] = [] + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader.read() + + if (done) { + break + } + + chunks.push(value) + receivedLength += value.length + onprocess?.(receivedLength, contentLength) + } + // 这里的chunksAll 已经是ArrayBuffer的数据类型了,可以直接返回,也可以转为blob处理 + const chunksAll = new Uint8Array(receivedLength) + let position = 0 + for (const chunk of chunks) { + chunksAll.set(chunk, position) + position += chunk.length + } + + onsuccess?.(chunksAll) + + return chunksAll +} + +export { RequestPercent } +export default RequestPercent + +// RequestPercent({ +// url: "http://117.21.250.136:9812/ZxqyGateway/biz/file/downApk/%E6%98%93%E4%BC%81%E6%95%B0%E8%BD%AC%E5%B9%B3%E5%8F%B0app-1.2.7.apk", +// option: { +// headers: { +// responseType: "arraybuffer", +// }, +// }, +// onerror: () => {}, +// onsuccess: data => { +// fs.writeFileSync("./aaa.apk", Buffer.from(data)) +// console.log("success", data) +// }, +// onprocess: (receivedLength, contentLength) => { +// console.log(receivedLength, contentLength) +// }, +// }) diff --git a/packages/helper/updater/main/hot/index.ts b/packages/helper/updater/main/hot/index.ts new file mode 100644 index 0000000..fcf2e89 --- /dev/null +++ b/packages/helper/updater/main/hot/index.ts @@ -0,0 +1,118 @@ +import { spawn } from "node:child_process" +import fs from "node:fs" +import path from "node:path" +import os from "node:os" +import { app } from "electron" +import download from "./download" +import extract from "extract-zip" + +import _logger from "logger/main" +import { emit, EventEnum } from "../handler" + +const logger = _logger.createNamespace("hot-updater") + +function getUpdateScriptTemplate() { + return process.platform === "win32" + ? ` + @echo off + timeout /t 2 + taskkill /IM "{{EXE_NAME}}" /F + xcopy /Y /E "{{UPDATE_DIR}}\\*" "{{APP_PATH}}" + start "" "{{EXE_PATH}}" + ` + : ` + #!/bin/bash + sleep 2 + pkill -f "{{EXE_NAME}}" + cp -Rf "{{UPDATE_DIR}}/*" "{{APP_PATH}}/" + open "{{EXE_PATH}}" + ` +} + +function generateUpdateScript() { + const scriptContent = getUpdateScriptTemplate() + .replace(/{{APP_PATH}}/g, process.platform === "win32" ? "%APP_PATH%" : "$APP_PATH") + .replace(/{{UPDATE_DIR}}/g, process.platform === "win32" ? "%UPDATE_DIR%" : "$UPDATE_DIR") + .replace(/{{EXE_PATH}}/g, process.platform === "win32" ? "%EXE_PATH%" : "$EXE_PATH") + .replace(/{{EXE_NAME}}/g, process.platform === "win32" ? "%EXE_NAME%" : "$EXE_NAME") + + const scriptPath = path.join(os.tmpdir(), `update.${process.platform === "win32" ? "bat" : "sh"}`) + fs.writeFileSync(scriptPath, scriptContent) + return scriptPath +} +// 标记是否需要热更新 +let shouldPerformHotUpdate = false +let isReadyUpdate = false +// 更新临时目录路径 +// 使用应用名称和随机字符串创建唯一的临时目录 +const updateTempDirPath = path.join(os.tmpdir(), `${app.getName()}-update-${Math.random().toString(36).substring(2, 15)}`) +app.once("will-quit", event => { + if (!shouldPerformHotUpdate) return + event.preventDefault() + const appPath = app.getAppPath() + const appExePath = process.execPath + const exeName = path.basename(appExePath) + // 生成动态脚本 + const scriptPath = generateUpdateScript() + + fs.chmodSync(scriptPath, 0o755) + + // 执行脚本 + const child = spawn(scriptPath, [], { + detached: true, + shell: true, + env: { + APP_PATH: appPath, + UPDATE_DIR: updateTempDirPath, + EXE_PATH: appExePath, + EXE_NAME: exeName, + }, + }) + child.unref() + app.exit() +}) + +// 下载热更新包 +export async function fetchHotUpdatePackage(updatePackageUrl: string) { + if (isReadyUpdate) return + + // 清除临时目录 + clearUpdateTempDir() + // 创建临时目录 + if (!fs.existsSync(updateTempDirPath)) { + fs.mkdirSync(updateTempDirPath, { recursive: true }) + } + + // 下载文件的本地保存路径 + const downloadPath = path.join(updateTempDirPath, "update.zip") + + try { + // 使用 fetch 下载更新包 + const arrayBuffer = await download({ + url: updatePackageUrl, + onprocess(now, all) { + logger.debug(`下载进度: ${((now / all) * 100).toFixed(2)}%`) + emit(EventEnum.UPDATE_PROGRESS, { percent: (now / all) * 100, now, all }) + }, + }) + fs.writeFileSync(downloadPath, Buffer.from(arrayBuffer)) + // 解压更新包 + await extract(downloadPath, { dir: updateTempDirPath }) + + // 删除下载的zip文件 + fs.unlinkSync(downloadPath) + isReadyUpdate = true + } catch (error) { + logger.debug("热更新包下载失败:", error) + throw error + } +} + +function clearUpdateTempDir() { + if (!fs.existsSync(updateTempDirPath)) return + fs.rmSync(updateTempDirPath, { recursive: true }) +} + +export function flagNeedUpdate() { + shouldPerformHotUpdate = true +} diff --git a/packages/helper/updater/main/index.ts b/packages/helper/updater/main/index.ts new file mode 100644 index 0000000..c3f3fcf --- /dev/null +++ b/packages/helper/updater/main/index.ts @@ -0,0 +1,137 @@ +import pkg from "electron-updater" +import { app, dialog } from "electron" +import Setting from "setting/main" +import EventEmitter from "events" +import { BaseSingleton } from "base" +import { fetchHotUpdatePackage, flagNeedUpdate } from "./hot" +import Locales from "locales/main" +import _logger from "logger/main" + +const logger = _logger.createNamespace("updater") +const { autoUpdater } = pkg + +class _Updater extends BaseSingleton { + public events = new EventEmitter() + private timer: ReturnType | null = null + // autoReplace = false + async triggerHotUpdate(autoReplace = false) { + const url = Setting.values("update.hoturl") + await fetchHotUpdatePackage(url) + flagNeedUpdate() + if (!autoReplace) { + dialog.showMessageBox({ + title: Locales.t("update.ready.hot.title"), + message: Locales.t("update.ready.hot.desc", { version: app.getVersion() }), + }) + } else { + app.quit() + } + } + + constructor() { + super() + // 配置自动更新 + autoUpdater.autoDownload = false + autoUpdater.autoInstallOnAppQuit = true + + // 检查更新错误 + autoUpdater.on("error", error => { + logger.debug("Update error:", error) + }) + + // 检查更新 + autoUpdater.on("checking-for-update", () => { + logger.debug("Checking for updates...") + }) + + // 有可用更新 + autoUpdater.on("update-available", info => { + logger.debug("Update available:", info) + this.promptUserToUpdate() + }) + + // 没有可用更新 + autoUpdater.on("update-not-available", info => { + logger.debug("Update not available:", info) + }) + + // 更新下载进度 + autoUpdater.on("download-progress", progressObj => { + logger.debug( + `Download speed: ${progressObj.bytesPerSecond} - Downloaded ${progressObj.percent}% (${progressObj.transferred}/${progressObj.total})`, + ) + }) + + // 更新下载完成 + autoUpdater.on("update-downloaded", info => { + logger.debug("Update downloaded:", info) + this.promptUserToInstall() + }) + } + + init() { + // 定期检查更新 + this.checkForUpdates() + this.timer && clearInterval(this.timer) + this.timer = setInterval( + () => { + this.checkForUpdates() + }, + 1000 * 60 * 60, + ) // 每小时检查一次 + } + + destroy() { + // 清理工作 + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + } + + private async checkForUpdates() { + if (app.isPackaged) { + try { + await autoUpdater.checkForUpdates() + logger.debug("Updater初始化检查成功.") + } catch (error) { + logger.debug("Failed to check for updates:", error) + } + } else { + logger.debug("正在开发模式,跳过更新检查.") + } + } + + private async promptUserToUpdate() { + const result = await dialog.showMessageBox({ + type: "info", + title: "发现新版本", + message: "是否下载新版本?", + buttons: ["下载", "暂不更新"], + defaultId: 0, + }) + + if (result.response === 0) { + autoUpdater.downloadUpdate() + } + } + + private async promptUserToInstall() { + const result = await dialog.showMessageBox({ + type: "info", + title: "更新已就绪", + message: "新版本已下载完成,是否立即安装?", + buttons: ["立即安装", "稍后安装"], + defaultId: 0, + }) + + if (result.response === 0) { + autoUpdater.quitAndInstall(false, true) + } + } +} + +const Updater = _Updater.getInstance() + +export { Updater } +export default Updater diff --git a/packages/helper/updater/renderer.ts b/packages/helper/updater/renderer.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/logger/main.ts b/packages/logger/main.ts index 5c4da62..a271fce 100644 --- a/packages/logger/main.ts +++ b/packages/logger/main.ts @@ -5,7 +5,6 @@ import setting from "setting/main" import * as rfs from "rotating-file-stream" import { LogLevel, LogLevelColor, LogLevelName } from "./common" - // 重置颜色的ANSI代码 const RESET_COLOR = "\x1b[0m" diff --git a/packages/setting/main.ts b/packages/setting/main.ts index 6bd3425..ea35d8d 100644 --- a/packages/setting/main.ts +++ b/packages/setting/main.ts @@ -4,9 +4,9 @@ import path from "path" import { cloneDeep } from "lodash" import Config from "config" import type { IDefaultConfig } from "config" -import _debug from "debug" +import _logger from "logger/main" -const debug = _debug("app:setting") +const logger = _logger.createNamespace("setting") type IConfig = IDefaultConfig @@ -59,7 +59,7 @@ function isEmptyDir(fPath: string) { class SettingClass { constructor() { - debug(`Setting inited`) + logger.debug(`Setting inited`) this.init() } @@ -122,7 +122,7 @@ class SettingClass { } } init() { - debug(`位置:${this.#pathFile}`) + logger.debug(`位置:${this.#pathFile}`) if (fs.pathExistsSync(this.#pathFile)) { const confingPath = fs.readFileSync(this.#pathFile, { encoding: "utf8" }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cfc77cd..e0607d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,6 +78,9 @@ importers: '@vueuse/core': specifier: ^12.7.0 version: 12.7.0(typescript@5.7.3) + base: + specifier: workspace:* + version: link:packages/base debug: specifier: ^4.4.0 version: 4.4.0 @@ -99,6 +102,9 @@ importers: extract-zip: specifier: ^2.0.1 version: 2.0.1 + helper: + specifier: workspace:* + version: link:packages/helper locales: specifier: workspace:* version: link:packages/locales @@ -178,6 +184,10 @@ importers: specifier: ^2.1.10 version: 2.1.10(typescript@5.7.3) + packages/base: {} + + packages/helper: {} + packages/locales: {} packages/logger: {} diff --git a/src/common/_ioc.main.ts b/src/common/_ioc.main.ts index 7ba0ba9..067c1be 100644 --- a/src/common/_ioc.main.ts +++ b/src/common/_ioc.main.ts @@ -12,7 +12,12 @@ const modules = new ContainerModule(bind => { const CommandClass = (module as { default: any }).default if (CommandClass) { const className = CommandClass.name.replace("Command", "") - bind(className + "Command").to(CommandClass).inSingletonScope() + if (CommandClass["init"]) { + CommandClass["init"]() + } + bind(className + "Command") + .to(CommandClass) + .inSingletonScope() } }) }) diff --git a/src/common/event/PlatForm/index.ts b/src/common/event/PlatForm/index.ts index d03501a..423d0b9 100644 --- a/src/common/event/PlatForm/index.ts +++ b/src/common/event/PlatForm/index.ts @@ -1,8 +1,8 @@ -import { _Base } from "common/lib/_Base" import { ApiFactory } from "common/lib/abstract" +import { BaseSingleton } from "base" import { LogLevel } from "packages/logger/common" -class PlatForm extends _Base { +class PlatForm extends BaseSingleton { constructor() { super() } diff --git a/src/common/event/Snippet/hook.ts b/src/common/event/Snippet/hook.ts index e4a24bb..3a89407 100644 --- a/src/common/event/Snippet/hook.ts +++ b/src/common/event/Snippet/hook.ts @@ -1,5 +1,5 @@ import { Snippet } from "." export function useSnippet() { - return Snippet.getInstance() + return Snippet.getInstance() } diff --git a/src/common/event/Snippet/index.ts b/src/common/event/Snippet/index.ts index 18f789c..5cf9945 100644 --- a/src/common/event/Snippet/index.ts +++ b/src/common/event/Snippet/index.ts @@ -1,7 +1,7 @@ -import { _Base } from "common/lib/_Base" +import { BaseSingleton } from "base" import { ApiFactory } from "common/lib/abstract" -class Snippet extends _Base { +class Snippet extends BaseSingleton { constructor() { super() } diff --git a/src/common/event/Tabs/index.ts b/src/common/event/Tabs/index.ts index f36ca59..de0025b 100644 --- a/src/common/event/Tabs/index.ts +++ b/src/common/event/Tabs/index.ts @@ -1,6 +1,6 @@ -import { _Base } from "../../lib/_Base" +import { BaseSingleton } from "base" -export class Tabs extends _Base { +export class Tabs extends BaseSingleton { constructor() { super() } diff --git a/src/common/event/Updater/index.ts b/src/common/event/Updater/index.ts new file mode 100644 index 0000000..c31799e --- /dev/null +++ b/src/common/event/Updater/index.ts @@ -0,0 +1,15 @@ +import { EventEnum } from "helper/updater/common" + +const curProgress = ref(0) + +api.on(EventEnum.UPDATE_PROGRESS, ({ percent, now, all }) => { + curProgress.value = percent +}) + +function useUpdate() { + return { + curProgress, + } +} + +export { useUpdate } diff --git a/src/common/event/Updater/main/command.ts b/src/common/event/Updater/main/command.ts new file mode 100644 index 0000000..8ba7617 --- /dev/null +++ b/src/common/event/Updater/main/command.ts @@ -0,0 +1,15 @@ +import Updater from "helper/updater/main" +import _logger from "logger/main" + +const logger = _logger.createNamespace("UpdaterCommand") + +export default class UpdaterCommand { + static init() { + // 命令初始化 + logger.debug("UpdaterCommand init") + } + + async triggerHotUpdate() { + Updater.triggerHotUpdate() + } +} diff --git a/src/common/event/common.ts b/src/common/event/common.ts deleted file mode 100644 index a90403b..0000000 --- a/src/common/event/common.ts +++ /dev/null @@ -1,5 +0,0 @@ -const keys = ["hot-update-ready"] as const - -type AllKeys = (typeof keys)[number] - -export type { AllKeys } diff --git a/src/common/event/update/index.ts b/src/common/event/update/index.ts deleted file mode 100644 index 55676c4..0000000 --- a/src/common/event/update/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -// import type { AllKeys } from "../common" - -const curProgress = ref(0) -// api.on("progress", () => { -// curProgress.value = 10 -// }) - -function useUpdate() { - return { - curProgress, - } -} - -export { useUpdate } diff --git a/src/common/event/update/main/command.ts b/src/common/event/update/main/command.ts deleted file mode 100644 index 069ece6..0000000 --- a/src/common/event/update/main/command.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { inject } from "inversify" -import Updater from "main/modules/updater" - -export default class PlatFormCommand { - constructor(@inject(Updater) private _Updater: Updater) {} - - async triggerHotUpdate() { - await this._Updater.triggerHotUpdate() - } -} diff --git a/src/common/event/update/main/index.ts b/src/common/event/update/main/index.ts deleted file mode 100644 index 9aa935d..0000000 --- a/src/common/event/update/main/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { broadcast } from "main/utils" -import { AllKeys } from "common/event/common" - -function emitHotUpdateReady(...argu) { - broadcast("hot-update-ready", ...argu) -} - -export { emitHotUpdateReady } diff --git a/src/common/lib/_Base.ts b/src/common/lib/_Base.ts deleted file mode 100644 index 1638ca1..0000000 --- a/src/common/lib/_Base.ts +++ /dev/null @@ -1,12 +0,0 @@ -export abstract class _Base { - static instance - - static getInstance(): T { - if (!this.instance) { - // 如果实例不存在,则创建一个新的实例 - // @ts-ignore ... - this.instance = new this() - } - return this.instance - } -} diff --git a/src/common/readme.md b/src/common/readme.md new file mode 100644 index 0000000..51c0c10 --- /dev/null +++ b/src/common/readme.md @@ -0,0 +1,7 @@ +## event + +通用事件处理模块 + +- main/**/* 处理主进程的模块 +- main/command.ts 会通过ioc收集,进入依赖管理中 +- 其他 处理渲染进程的模块 \ No newline at end of file diff --git a/src/main/App.ts b/src/main/App.ts index 030f161..8976300 100644 --- a/src/main/App.ts +++ b/src/main/App.ts @@ -10,9 +10,7 @@ import BaseClass from "./base/base" import IOC from "./_ioc" import DB from "./modules/db" import Zephyr from "./modules/zephyr" -import Updater from "./modules/updater" import { crashHandler } from "logger/crash-handler" -import { eventbus } from "./event" protocol.registerSchemesAsPrivileged([ // { @@ -44,12 +42,6 @@ protocol.registerSchemesAsPrivileged([ @injectable() class App extends BaseClass { - - static events = { - AppInit: "App.init", - AppReady: "App.ready", - } - destroy() { this._IOC.destroy() // 这里是应用正常退出, 可以检测应用是不是非正常退出,比如应用启动时记录一个启动时间并删除上一次结束时间和开始时间,结束时记录一个结束时间, @@ -63,7 +55,6 @@ class App extends BaseClass { @inject(DB) private _DB: DB, @inject(WindowManager) private _WindowManager: WindowManager, @inject(Zephyr) private _Zephyr: Zephyr, - @inject(Updater) private _Updater: Updater, ) { super() } @@ -73,10 +64,8 @@ class App extends BaseClass { // 主进程中添加如下代码即可 app.commandLine.appendSwitch("wm-window-animations-disabled") // 开启硬件加速 - app.disableHardwareAcceleration(); - eventbus.emit(App.events.AppInit) + app.disableHardwareAcceleration() crashHandler.init() - this._Updater.init() this._DB.init() this._Command.init() this._WindowManager.init() @@ -91,7 +80,6 @@ class App extends BaseClass { color: "#F8F8F8", symbolColor: "#000000", }) - eventbus.emit(App.events.AppReady) }) app.on("will-quit", () => { this.destroy() diff --git a/src/main/base/base.ts b/src/main/base/base.ts index c4b2260..c04c2ac 100644 --- a/src/main/base/base.ts +++ b/src/main/base/base.ts @@ -49,10 +49,7 @@ // export { BaseClass } // export default BaseClass -import EventEmitter from "node:events" - abstract class BaseClass { - public _events = new EventEmitter() abstract init(...argus: any[]) abstract destroy() } diff --git a/src/main/debug.ts b/src/main/debug.ts new file mode 100644 index 0000000..f3c0e84 --- /dev/null +++ b/src/main/debug.ts @@ -0,0 +1,60 @@ +import debug from "debug" +import { app } from "electron" +import path from "node:path" +import logger from "logger/main" +import * as rfs from "rotating-file-stream" +import fs from "fs" + +// 配置根目录 +const logsPath = app.getPath("logs") +logger.debug(`日志地址:${logsPath}`) + +const LOG_ROOT = path.join(logsPath) + +// 缓存当前应用启动的日志文件流 +let currentLogStream: rfs.RotatingFileStream | null = null + +// 生成当前启动时的日志文件名 +const getLogFileName = () => { + const now = new Date() + const timestamp = now.toISOString().replace(/[:.]/g, "-") + return `app-${timestamp}.log` +} + +// 覆盖 debug.log 方法 +const originalLog = debug.log +debug.log = function (...args) { + // 保留原始控制台输出 + originalLog.apply(this, args) + + // 确保日志目录存在 + if (!fs.existsSync(LOG_ROOT)) { + fs.mkdirSync(LOG_ROOT, { recursive: true }) + } + + // 延迟初始化日志流,直到第一次写入 + if (!currentLogStream) { + const logFileName = getLogFileName() + currentLogStream = rfs.createStream(logFileName, { + path: LOG_ROOT, + size: "10M", // 单个文件最大 10MB + rotate: 10, // 保留最近 10 个文件 + }) + } + + // @ts-ignore 获取当前命名空间 + const namespace = this.namespace || "unknown" + + // 写入日志(添加时间戳和命名空间) + const timestamp = new Date().toISOString() + const message = args.join(" ") + currentLogStream.write(`[${timestamp}] [${namespace}] ${message}\n`) +} + +app.on("before-quit", () => { + if (currentLogStream) { + currentLogStream.end() + currentLogStream.destroy() + currentLogStream = null + } +}) diff --git a/src/main/index.ts b/src/main/index.ts index e3eae03..a59ced2 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,73 +1,11 @@ import "reflect-metadata" +import "./debug" +import "setting/main" import "logger/main" import "logger/main-error" -import "setting/main" import { _ioc } from "main/_ioc" import { App } from "main/App" -import debug from "debug" -import fs from "fs" -import path from "path" -import * as rfs from "rotating-file-stream" -import { app } from "electron" - -// 配置根目录 -const logsPath = app.getPath("logs") -console.log(`日志地址:${logsPath}`) - -const LOG_ROOT = path.join(logsPath) - -// 缓存当前应用启动的日志文件流 -let currentLogStream: rfs.RotatingFileStream | null = null - -// 生成当前启动时的日志文件名 -const getLogFileName = () => { - const now = new Date() - const timestamp = now.toISOString().replace(/[:.]/g, '-') - return `app-${timestamp}.log` -} - -// 覆盖 debug.log 方法 -const originalLog = debug.log -debug.log = function (...args) { - // 保留原始控制台输出 - originalLog.apply(this, args) - - // 确保日志目录存在 - if (!fs.existsSync(LOG_ROOT)) { - fs.mkdirSync(LOG_ROOT, { recursive: true }) - } - - // 延迟初始化日志流,直到第一次写入 - if (!currentLogStream) { - const logFileName = getLogFileName() - currentLogStream = rfs.createStream(logFileName, { - path: LOG_ROOT, - size: "10M", // 单个文件最大 10MB - rotate: 10, // 保留最近 10 个文件 - }) - } - - // 获取当前命名空间 - // @ts-ignore - const namespace = this.namespace || 'unknown' - - // 写入日志(添加时间戳和命名空间) - const timestamp = new Date().toISOString() - const message = args.join(" ") - currentLogStream.write(`[${timestamp}] [${namespace}] ${message}\n`) -} - const curApp = _ioc.get(App) curApp.init() - -const _debug = debug("app:app") -app.on("before-quit", () => { - _debug("应用关闭") - if (currentLogStream) { - currentLogStream.end() - currentLogStream.destroy() - currentLogStream = null - } -}) diff --git a/src/main/modules/_ioc.ts b/src/main/modules/_ioc.ts index 52cfab7..f46fcd1 100644 --- a/src/main/modules/_ioc.ts +++ b/src/main/modules/_ioc.ts @@ -5,11 +5,9 @@ import { WindowManager } from "./window-manager" import { Tabs } from "./tabs" import Commands from "./commands" import Zephyr from "./zephyr" -import Updater from "./updater" const modules = new ContainerModule(bind => { bind(Zephyr).toSelf().inSingletonScope() - bind(Updater).toSelf().inSingletonScope() bind(Api).toSelf().inSingletonScope() bind(WindowManager).toSelf().inSingletonScope() bind(Commands).toSelf().inSingletonScope() @@ -21,7 +19,6 @@ async function destroyAllModules(ioc: Container) { await Promise.all([ ioc.get(WindowManager).destroy(), ioc.get(Commands).destroy(), - ioc.get(Updater).destroy(), ioc.get(Zephyr).destroy(), ioc.get(Tabs).destroy(), ioc.get(Api).destroy(), diff --git a/src/main/modules/db/index.ts b/src/main/modules/db/index.ts index ce5db72..0d9d22e 100644 --- a/src/main/modules/db/index.ts +++ b/src/main/modules/db/index.ts @@ -3,14 +3,14 @@ import Setting from "setting/main" import { CustomAdapter, CustomLow } from "./custom" import path from "node:path" import BaseClass from "main/base/base" -import _debug from "debug" +import _logger from "logger/main" -const debug = _debug("app:db") +const logger = _logger.createNamespace("db") @injectable() class DB extends BaseClass { destroy() { - debug(`DB destroy`) + logger.debug(`DB destroy`) } Modules: Record> = {} diff --git a/src/main/modules/tabs/Tab.ts b/src/main/modules/tabs/Tab.ts index 9f7b1ab..007d322 100644 --- a/src/main/modules/tabs/Tab.ts +++ b/src/main/modules/tabs/Tab.ts @@ -5,8 +5,9 @@ import _debug from "debug" // import { Layout } from "./Constant" import FuckHTML from "@res/fuck.html?asset" import { fileURLToPath, pathToFileURL } from "node:url" +import EventEmitter from "node:events" -const debug = _debug("app:tab") +const debug = _debug("tab") interface IOption { url: string @@ -24,6 +25,7 @@ class Tab extends BaseClass { init() { // TODO } + public events = new EventEmitter() public url: string = "" public showUrl: string = "" public title: string = "" @@ -55,10 +57,6 @@ class Tab extends BaseClass { return this.active } - get events() { - return this._events - } - constructor(options = {}, window: BrowserWindow, curRect?: IRect) { super() this.listenResize = this.listenResize.bind(this) diff --git a/src/main/modules/tabs/index.ts b/src/main/modules/tabs/index.ts index c60643e..4be45d8 100644 --- a/src/main/modules/tabs/index.ts +++ b/src/main/modules/tabs/index.ts @@ -11,7 +11,7 @@ interface IRect { height: number } -const debug = _debug("app:tabs") +const debug = _debug("tabs") class Tabs extends BaseClass { destroy() { diff --git a/src/main/modules/updater/hot/index.ts b/src/main/modules/updater/hot/index.ts deleted file mode 100644 index 7e77cf6..0000000 --- a/src/main/modules/updater/hot/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { spawn } from "node:child_process" -import fs from "node:fs" -import path from "node:path" -import os from "node:os" -import { app } from "electron" -import extract from "extract-zip" -import { emitHotUpdateReady } from "common/event/Update/main" - -import _debug from "debug" -const debug = _debug("app:hot-updater") - -function getUpdateScriptTemplate() { - return process.platform === "win32" - ? ` - @echo off - timeout /t 2 - taskkill /IM "{{EXE_NAME}}" /F - xcopy /Y /E "{{UPDATE_DIR}}\\*" "{{APP_PATH}}" - start "" "{{EXE_PATH}}" - ` - : ` - #!/bin/bash - sleep 2 - pkill -f "{{EXE_NAME}}" - cp -Rf "{{UPDATE_DIR}}/*" "{{APP_PATH}}/" - open "{{EXE_PATH}}" - ` -} - -function generateUpdateScript() { - const scriptContent = getUpdateScriptTemplate() - .replace(/{{APP_PATH}}/g, process.platform === "win32" ? "%APP_PATH%" : "$APP_PATH") - .replace(/{{UPDATE_DIR}}/g, process.platform === "win32" ? "%UPDATE_DIR%" : "$UPDATE_DIR") - .replace(/{{EXE_PATH}}/g, process.platform === "win32" ? "%EXE_PATH%" : "$EXE_PATH") - .replace(/{{EXE_NAME}}/g, process.platform === "win32" ? "%EXE_NAME%" : "$EXE_NAME") - - const scriptPath = path.join(os.tmpdir(), `update.${process.platform === "win32" ? "bat" : "sh"}`) - fs.writeFileSync(scriptPath, scriptContent) - return scriptPath -} -// 标记是否需要热更新 -let shouldPerformHotUpdate = false -let isReadyUpdate = false -// 更新临时目录路径 -// 使用应用名称和随机字符串创建唯一的临时目录 -const updateTempDirPath = path.join(os.tmpdir(), `${app.getName()}-update-${Math.random().toString(36).substring(2, 15)}`) -app.once("will-quit", event => { - if (!shouldPerformHotUpdate) return - event.preventDefault() - const appPath = app.getAppPath() - const appExePath = process.execPath - const exeName = path.basename(appExePath) - // 生成动态脚本 - const scriptPath = generateUpdateScript() - - fs.chmodSync(scriptPath, 0o755) - - // 执行脚本 - const child = spawn(scriptPath, [], { - detached: true, - shell: true, - env: { - APP_PATH: appPath, - UPDATE_DIR: updateTempDirPath, - EXE_PATH: appExePath, - EXE_NAME: exeName, - }, - }) - child.unref() - app.exit() -}) - -// 下载热更新包 -export async function fetchHotUpdatePackage(updatePackageUrl: string = "https://example.com/updates/latest.zip") { - if (isReadyUpdate) return - - // 清除临时目录 - clearUpdateTempDir() - // 创建临时目录 - if (!fs.existsSync(updateTempDirPath)) { - fs.mkdirSync(updateTempDirPath, { recursive: true }) - } - - // 下载文件的本地保存路径 - const downloadPath = path.join(updateTempDirPath, "update.zip") - - try { - // 使用 fetch 下载更新包 - const response = await fetch(updatePackageUrl) - if (!response.ok) { - throw new Error(`下载失败: ${response.status} ${response.statusText}`) - } - - // 将下载内容写入文件 - const arrayBuffer = await response.arrayBuffer() - fs.writeFileSync(downloadPath, Buffer.from(arrayBuffer)) - - // 解压更新包 - await extract(downloadPath, { dir: updateTempDirPath }) - - // 删除下载的zip文件 - fs.unlinkSync(downloadPath) - isReadyUpdate = true - emitHotUpdateReady() - } catch (error) { - debug("热更新包下载失败:", error) - throw error - } -} - -function clearUpdateTempDir() { - if (!fs.existsSync(updateTempDirPath)) return - fs.rmSync(updateTempDirPath, { recursive: true }) -} - -export function flagNeedUpdate() { - shouldPerformHotUpdate = true -} diff --git a/src/main/modules/updater/index.ts b/src/main/modules/updater/index.ts deleted file mode 100644 index 81d9924..0000000 --- a/src/main/modules/updater/index.ts +++ /dev/null @@ -1,133 +0,0 @@ -import pkg from "electron-updater" -import { app, dialog } from "electron" -import { injectable } from "inversify" -import BaseClass from "main/base/base" -// import { Setting } from "../setting" -import _debug from "debug" -import EventEmitter from "events" -import { fetchHotUpdatePackage, flagNeedUpdate } from "./hot" -import Locales from "locales/main" - -const debug = _debug("app:updater") -const { autoUpdater } = pkg - -@injectable() -export class Updater extends BaseClass { - public events = new EventEmitter() - private timer: ReturnType | null = null - // autoReplace = false - async triggerHotUpdate(autoReplace = false) { - await fetchHotUpdatePackage() - flagNeedUpdate() - if (!autoReplace) { - dialog.showMessageBox({ - title: Locales.t("update.ready.hot.title"), - message: Locales.t("update.ready.hot.desc", { version: app.getVersion() }), - }) - } else { - app.quit() - } - } - - constructor() { - super() - - // 配置自动更新 - autoUpdater.autoDownload = false - autoUpdater.autoInstallOnAppQuit = true - - // 检查更新错误 - autoUpdater.on("error", error => { - debug("Update error:", error) - }) - - // 检查更新 - autoUpdater.on("checking-for-update", () => { - debug("Checking for updates...") - }) - - // 有可用更新 - autoUpdater.on("update-available", info => { - debug("Update available:", info) - this.promptUserToUpdate() - }) - - // 没有可用更新 - autoUpdater.on("update-not-available", info => { - debug("Update not available:", info) - }) - - // 更新下载进度 - autoUpdater.on("download-progress", progressObj => { - debug( - `Download speed: ${progressObj.bytesPerSecond} - Downloaded ${progressObj.percent}% (${progressObj.transferred}/${progressObj.total})`, - ) - }) - - // 更新下载完成 - autoUpdater.on("update-downloaded", info => { - debug("Update downloaded:", info) - this.promptUserToInstall() - }) - } - - init() { - // 定期检查更新 - this.checkForUpdates() - this.timer && clearInterval(this.timer) - this.timer = setInterval( - () => { - this.checkForUpdates() - }, - 1000 * 60 * 60, - ) // 每小时检查一次 - } - - destroy() { - // 清理工作 - if (this.timer) { - clearInterval(this.timer) - this.timer = null - } - } - - private async checkForUpdates() { - if (app.isPackaged) { - try { - await autoUpdater.checkForUpdates() - } catch (error) { - debug("Failed to check for updates:", error) - } - } - } - - private async promptUserToUpdate() { - const result = await dialog.showMessageBox({ - type: "info", - title: "发现新版本", - message: "是否下载新版本?", - buttons: ["下载", "暂不更新"], - defaultId: 0, - }) - - if (result.response === 0) { - autoUpdater.downloadUpdate() - } - } - - private async promptUserToInstall() { - const result = await dialog.showMessageBox({ - type: "info", - title: "更新已就绪", - message: "新版本已下载完成,是否立即安装?", - buttons: ["立即安装", "稍后安装"], - defaultId: 0, - }) - - if (result.response === 0) { - autoUpdater.quitAndInstall(false, true) - } - } -} - -export default Updater diff --git a/src/main/modules/window-manager/index.ts b/src/main/modules/window-manager/index.ts index 975d10b..f3fa8c4 100644 --- a/src/main/modules/window-manager/index.ts +++ b/src/main/modules/window-manager/index.ts @@ -3,7 +3,6 @@ import { cloneDeep, merge } from "lodash" import { defaultConfig, defaultWindowConfig, getWindowsMap, IConfig, Param } from "./windowsMap" import { optimizer } from "@electron-toolkit/utils" import BaseClass from "main/base/base" -import _debug from "debug" import _logger from "logger/main" const logger = _logger.createNamespace("modlue:window-manager") // _debug("app:window-manager") @@ -66,7 +65,7 @@ export default class WindowManager extends BaseClass { } createWindow(name: string, opts?: Partial){ - let info = opts as Param + const info = opts as Param info.name = name if (!info.ignoreEmptyUrl && !info.url) { dialog.showErrorBox("错误", name + "窗口未提供url") diff --git a/src/main/modules/zephyr/index.ts b/src/main/modules/zephyr/index.ts index b812250..a5e3389 100644 --- a/src/main/modules/zephyr/index.ts +++ b/src/main/modules/zephyr/index.ts @@ -1,12 +1,12 @@ import { session, net } from "electron" import { injectable } from "inversify" import BaseClass from "main/base/base" -import _debug from "debug" +import _logger from "logger/main" import fs from "fs" import path from "path" import { app } from "electron" -const debug = _debug("app:zephyr") +const logger = _logger.createNamespace("zephyr") /** * Zephyr 模块 - 安全的本地文件访问协议 @@ -108,7 +108,7 @@ class Zephyr extends BaseClass { super() this.interceptHandlerZephyr = this.interceptHandlerZephyr.bind(this) this.initLogFile() - debug("zephyr init") + logger.debug("zephyr init") } private async initLogFile() { @@ -135,7 +135,7 @@ class Zephyr extends BaseClass { const count = this.rateLimiter.get(filePath) || 0 if (count >= this.MAX_REQUESTS) { - debug("访问频率超限:", filePath) + logger.debug("访问频率超限:", filePath) return true } @@ -164,7 +164,7 @@ class Zephyr extends BaseClass { try { await fs.promises.appendFile(this.LOG_FILE, JSON.stringify(logEntry) + "\n", "utf8") } catch (error) { - debug("写入审计日志失败:", error) + logger.debug("写入审计日志失败:", error) } } @@ -197,18 +197,17 @@ class Zephyr extends BaseClass { ses.protocol.unhandle("zephyr") this.fileLocks.clear() this.rateLimiter.clear() - debug("zephyr destroyed") } init(partition?: string) { const ses = partition ? session.fromPartition(partition) : session.defaultSession ses.protocol.handle("zephyr", this.interceptHandlerZephyr) - debug("zephyr initialized with partition:", partition) + logger.debug("zephyr initialized with partition:", partition) } setAllowedPaths(config: Partial) { Object.assign(this.pathConfig, config) - debug("Updated allowed paths:", this.pathConfig) + logger.debug("Updated allowed paths:", this.pathConfig) } private isValidPath(filePath: string): boolean { @@ -233,32 +232,32 @@ class Zephyr extends BaseClass { try { // 1. 基本路径检查 if (!this.isValidPath(filePath)) { - debug("不安全的路径字符:", filePath) + logger.debug("不安全的路径字符:", filePath) return false } // 2. 检查是否包含 .. 路径 if (filePath.includes("..")) { - debug("检测到路径遍历尝试") + logger.debug("检测到路径遍历尝试") return false } // 3. 检查符号链接 if (await this.isSymlink(filePath)) { - debug("不允许访问符号链接") + logger.debug("不允许访问符号链接") return false } // 4. 检查文件大小 if (!(await this.checkFileSize(filePath))) { - debug("文件超出大小限制") + logger.debug("文件超出大小限制") return false } // 5. 文件类型检查 const ext = path.extname(filePath).toLowerCase() if (!this.ALLOWED_EXTENSIONS.includes(ext)) { - debug("不允许的文件类型:", ext) + logger.debug("不允许的文件类型:", ext) return false } @@ -274,7 +273,7 @@ class Zephyr extends BaseClass { }) if (!isInAllowedPath) { - debug("路径不在允许范围内") + logger.debug("路径不在允许范围内") return false } @@ -294,7 +293,7 @@ class Zephyr extends BaseClass { return true } catch (error: any) { await this.logAccess(operation, filePath, false, error.message) - debug("路径安全检查错误:", error) + logger.debug("路径安全检查错误:", error) return false } } @@ -314,7 +313,7 @@ class Zephyr extends BaseClass { } if (!(await this.isPathSafe(filePath, operation))) { - debug("访问被拒绝:", filePath) + logger.debug("访问被拒绝:", filePath) return new Response("Access Denied", { status: 403 }) } @@ -328,7 +327,7 @@ class Zephyr extends BaseClass { return new Response("Operation not supported", { status: 400 }) } } catch (error) { - debug("处理请求错误:", error) + logger.debug("处理请求错误:", error) return new Response("Internal Server Error", { status: 500 }) } } @@ -420,7 +419,7 @@ class Zephyr extends BaseClass { case this.OPERATIONS.WRITE: return this.pathConfig.write default: - debug("未知的操作类型:", operation) + logger.debug("未知的操作类型:", operation) return null } } diff --git a/src/main/utils/index.ts b/src/main/utils/index.ts index c485860..11aa880 100644 --- a/src/main/utils/index.ts +++ b/src/main/utils/index.ts @@ -12,7 +12,7 @@ export function getFileUrl(app: string) { return slash(winURL) } -export function getPreloadUrl(file){ +export function getPreloadUrl(file) { return join(__dirname, `../preload/${file}.mjs`) } diff --git a/tsconfig.node.json b/tsconfig.node.json index b15a15f..b85c63b 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -13,12 +13,17 @@ "packages/logger/preload.ts", "packages/logger/preload-error.ts", "packages/logger/common.ts", + "packages/**/*.main.ts", + "packages/**/main/**/*", + "packages/**/main.ts", + "packages/**/*.common.ts", + "packages/**/common.ts", "src/common/**/*.main.ts", "src/common/**/main/**/*", "src/common/**/main.ts", "src/common/**/*.common.ts", "src/common/**/common.ts" -, "src/common/event/_Base.ts" ], + ], "compilerOptions": { "composite": true, "emitDecoratorMetadata": true, @@ -59,6 +64,9 @@ "logger/*": [ "packages/logger/*" ], + "base/*": [ + "packages/base/*" + ], } } } diff --git a/tsconfig.web.json b/tsconfig.web.json index 4aa9783..54f273e 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -13,7 +13,8 @@ "src/types/**/*", "config/**/*", "./typed-router.d.ts", - "src/common/**/*" + "src/common/**/*", + "packages/**/*", ], "exclude": [ "packages/locales/main.ts", @@ -21,6 +22,9 @@ "packages/logger/main.ts", "packages/logger/main-error.ts", "packages/logger/crash-handler.ts", + "packages/**/main/**/*", + "packages/**/*.main.ts", + "packages/**/main.ts", "src/common/**/main/**/*", "src/common/**/*.main.ts", "src/common/**/main.ts" @@ -60,6 +64,9 @@ "@res/*": [ "resources/*" ], + "base/*": [ + "packages/base/*" + ], } } }