# app.json 配置 ## 功能 `app.json` 是 `bt-app` 的桌面应用配置文件。它描述应用名称、窗口、入口、运行模式、图标、主脚本和打包资源。 `app.json` 是唯一配置来源。项目根目录不存在 `app.json` 但存在 `index.html` 时,`bt-app` 会自动写入默认 `app.json` 后再启动;`index.html` 中的 `` 和自定义标签不会覆盖应用配置。 ## 完整示例 ```json { "app": { "id": "org.example.diary", "name": "Diary", "title": "我的日记本", "version": "1.0.0", "description": "BT 桌面日记本示例", "copyright": "Copyright 2026 BT", "mode": "static", "entry": "index.html", "icon": "icon.ico", "storage": "app", "file_associations": [ { "extensions": ["md", "markdown"], "icon": "icons/markdown.ico", "description": "Markdown 文档", "context_menu": "以 Diary 打开" } ], "main": "main.bt" }, "window": { "width": 900, "height": 700, "resizable": true, "fullscreen": false, "hide_titlebar": false, "transparent": false, "always_on_top": false }, "dev": { "watch": true, "delay": 500, "devtools": true, "console": true }, "resources": [ "app.json", "index.html", "icon.ico", "main.bt", "assets/**" ], "exclude": [ "assets/test/**", "assets/*.bak" ] } ``` ## app 字段 | 字段 | 类型 | 必填 | 默认值 | 有效范围或可选值 | 说明 | |---|---|---|---|---|---| | `app.id` | string | 否 | 根据 `app.name` 生成 `org.btlang.<name>` | 小写反向域名形式;至少两段;每段只能包含 ASCII 字母、数字、`_`、`-`,且首尾为字母或数字 | 跨版本保持稳定的应用标识。显式配置后用于 WebView profile、凭据和应用数据隔离,不应因显示名称或输出文件名变化而修改。 | | `app.name` | string | 否 | `BTApp` | 单个文件名片段;不能包含路径或 Windows 文件名非法字符 | 应用内部名称,也是默认打包输出文件名。 | | `app.title` | string | 否 | `BT 桌面应用` | 非空文本 | 窗口标题。用户看到的应用名称通常写在这里。 | | `app.version` | string | 否 | `1.0.0` | 非空文本 | 应用版本,并写入 BTR 软件信息。 | | `app.description` | string | 否 | 无 | 非空文本或省略 | 应用说明。Windows 打包时写入 exe 的 `FileDescription` 元信息。 | | `app.copyright` | string | 否 | 无 | 非空文本或省略 | 版权说明。Windows 打包时写入 exe 的 `LegalCopyright` 元信息。 | | `app.mode` | string | 否 | `static` | `static`、`server`、`remote` | 运行模式。 | | `app.entry` | string | 否 | 按模式决定 | `static` 为项目内安全相对路径;`server`、`remote` 为 HTTP/HTTPS URL | 窗口入口。`static` 默认 `index.html`,`server` 默认 `http://127.0.0.1:18280`,`remote` 默认 `https://example.com`。 | | `app.icon` | string | 否 | 内置图标 | 项目内安全相对 `.ico` 路径 | 用于运行窗口图标、BTR 工具条展示和 Windows 打包 exe 图标。 | | `app.storage` | string | 否 | `app` | `app`、`private`、`global` | WebView 存储策略。`app` 按应用标识使用独立持久 profile;`private` 每次启动使用唯一临时 profile;`global` 使用旧版全局共享 profile。 | | `app.file_associations` | object[] | 否 | `[]` | 见下表 | Windows 业务文件关联列表。只由打包后的 exe 应用注册;外部 BTR 不注册其中声明的关联。 | | `app.main` | string/boolean/null | 否 | 自动尝试 `main.bt` | 安全相对 `.bt` 路径、`false`、空字符串、`true` 或 `null` | 前端 `bt.call()` 可调用的 BT 主脚本。字符串表示指定脚本;`false` 或空字符串表示不执行;其他默认形式自动查找 `main.bt`。 | 建议从项目创建时就显式写入 `app.id`。未写时仍按旧行为兼容:运行时根据当前 `app.name` 生成默认 ID,并继续沿用旧版按名称保存的数据位置;一旦显式设置稳定 ID,后续修改 `app.name` 或 `app.title` 不会更换应用 profile 与数据目录。 ## app.file_associations 字段 每个关联对象可同时声明多个扩展名。打包应用启动后会把自身注册为这些扩展名的打开程序,并添加资源管理器右键菜单;文件路径会作为启动参数传入,可通过 `window.bt.app.args()` 读取。 | 字段 | 类型 | 必填 | 默认值 | 有效范围或可选值 | 含义 | |---|---|---|---|---|---| | `extensions` | string[] | 是 | 无 | 每项为 1 到 32 个 ASCII 字母或数字;可带前导 `.`,读取后会移除并转成小写;全配置内不能重复 | 需要关联的文件扩展名。 | | `icon` | string | 否 | `app.icon` | 项目内相对路径,只支持 `.ico` 文件 | 文件类型专属图标。构建时嵌入 exe 的独立图标资源组,资源管理器中的关联文件使用该图标;右键菜单仍显示应用主图标。 | | `description` | string | 否 | `<app.title> 文档` | 非空文本,不允许 NUL | Windows 中显示的文件类型说明。 | | `context_menu` | string | 否 | `以 <app.title> 打开` | 非空文本,不允许 NUL | 文件资源管理器右键菜单文本。 | ```json { "app": { "name": "M++", "title": "M++", "file_associations": [ { "extensions": ["md"], "icon": "markdown.ico", "description": "Markdown 文档", "context_menu": "以 M++ 打开" } ] } } ``` `file_associations[].icon` 和 `app.icon` 作用不同:前者表示文件类型图标,后者表示 exe、窗口和任务栏中的应用图标。关联图标会直接嵌入单文件 exe,不需要额外写入 `resources`;省略时继续复用应用主图标,兼容旧配置。 Windows 关联写入 `HKEY_CURRENT_USER\\Software\\Classes`,不需要管理员权限,也不会修改其他用户。系统会尊重用户已经在 Windows 设置中明确选择的默认应用;这种情况下右键菜单和“打开方式”仍会出现,用户可在系统设置中把新应用设为默认。bt-app 不删除带签名保护的 `UserChoice`,也不会在每次启动时抢回用户后来选择的其他默认程序。 ## window 字段 | 字段 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | `window.width` | number | 否 | `800` | 主窗口初始宽度,单位为逻辑像素。写 `0` 会回退到默认值。 | | `window.height` | number | 否 | `500` | 主窗口初始高度,单位为逻辑像素。写 `0` 会回退到默认值。 | | `window.resizable` | boolean | 否 | `true` | 是否允许用户调整窗口大小。 | | `window.fullscreen` | boolean | 否 | `false` | 是否全屏启动。 | | `window.hide_titlebar` | boolean | 否 | `false` | 是否隐藏系统标题栏。隐藏后需要页面自己提供拖动、关闭等交互;Windows 无标题栏窗口会关闭产生 1px 白边的系统阴影。 | | `window.transparent` | boolean | 否 | `false` | 是否在创建时同时启用原生窗口和 WebView 透明背景。设为 `true` 时必须同时设置 `hide_titlebar: true`;修改后必须重启应用,热重载不会切换透明状态。 | | `window.always_on_top` | boolean | 否 | `false` | 是否置顶窗口,适合悬浮工具、监控面板等场景。 | 主窗口启动时会先以无边框、无投影且隐藏的状态创建 WebView。非透明页面开始加载后会显示 bt-app 内置的无边框加载动画;首个页面完成加载后,bt-app 才应用 `hide_titlebar` 对应的最终边框和系统投影。透明窗口不会绘制矩形加载背景,而是保持隐藏到页面首帧完成。该时序由运行时统一处理,可避免 Windows 非客户区边线和 WebView 默认白底在页面首帧前闪现,项目页面不需要额外制作启动遮罩。 ### 透明窗口 透明窗口适合悬浮工具、圆角面板、桌面挂件以及带 Alpha 通道的 PNG 界面。它不是运行期 API,而是窗口创建期配置: ```json { "window": { "width": 320, "height": 180, "resizable": false, "fullscreen": false, "hide_titlebar": true, "transparent": true, "always_on_top": true } } ``` 页面根节点必须保持透明,只让实际界面容器绘制背景和圆角: ```css html, body { margin: 0; width: 100%; height: 100%; background: transparent; } .app-shell { width: 100%; height: 100%; border-radius: 24px; background: rgba(24, 28, 42, 0.92); } ``` `transparent: true` 会关闭矩形原生阴影,阴影需要由 HTML/CSS 绘制并在窗口尺寸内预留透明边距。PNG 和 HTML 元素可以使用半透明像素;完全透明的圆角区域仍属于原生矩形窗口的命中范围,不会自动点击穿透到下层应用。 ## dev 字段 | 字段 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | `dev.watch` | boolean | 否 | `true` | 开发目录运行时是否监听资源变化并自动刷新页面。打包后的 Bundle 运行不生效。 | | `dev.delay` | number | 否 | `500` | 文件变化后的防抖时间,单位为毫秒。连续保存多个文件只刷新一次。 | | `dev.devtools` | boolean | 否 | `false` | 是否允许打开 WebView 开发者工具。开启后可按 `F12` 或 `Ctrl+Shift+I` 打开,也可调用 `window.bt.window.open_devtools()`。建议只在开发阶段开启;文件变化热重载不会自动弹出开发者工具。 | | `dev.console` | boolean | 否 | `true` | 是否启用调试控制台。打包时为 `false` 会把 Windows exe 改为 GUI 子系统,双击时不弹控制台。 | 开发模式支持 `F5`、`Ctrl+R` 和 `Cmd+R` 刷新当前页面。`dev.watch=true` 时,`resources - exclude` 命中的文件保存、新增、删除或重命名后会自动刷新页面。`dev.watch=false` 时不会监听普通资源变化,但仍会监听 `app.json`,以便修改配置后自动恢复。`window.transparent` 同时影响原生窗口和 WebView,只能在窗口创建时应用;改变该字段后需要重启 `bt-app`。 开发目录运行时遇到 `app.json` 解析失败、入口文件缺失、`app.main` 缺失或脚本执行异常时,会在窗口内显示统一错误页并继续监听文件变化;修复后会自动重新加载。热重载错误状态会沿用上一次有效配置中的控制台设置,不会因为进入错误页而强制弹出控制台。 ## resources 字段 | 字段 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | `resources` | string[] | 否 | `[]` | 打包时进入 Bundle 的资源规则,支持普通相对文件、glob 和 `assets/**` 这类递归目录规则。 | | `exclude` | string[] | 否 | `[]` | 排除打包与开发监听的资源规则,优先级高于 `resources`。 | 构建时还会自动补齐必要资源: - 当前目录存在 `app.json` 时自动加入 `app.json`。 - `static` 模式自动加入 `app.entry` 指向的入口文件。 - `app.main` 自动模式下如果存在 `main.bt`,自动加入 `main.bt`。 - 指定 `app.main` 字符串时自动加入该脚本。 - `app.main` 为 `false` 或空字符串时不需要主脚本;旧配置中 `resources` 残留的 `main.bt` 若文件不存在会被跳过。 - 当前目录存在 `server.bt` 时自动加入 `server.bt`。 - 配置了 `app.icon` 时自动加入图标文件。 最终资源集合按 `resources - exclude` 计算,该规则同时用于打包和开发模式文件监听。`dist/` 构建输出目录始终不会进入资源产物。`resources` 和 `exclude` 只能写项目内相对路径,不能写绝对路径,不能包含 `..`。普通文件不存在会打包失败;普通目录会递归收集目录内文件;`assets/**` 会递归收集目录内文件。 ## 默认生成的 app.json 项目根目录没有 `app.json`,但存在 `index.html` 时,会生成以下默认配置: ```json { "app": { "id": "org.btlang.bt_app", "name": "BT-APP", "title": "BT-APP", "version": "1.0.0", "description": "BT桌面软件", "copyright": "Copyright 2026 BT", "mode": "static", "entry": "index.html", "storage": "app", "main": "main.bt" }, "window": { "width": 800, "height": 500, "resizable": true, "fullscreen": false, "hide_titlebar": false, "transparent": false, "always_on_top": false }, "dev": { "watch": true, "delay": 500, "devtools": true, "console": true }, "resources": [ "app.json", "index.html", "assets/**" ], "exclude": [] } ``` 默认配置中的 `app.main` 指向 `main.bt`。如果目录中还没有 `main.bt`,运行器会创建一个空文件,确保项目可以直接启动。默认资源会包含 `assets/**`,适配 Vue/Vite 常见构建产物。需要打包其他目录或文件时,请手动把它们写入 `resources`,bt-app 不再从 HTML 标签中自动扫描资源。 ## mode运行模式 ### static 该模式为静态HTML加载方式,需要配置`app.entry`为入口 HTML 文件路径,例如 index.html。 ### server 该模式会执行当前目录的 `server.bt` 脚本,并启动Web服务,需要配置 `app.entry` 为该Web服务的完整URL,例如 `http://127.0.0.1:18280`。 提示:请确保 `server.bt` 脚本文件存在,并能正确启动 BT Web 服务。 ### remote 该模式会直接打开远程URL,需要配置 `app.entry` 为远程URL,例如 `https://example.com`。 ### 运行机制 以上三种运行模式都会自动执行当前目录的 `app.main` 脚本,并注入 `window.bt` 对象,用于与BT脚本进行交互。 - 如果 `app.main` 配置为 `false`,则不会执行该脚本。 - 如果 `app.main` 配置不存在,则自动查找当前目录的 `main.bt` 脚本并执行。 ## 注意事项 - `app.name` 和 `app.title` 不同:`name` 为打包输出的文件名,`title` 为程序窗口的标题。 - `app.icon` 只接受 `.ico` 格式的图标文件。 - `app.file_associations[].icon` 同样只接受项目内 `.ico` 文件;文件不存在时构建会失败。 - `app.file_associations` 只在 Windows 打包应用启动时注册;仅执行 `bt-app.exe build` 不会修改开发机的文件关联。 - `window.transparent=true` 必须配合 `window.hide_titlebar=true`,并由页面把 `html`、`body` 背景设为 `transparent`。 - `index.html` 只作为页面入口,不承担配置职责。