Skip to content

HTML 资源打包

把前端工程(Vue dist / 静态站点)打进 exe,单文件分发。消费方代码不变,两种模式任选。

Mode 2:自动(推荐,0 配置)

资产放约定目录 src/assets/html/,库 fetch 时自动打包——.rch::webviewINTERFACE_SOURCES 注入,消费方 link 即编译进 exe。

cpp
opts.url = L"src/assets/html/index.html";   // 约定目录路径
toml
[target.myapp]
sources = ["src/main.cpp"]
link-libraries = ["h::webview"]   # 仅此行,.rc 自动注入 exe

Mode 1:显式(自定义目录 / 多 target)

任意本地路径,自定义扫描目录:

cpp
opts.url = L"E:\\myapp\\dist\\index.html";   // 任意本地路径
toml
[target.myapp]
sources = ["src/main.cpp"]
link-libraries = ["h::webview"]
cmake-after = "webview_package_assets(myapp src)"   # 显式扫描 src

两模式互斥

Mode 1 自动接管:函数内清 Mode 2 的 INTERFACE_SOURCES 注入,无需变量。CMake ≥ 3.15。

地址模式(两模式通用)

cpp
opts.url = L"https://github.com";   // 不打包,直接 Navigate

工作原理

构建期tools/gen_assets_rc.py 扫源码 opts.url = L"..." 字面量 + 约定目录 src/assets/html/,取本地路径所在目录全部文件 → RT_RCDATA 嵌入 exe + __manifest__ 清单。

运行时loadURL 三分支:

url 形式行为
https://直接 Navigate(地址模式)
本地路径命中 manifestWebView2 WebResourceRequested 内存拦截(https://app.local/*,RT_RCDATA 直返 + MIME)→ Navigate(打包模式,资源不出内存,%TEMP% 不落盘)
本地路径未命中file:/// 读盘(dev 模式)

开发机(文件在盘)与用户机(资源在 exe)行为一致。

资源增删自动重建

src/assets/html/新增/删除文件,下次 cmake --build 自动重 configure 重打包(CONFIGURE_DEPENDS),无需手跑 cmake -B build

编辑现有文件内容仍需 cmake -B build 重 configure(rc.exe 嵌字节,manifest 不变时跳过)。

约束

WARNING

  • opts.url 路径须为字符串字面量opts.url = L"E:\\dist\\index.html" ✅。拼接 / 变量赋值不被扫描 → 退化为 dev 读盘,不打包。
  • 远程地址任意写法均可(运行时判断,非扫描)。
  • 路径是 manifest 匹配键,非用户机真实路径——绝对路径跨机器仍能命中打包。

配合前端构建

以 Vue + Vite 为例,前端 build 产物输出到约定目录:

bash
cd web/frontend
npm run build          # 输出到 ../src/assets/html

Vite 配置要点(vite.config.ts):

ts
export default defineConfig({
  root: 'src/renderer',
  base: './',                                  // 相对路径,适配 app.local
  build: { outDir: '../assets/html', emptyOutDir: true }
})

前端 rebuild 后须再次 cmake --build 把资源重打包进 exe。

下一步