Sabaki 调试指南:开启 DevTools、settings.json 配置机制与 Electron 调试通道详解
桌面应用【免费下载链接】SabakiAn elegant Go board and SGF editor for a more civilized age.项目地址https://gitcode.com/gh_mirrors/sa/Sabaki点击查看免费下载本文基于 docs/guides/debugging.md 展开讲解如何为 Sabaki 这款基于 Electron 的围棋 SGF 编辑器开启 Chrome 开发者工具DevTools从定位跨平台的settings.json、修改debug.dev_tools配置项到理解 Developer 菜单 的注入条件、菜单点击事件经 IPC 到达主进程toggleDevTools()的完整调用链。读完本文你既能按文档一步步打开开发者工具也能读懂其背后的实现原理并掌握 GTP 引擎日志、未捕获异常弹窗等辅助排障手段。一、为什么 Sabaki 的调试方式是这样的Electron 架构背景Sabaki 是一个用 HTML、CSS 和 JavaScript 编写的桌面应用构建于 Electronpackage.json 的 devDependencies 中锁定为electron: ^43.0.0。由于 Electron 内嵌 Chromium它天然带有与 Chrome 完全一致的开发者工具这一点在 docs/README.md 的 Development 栏目中与 构建与测试指南 并列收录。Sabaki 的代码分为主进程与渲染进程两层这直接决定了调试入口的形态主进程入口是 src/main.js负责创建BrowserWindow、构建应用菜单buildMenu()、注册 IPC 处理器setupIpcHandlers()渲染进程加载 index.html 及其打包产物业务逻辑集中在 src/modules/sabaki.js 等模块中src/preload.js 通过window.sabaki全局对象向渲染进程暴露一组受控的桥接 API窗口操作、WebContents 操作、对话框、设置读写等。因为 DevTools 的开关属于主进程对webContents的控制Sabaki 没有把它的入口放在界面里而是设计成“配置驱动”只有当用户显式开启调试开关后菜单栏中才会出现 Developer 菜单。下文先给出官方文档的完整操作步骤再逐层拆解实现。二、开启开发者工具官方标准操作步骤以下为 docs/guides/debugging.md 的完整操作流程。由于 Sabaki 在运行时会随时把内存中的设置写回settings.json第 1 步要求先关闭 Sabaki避免你的修改被覆盖丢失。第 1 步必要时先关闭 Sabaki。第 2 步确定 Sabaki 存放设置的目录。三个平台的位置分别是平台设置目录Windows%APPDATA%\SabakiLinux$XDG_CONFIG_HOME/Sabaki或~/.config/SabakimacOS~/Library/Application Support/Sabaki第 3 步打开settings.json搜索键debug.dev_tools。第 4 步把值改为true并保存settings.json。第 5 步启动 Sabaki主菜单栏会多出一个名为 Developer 的菜单。第 6 步点击菜单中的 Toggle Developer Tools即可开关 DevTools。说明如果settings.json中根本搜不到debug.dev_tools这个键说明该键尚未被写入过——Sabaki 首次启动时会用内置默认值补全所有缺失键见下文 3.2 节的加载逻辑默认值就是false。你也可以手动新增debug.dev_tools: true这一行效果相同。三、debug.dev_tools配置项与 settings.json 的加载机制3.1 设置目录与 settings.json 的确定位置上述“设置目录”并非文档的口头约定而是 src/setting.js 在模块加载时计算并导出的const portableDir process.env.PORTABLE_EXECUTABLE_DIR for (let dir of [ (exports.userDataDirectory portableDir ? path.join(portableDir, Sabaki) : app.getPath(userData)), (exports.themesDirectory path.join(exports.userDataDirectory, themes)), ]) { ... } exports.settingsPath path.join(exports.userDataDirectory, settings.json)两点值得注意app.getPath(userData)是 Electron 按操作系统约定生成的用户数据目录对应文档中列出的%APPDATA%\Sabaki、~/.config/Sabaki、~/Library/Application Support/Sabaki三种路径如果设置了PORTABLE_EXECUTABLE_DIR环境变量即使用绿色便携版运行设置会改存到可执行文件旁的Sabaki/子目录而不是系统用户目录——便携版用户修改的是便携目录下的settings.json这与文档列出的三个常规位置不同是实际调试时容易踩的坑。同时该目录下的styles.css用户样式表也会在首次运行时自动生成同样可用于调试样式问题。3.2debug.dev_tools的默认值与“只认已知键”的加载规则debug.dev_tools的默认值定义在 src/setting.js 的defaults表中let defaults { ... debug.dev_tools: false, ... }Sabaki 目前唯一的debug.*前缀配置项就是这个键它是整个调试能力的总开关。setting.load()src/setting.js的加载规则对手动编辑settings.json的人特别重要exports.load function () { try { settings JSON.parse(fs.readFileSync(exports.settingsPath, utf8)) } catch (err) { settings {} } // Load default settings for (let key in defaults) { if (key in settings) continue settings[key] defaults[key] } // Delete invalid settings for (let key in settings) { if (key in defaults) continue delete settings[key] } ... }键不存在 → 补默认值所以首次启动后settings.json会自动包含完整的键集合键不在默认表中 → 直接删除如果你手误把键名写成debug.devtools或其他变体它不仅不生效还会在下次load()/save()时被静清理掉。改配置前务必核对 src/setting.js 中的键名拼写JSON 解析失败 → 回退为空对象也就是说把settings.json写坏多余逗号、引号不配对不会导致 Sabaki 崩溃而是等同于“全新默认设置”所有个性化配置引擎列表、主题等将失效——这也是调试“配置不生效”类问题时的一个重要检查点。保存端src/setting.js 的save()会把键按字典序排序后以两空格缩进的 JSON 写回磁盘应用运行期间任何setting.set()都会立即触发写盘并向所有窗口广播change事件。四、Developer 菜单的注入条件与完整调用链4.1 菜单项是条件生成的docs/guides/debugging.md 中“多出一个 Developer 菜单”的现象对应 src/menu.js 中这段条件数组项setting.get(debug.dev_tools) { id: developer, label: i18n.t(menu.developer, Developer), submenu: [ { label: i18n.t(menu.developer, Open Settings Folder), click: () shell.showItemInFolder(setting.settingsPath), neverDisable: true, }, { label: i18n.t(menu.developer, Toggle Developer Tools), click: () sabaki.window.webContents.toggleDevTools(), neverDisable: true, }, {type: separator}, { label: i18n.t(menu.developer, Load Language File…), click: async () { /* 弹出安全警告后加载 .js 语言文件 */ }, }, { label: i18n.t(menu.developer, Unload Language File), click: () { i18n.loadFile(null) }, }, ], }, ].filter((x) !!x)setting.get(debug.dev_tools) {...}这一写法意味着开关为false时表达式结果为false被末尾的.filter((x) !!x)过滤掉菜单自然不存在开关为true时才注入。这也解释了文档为什么要强调“修改后需重启”——菜单模板在启动及窗口状态变化时重建src/main.js 的buildMenu()而不是热更新。从源码结构看开启开关后你能用到的其实不止 DevTools 一项Developer 菜单共含四个入口Open Settings Folder调用shell.showItemInFolder(setting.settingsPath)直接在系统文件管理器中定位settings.json——对“找不准设置目录在哪”的跨平台问题是最省事的办法Toggle Developer Tools本文主角开关 DevToolsLoad Language File… / Unload Language File加载/卸载一个 JavaScript 语言文件用于 i18n 定制与调试。菜单点击前会弹出明确警告提示语言文件“本质上是 JavaScript 文件可以在你的电脑上执行任意代码建议只加载信任作者的版本”调试时请勿加载来路不明的语言文件。4.2 菜单点击如何变成toggleDevTools()三条相关链路Sabaki 的菜单交互跨越主进程与渲染进程理解这条链对调试 UI 问题例如“菜单点了没反应”很有帮助。菜单的构建与点击分发。渲染进程中的 src/components/MainMenu.js 调用 src/menu.js 的get()生成菜单数据通过ipcRenderer.send(build-menu, ...)通知主进程。主进程 src/main.js 的processMenu把每个带click的菜单项改写为“向渲染进程发送menu-click-${item.id}事件”if (click in item) { item.click () { let window BrowserWindow.getFocusedWindow() if (!window) return window.webContents.send(menu-click-${item.id}) } }MainMenu 则递归地为每个带click的项注册监听器点击回调item.click()实际在渲染进程内执行——这就是为什么菜单模板里可以直接写sabaki.window.webContents.toggleDevTools()。渲染进程到主进程的 IPC 桥。sabaki.window.webContents是 src/modules/sabaki.js 中的代理对象其toggleDevTools转发到 src/preload.js 暴露的桥接方法webContents: { ... toggleDevTools: () ipcRenderer.invoke(webContents:toggleDevTools), ... }主进程侧的处理器在 src/main.jsipcMain.handle(webContents:toggleDevTools, (e) e.sender.toggleDevTools())e.sender就是发起调用的那个webContentstoggleDevTools()是 Electron 的标准 API——由此与 Chrome 完全一致的开发者工具Elements / Console / Sources / Network 等面板随即打开。至此完整调用链为Developer 菜单 Toggle Developer Tools → 主进程 buildMenu 改写为 send(menu-click-developer-3) [src/main.js] → MainMenu 监听器执行 item.click() [src/components/MainMenu.js] → sabaki.window.webContents.toggleDevTools() [src/modules/sabaki.js] → ipcRenderer.invoke(webContents:toggleDevTools) [src/preload.js] → ipcMain.handle 中 e.sender.toggleDevTools() [src/main.js] → Chromium DevTools 打开菜单的禁用规则。src/menu.js 的processMenu在disableAll时例如全部窗口关闭后 macOS 上的重建会禁用所有普通菜单项但带neverDisable: true标记的项例外——Developer 菜单下的四个项都标记了neverDisable因此即使在“空应用”状态下也能打开设置目录或 DevTools这对排查“启动后窗口异常退出”类问题是个实用特性。五、补充调试通道GTP 引擎日志与未捕获异常弹窗对于引擎接入类问题连不上引擎、GTP 协议异常DevTools 之外还有一条专门的文件日志通道。package.json 的dependencies中包含winston: ^3.2.1对应实现是 src/modules/gtplogger.js由两个配置项控制默认值见 src/setting.jsgtp.console_log_enabled默认falsegtp.console_log_path默认null指定日志目录。两项都可以在界面中配置偏好设置抽屉 src/components/drawers/PreferencesDrawer.js 的 Engines 页签提供了 Enable GTP logging to directory 复选框和目录选择输入框与手动编辑settings.json等价。启用后gtplogger.write() 会把引擎的每条交互按统一格式写入 winston 日志winstonLogger.log( info, ${stream.engine} ${typeText} : ${stream.message}, )其中typeText区分流向stderr → (err)、stdin → (in)、stdout → (out)、meta → (meta)并带YYYY-MM-DD HH:mm:ss.SSS毫秒时间戳。日志文件由 updatePath() 动态挂载文件名为sabaki_YYYY-MM-DD-HH-MM-SS_pid.log进程 ID 保证多实例不冲突引擎重新挂载时通过rotate()换新文件。两个调试要点启动时会校验目录可写validate()路径无效或不可写会弹出警告框提示“请确认日志目录有效且可写或关闭 GTP 日志”排查“引擎无响应/分析中断”时这份带流向标记的完整 GTP 转录比 DevTools 里的内存态更便于事后复盘。另一条兜底通道是主进程的未捕获异常处理src/main.js 注册了process.on(uncaughtException)触发时弹出dialog.showErrorBox标题为“Sabaki v版本”正文提示“Sabaki 将自行退出如可能请到仓库报告问题”并附带完整的err.stack随后process.exit(1)。也就是说拿到这个弹窗里的堆栈信息而不是只看一句报错是提交可复现问题报告的关键材料。六、开发与 E2E 场景下的调试实践docs/guides/debugging.md 面向终端用户但同一套设置机制也让开发者的调试路径非常一致——核心技巧是用一个隔离的临时user-data-dir复现问题。docs/guides/building-tests.md 给出的开发循环是npm install之后npm run watchwebpack 开发模式增量打包 prettier 监听格式化、npm start以 Electron 启动./src/main.js、npm testmocha 单元测试。E2E 测试则把“隔离设置目录”的做法工程化了。e2e/fixtures/electron-app.js 中的electronAppfixture 为每次测试fs.mkdtempSync(...)创建临时目录并把一组“确定化”设置关闭动画、音效、更新检查gtp.move_delay: 0等写入该目录的settings.json以--user-data-dirtmp参数启动 Electron——该参数会把app.getPath(userData)精确指向临时目录因此settings.json位于其根目录正好匹配 src/setting.js 的路径拼接用app.evaluate在主进程中桩掉所有原生对话框showMessageBox/showOpenDialog/showSaveDialog/showErrorBox防止任何弹窗阻塞测试进程。这正是调试“设置相关 bug”的可复用套路自己也可以在系统临时目录伪造一份settings.json用electron . --user-data-dir临时目录启动快速验证某个配置组合的行为而不污染真实配置测试结束后清理临时目录即可。运行方式见 docs/guides/building-tests.md 与 playwright.config.js$ npm run test:e2e # 构建 webpack 包 运行全部套件 $ npm run test:e2e:smoke # 只跑冒烟套件 $ npm run test:e2e:headed # 带可见窗口的模式Linux 上可绕开 xvfbLinux 上测试默认经xvfb-run在虚拟帧缓冲中运行调试界面问题时可用npm run test:e2e:headed直接看到真实 Electron 窗口。七、小结Sabaki 的 DevTools 开关是配置驱动的在%APPDATA%\SabakiWindows/~/.config/SabakiLinux/~/Library/Application Support/SabakimacOS下的settings.json中将debug.dev_tools置为true重启后主菜单出现 Developer → Toggle Developer Tools便携版注意使用PORTABLE_EXECUTABLE_DIR指向的目录。settings.json的加载规则是“缺键补默认、非法键删除、坏文件回退默认”手改配置时务必核对 src/setting.js 中的键名Developer 菜单由 src/menu.js 按开关条件注入其点击经build-menu→menu-click-*IPC 链回到渲染进程执行最终由主进程e.sender.toggleDevTools()打开 Chromium DevTools引擎类问题优先开启gtp.console_log_enabledgtp.console_log_path文件日志src/modules/gtplogger.js主进程未捕获异常的堆栈会直接显示在错误弹窗中开发调试可复用 E2E fixture 的手法--user-data-dir指向临时目录实现配置隔离配合 docs/guides/building-tests.md 中的npm run watch/npm start完成闭环。赞分享桌面应用【免费下载链接】SabakiAn elegant Go board and SGF editor for a more civilized age.项目地址https://gitcode.com/gh_mirrors/sa/Sabaki点击查看免费下载相关推荐BoostnoteElectron 应用调试指南DevTools 与断点调试实战BoostnoteElectron 应用调试指南DevTools 与断点调试实战 本指南以 Boostnote开源 Markdown 笔记应用为对象知识管理桌面应用Electron API Demos开发调试配置VS Code与Chrome DevToolsElectron API Demos开发调试配置VS Code与Chrome DevTools Electron API Demos作为官方交互式API演示应示例工程桌面应用终极Redux DevTools完整配置与调试指南从入门到精通终极Redux DevTools完整配置与调试指南从入门到精通 Redux DevTools是Redux生态系统中不可或缺的开发工具它能帮助开发者实时监控R开发工具前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

英飞凌SiC产品线深度解析:选型、驱动与工程实践

英飞凌SiC产品线深度解析:选型、驱动与工程实践

做电源和电驱这行,这几年最大的感受就是散热器在变小、风扇转速在变慢、开关频率在往上拉。早几年做20kW级别的充电模块,IGBT配大散热器是标配,满载时热量大得吓人;换成SiC之后再回头做同规格产品,体积和噪音完全是两个…

2026/10/14 17:48:12 阅读更多 →
Elasticsearch自定义分析器实战:从分词器到同义词的完整构建指南

Elasticsearch自定义分析器实战:从分词器到同义词的完整构建指南

做搜索的同学应该都有过这种体验:索引建好了、文档导进去了,用户搜"笔记本"就是查不出来,因为商品标题里写的是"Laptop";或者从网页抓来的内容带着HTML标签,用户搜"手机"时倒是一堆&quo…

2026/10/14 17:48:12 阅读更多 →
信号完整性分析入门:反射、串扰与时序三大核心问题解析

信号完整性分析入门:反射、串扰与时序三大核心问题解析

做硬件这几年,我对“信号完整性分析”这六个字的理解,经历了从课本名词到吃饭家伙的转变。刚入行时觉得反射、串扰都是仿真教材里的概念,离实际板子很远;直到有一次调试一块FPGA高速采集板,数据在低频下怎么测都正常&a…

2026/10/14 17:48:12 阅读更多 →

最新新闻

C语言手写FFT:从蝶形运算到位反转的嵌入式实现

C语言手写FFT:从蝶形运算到位反转的嵌入式实现

简介:这份资源面向具备一定C语言与信号处理基础的学习者,聚焦快速傅里叶变换(FFT)与逆变换(IFFT)的工程实现,帮助读者理解离散傅里叶变换的数学原理并落地为可编译运行的代码。内容围绕Cooley-T…

2026/10/14 18:29:51 阅读更多 →
WebRTC入门实战:从一对一通话Demo到避坑指南

WebRTC入门实战:从一对一通话Demo到避坑指南

1. 从一次视频通话卡顿说起:WebRTC到底解决了什么问题第一次接触WebRTC,是因为一个很具体的需求:做一个网页端的多人视频通话功能,要求打开浏览器就能用,不装插件、不装客户端。当时第一反应是去找现成的第三方服务&am…

2026/10/14 18:29:51 阅读更多 →
WinCE TCP通信实战:从Winsock选型到心跳重连的避坑指南

WinCE TCP通信实战:从Winsock选型到心跳重连的避坑指南

简介:这份资源面向在Windows CE嵌入式平台上进行网络开发的工程师与学习者,提供基于Visual Studio 2005环境的TCP通信样例工程,帮助理解并掌握WinCE设备上的Winsock网络编程。包内共29个文件,以h头文件、cpp源文件、vcproj工程文件…

2026/10/14 18:29:51 阅读更多 →
STM32F407+FSMC+W5100S工业以太网稳定设计指南

STM32F407+FSMC+W5100S工业以太网稳定设计指南

简介:本资源是一套基于STM32F407VET6单片机与W5100S以太网模块的FSMC接口网络通信完整工程,面向嵌入式初学者及物联网硬件开发人员,解决STM32平台下高速以太网外设驱动与TCP协议栈应用落地难题。压缩包共143个文件,含56个C源码与5…

2026/10/14 18:29:51 阅读更多 →
Obsidian量子测试知识图谱:开源模板与实操指南

Obsidian量子测试知识图谱:开源模板与实操指南

1. 为什么是 Obsidian,以及量子测试场景的真实痛点1.1 量子测试不是普通软件测试先从一个很实际的问题说起:做量子计算相关的测试工作,到底有多少种资料要管?我自己入坑量子测试之前,以为它和普通软件测试差不太多——…

2026/10/14 18:29:51 阅读更多 →
离散控制Matlab代码:当HJB方程撞上Tensor Train,为什么状态维度一高就集体翻车

离散控制Matlab代码:当HJB方程撞上Tensor Train,为什么状态维度一高就集体翻车

简介:这份资源面向从事最优控制、科学计算与数值分析的研究生、工程师及科研人员,提供离散控制场景下Hamilton-Jacobi-Bellman方程牛顿策略迭代的Tensor Train实现,属于系统开源类Matlab代码。压缩包共15个文件,以13个.m脚本为核心…

2026/10/14 18:28:51 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →