news 2026/10/23 18:42:11

同一套 Rust 代码跑进浏览器:ArtCraft Launcher Web 版(WASM)功能与原理详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
同一套 Rust 代码跑进浏览器:ArtCraft Launcher Web 版(WASM)功能与原理详解

【免费下载链接】craft-launcher

The Craft App Launcher

项目地址:https://gitcode.com/gh_mirrors/cr/craft-launcher
点击查看免费下载

ArtCraft Launcher 是一款用 Rust 编写的 Craft App Suite 启动器,负责安装、更新和打开 PhotoCraft、LightCraft、FilmCraft 等 12 款创意应用。它的 Web 版把同一套界面代码编译成 WebAssembly(WASM)直接跑在浏览器里:展示全套应用目录、自动识别访客的操作系统,并给出对应的下载链接。这篇文章带你完整了解 Web 版能做什么、代码是怎么分层的,以及如何构建部署。

Web 版能做什么、不能做什么 🌐

浏览器不能操作本地文件系统,所以 Web 版无法安装应用。它把自己定位成一个"目录 + 下载中心":

功能桌面版Web 版
展示 12 款应用目录与最新版本✅✅
识别访客系统,给出对应下载包✅✅
一键安装 / 更新 / 启动 / 卸载✅❌(改为"下载"按钮 + GitHub 链接)
系统托盘、登录项、通知✅❌
多语言界面(含简体中文)✅✅(跟随浏览器语言)
记住你的设置✅(本地文件)✅(浏览器 localStorage)

具体来看,Web 版打开后会自动完成这几件事:

  1. 拉取最新 release:逐个访问 GitHub REST API(api.github.com允许跨域请求),得到每款应用的最新版本号、发布时间和全部下载文件——不需要自己的后端服务器;
  2. 识别访客平台:解析浏览器 User-Agent,判断是 Windows / macOS / Linux / FreeBSD,以及 x64 / ARM64 / RISC-V 架构,据此为每个应用挑出正确的下载包(.msi、.dmg、.AppImage……);
  3. 匹配界面语言:优先读取地址栏里的?lang=ru参数,其次读浏览器的偏好语言,加载提示文字也会用对应语言显示;
  4. 记住设置:语言、视图方式等设置通过 eframe 的持久化机制存入浏览器 localStorage,下次打开自动恢复。

💡 一个小细节:桌面版会用系统自带的 CJK 字体渲染中文、日文等文字,而 Web 版没有这个条件——当系统无法提供字体时,界面会退回英文,并在设置里说明原因。

界面可以在"网格(Grid)"和"表格(Table)"两种布局间切换,支持排序与搜索,这些交互逻辑在两个平台完全一致——因为它们本就是同一份 UI 代码。

同一套代码的关键:三层 Crate 架构

整个项目是一个 Cargo 工作区(见 Cargo.toml),按职责拆成三层,这是"一套代码两端跑"能成立的根本原因:

层位置内容能否编译到 WASM
corecrates/core/纯数据与逻辑:应用目录、版本比较、GitHub release 解析、按平台挑选下载包✅
ui-eguicrates/ui-egui/共享界面:网格/表格视图、设置、主题、多语言✅
nativecrates/native/桌面专属:下载、安装、托盘、自更新❌
artcraft-launcher-webapps/artcraft-launcher-web/Web 壳:WASM 入口 + 浏览器后端,仅约 260 行✅

crates/core/src/lib.rs 开头就说明了设计意图:core 里没有任何 I/O,所以桌面版、Web 版和测试代码可以原样共享它。比如"从一堆下载文件里挑出最适合当前平台的包"这个逻辑,两端都用同一个函数pick_asset(crates/core/src/platform.rs)。

UI 层与后端之间只通过一条清晰的协议对话,定义在 crates/core/src/protocol.rs:

  • UI → 后端:发送Command(检查更新、安装、启动、配置……);
  • 后端 → UI:每帧拉取一次Event(最新 release、进度、完成/失败)。

桌面后端在独立线程里干活,Web 后端在 async 任务里干活,两边都不阻塞渲染帧。

还有一个巧妙的"能力开关"——Capabilities结构体。每个后端通过它告诉 UI 自己能干什么:

  • 桌面版声明manage_apps: true,按钮就是"安装 / 更新 / 打开";
  • Web 版声明manage_apps: false(见 apps/artcraft-launcher-web/src/web.rs),同一份 UI 代码就会自动把主按钮换成"下载",并链接到对应的 GitHub 下载文件。

UI 因此可以保持"薄薄一层":只负责画卡片、读状态、发命令,完全不关心背后是操作系统还是浏览器。

Web 壳的实现:fetch、UA 与 localStorage

Web 壳的入口是 apps/artcraft-launcher-web/src/main.rs,通过eframe::WebRunner把 egui 界面渲染到页面里的<canvas>上(index.html 就只有一个画布和一个加载提示)。真正有浏览器味道的代码都集中在 apps/artcraft-launcher-web/src/web.rs:

查最新版本:用浏览器的fetch直接向 GitHub API 发 CORS 请求。对每个应用请求releases/latest,把 JSON 交给 core 里现成的解析函数。遇到 403/429(限流)时会读取x-ratelimit-reset响应头,把恢复时间告诉界面;没登录的访客共享的是"每 IP 每小时 60 次请求"的额度,所以界面会把限流情况说清楚,而不是干转圈。

猜访客平台:visitor_platform函数(apps/artcraft-launcher-web/src/web.rs)检查 User-Agent 中的 "windows"、"mac os"、"linux" 等关键字来确定系统,再用 "aarch64" / "arm64" / "riscv" 确定架构。

语言检测:detect_language函数(apps/artcraft-launcher-web/src/web.rs)在首帧之前执行,把?lang=xx参数和navigator.languages一起交给 i18n 模块(实现见 crates/ui-egui/src/i18n/detect.rs),并同步更新页面的<html lang>属性和加载文字。

设置持久化:eframe 在 Web 上自动使用 localStorage,所以"保存设置"只需一行eframe::set_value,和桌面版共用同一个Settings结构体(crates/ui-egui/src/settings.rs)。

如何构建并部署 Web 版 🛠️

本地构建只需两条命令:

cargo install trunk --locked # 安装 WASM 构建工具 trunk rustup target add wasm32-unknown-unknown # 添加 WASM 目标 cd apps/artcraft-launcher-web && trunk serve # 本地运行于 127.0.0.1:8766

Trunk.toml 指定了两个关键设置:输出目录为../../dist/web,public_url = "./"让所有资源都走相对路径——这保证了站点无论是挂在域名根目录、子路径还是 CDN 桶里都能正常工作。

apps/artcraft-launcher-web/Cargo.toml 里还有个值得注意的注释:渲染走 wgpu,浏览器里是WebGPU 优先、WebGL2 兜底,所以无需担心老显卡。工作区 Cargo.toml 里的wasm-releaseprofile 开启了opt-level = "s"(按体积优化)+fatLTO,尽量压缩最终的.wasm文件。

产物是什么?一个自包含的纯静态站点(packaging/web/README.md 有完整说明):

文件说明
index.html页面本身,全部使用相对 URL 加载资源
artcraft-launcher-web-<hash>.jswasm-bindgen 生成的胶水代码(ES module)
artcraft-launcher-web-<hash>_bg.wasm应用主体(egui 界面 + 业务逻辑)
_headers/.htaccessNetlify / Cloudflare Pages / Apache 的示例配置

没有服务端代码,也没有一行手写的 JavaScript——把文件夹上传到任何能托管静态文件的地方即可。官方构建脚本 packaging/web/package.sh 还会做两道具保险:发现根绝对路径 URL 直接报错(防止子路径部署翻车),WASM 超过 24 MiB 也报错(Cloudflare 单文件上限 25 MiB)。

部署时真正需要关心的是这几项(详见 packaging/web/README.md):

  • .wasm的 MIME 类型必须是application/wasm,否则浏览器拒绝流式编译;
  • 对.wasm/.js/.html开启 gzip 或 Brotli 压缩;
  • 带内容哈希的.wasm和.js可以设置"一年 + immutable"缓存,只有index.html需要no-cache;
  • 应用不使用SharedArrayBuffer,因此不需要 COOP/COEP 那套隔离头。

想把它嵌进别的页面?一个iframe即可(沙箱化 iframe 至少需要allow-scripts allow-same-origin allow-popups,其中allow-popups是为了让下载链接能打开)。本地想先验证一下,在站点目录里跑python3 -m http.server 8765然后打开http://localhost:8765/就够了。

如何验证 WASM 构建没问题

仓库的 CI 任务把 WASM 兼容性也纳入了日常检查(xtask/src/main.rs):cargo xtask wasm会对"必须能跑在浏览器里"的 crate(core 与 web 应用)执行cargo check --target wasm32-unknown-unknown,cargo xtask ci则一次跑完格式检查、clippy、全部测试和 WASM 检查。这样任何误引入"只有原生平台才有"的依赖都会立刻被发现,而不是等到上传部署时才爆炸。

小结

ArtCraft Launcher Web 版的做法可以概括为三句话:

  1. 纯逻辑下沉:目录、版本、release 解析全部放进无 I/O 的 core 层,天然可编译为 WASM;
  2. 协议隔离:UI 只认Command/Event协议和Capabilities开关,桌面后端与 Web 后端各写各的,UI 一行不改;
  3. 静态站点交付:trunk 构建出的 HTML + JS + WASM 三件套,扔到任何静态托管上即可运行。

对想给 Rust/egui 项目加"浏览器版"的开发者来说,这套分层值得直接抄作业:先想清楚哪部分代码不碰 I/O,再把平台差异全部塞进 trait 的另一侧。

【免费下载链接】craft-launcher

The Craft App Launcher

项目地址:https://gitcode.com/gh_mirrors/cr/craft-launcher
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 6:24:04

Linux服务器预约系统开发实战:Flask与SQLite应用

1. 项目背景与核心需求这个Linux服务器预约系统小项目是面向运维初学者的实践教程第三部分。在前两节课中&#xff0c;我们已经完成了基础环境搭建和用户管理模块&#xff0c;现在需要实现核心的预约功能模块。典型的应用场景包括&#xff1a;高校实验室的服务器资源分配中小企…

作者头像 李华
网站建设 2026/10/23 22:23:38

2022护理保研浙江大学:湘雅PICOS追问、健康宣教口译与科研准备

&#x1f4cc; 大一保研必看&#xff5c;从入学准备到推免录取的全流程攻略 绩点、英语、科研竞赛&#xff0c;先抓哪一项&#xff1f; 按大一到大三梳理准备顺序&#xff0c;讲清夏令营、预推免、申请材料和面试要点。 &#x1f449; 点击阅读完整攻略 → 我的背景与申请结果 …

作者头像 李华
网站建设 2026/10/23 22:23:37

Linux服务管理核心:systemctl命令与unit配置实战

1. 为什么系统管理员绕不开systemctl 1.1 从init脚本到systemd&#xff1a;命令背后的体系变化 新接手一台服务器&#xff0c;第一件事不是部署业务&#xff0c;而是搞清楚这台机器上的服务是怎么管的。登录上去敲几行命令&#xff0c;看看Nginx和MySQL的存活状态&#xff0c;…

作者头像 李华
网站建设 2026/10/17 12:58:39

PowerShell别名完全指南:从Set-Alias到函数模拟与持久化配置

你有没有算过自己每天在 Windows 终端里重复敲了多少次长命令&#xff1f;我最开始折腾 PowerShell 设置命令别名&#xff0c;纯粹是因为Get-Service、Get-Process这种命令不长不短&#xff0c;每次敲都容易在中间卡一下&#xff0c;干脆设一个别名把它缩短。这个问题听起来小&…

作者头像 李华
网站建设 2026/10/19 6:39:58

从TOPS到TCO:企业算力规划与成本优化实操指南

我不准备逐字背诵任何规范清单&#xff0c;直接按一个资深从业者的口吻&#xff0c;把这篇关于云栖大会与算力规划的文章写透。下面就是正文。1. 云栖大会现场的几个直观信号今年云栖大会逛下来&#xff0c;最强烈的感受是&#xff1a;算力这个词&#xff0c;已经从技术圈的黑话…

作者头像 李华
网站建设 2026/10/19 7:05:47

Bert-VITS2 2.3中文语音克隆实战:从数据准备到6000步训练调参指南

简介&#xff1a;面向人工智能深度学习与语音克隆领域开发者的Bert-vits2项目模型包&#xff0c;内含星之守护者阿狸中文语音模型&#xff0c;训练步数6000&#xff0c;版本2.3。该开源TTS方案基于当前广受好评的端到端语音合成架构&#xff0c;在韵律表现上尤为突出&#xff0…

作者头像 李华