Valdi 路线图深度解读:Web 渲染器与 bzlmod 迁移进行时,以及明确不做的技术边界
【免费下载链接】ValdiValdi is a cross-platform UI framework that delivers native performance without sacrificing developer velocity.项目地址: https://gitcode.com/gh_mirrors/val/Valdi
导读:本文以仓库根目录的 ROADMAP.md 为主线,系统梳理 Valdi 当前正在推进的两大方向(HTML/CSS Web 渲染器、bzlmod 模块化改造)与四个明确不做的事项(Swift/SwiftUI 运行时、WebSocket API、macOS Intel 支持、Windows 开发环境)。读完本文,你将能基于 Valdi 的真实演进方向,判断它是否适合你的项目,并掌握在 Web 目标尚未成熟、原生能力受限时利用 Polyglot 模块补齐短板的落地路径。
Valdi 是一个跨平台 UI 框架,目前已能将同一套 TypeScript 声明式代码渲染到 iOS、Android 与 macOS。官方路线图文档 ROADMAP.md 全文不到 40 行,但它精确回答了社区最常问的几个问题:什么正在做、什么在调研、什么明确不做。它是一份决策文档而非功能承诺书——文档开篇即声明:"This roadmap is not a commitment. Priorities shift."(本路线图并非承诺,优先级随时会变)。
本文将这份文档与仓库中的实际代码、构建配置与工具链相互印证,逐条展开。
一、路线图文档的定位:为技术选型提供决策参考
ROADMAP.md 的写作目的非常清晰:它不是为了给外部一个"画饼式"的发布计划,而是为了回答关于项目方向的高频问题,让开发者在决定"Valdi 是否适合我的项目"时拥有足够的依据。
文档结构分为三大块:
- In Progress(进行中):Web / HTML target、bzlmod 支持;
- Not on Our Current Roadmap(不在当前路线图):Swift/SwiftUI 运行时、WebSocket API、macOS Intel (x64)、Windows 开发环境;
- Questions?(反馈渠道):通过 GitHub Discussion 或 issue 提交诉求。
这种"明确列出不做什么"的做法,对技术选型者尤其有价值——你可以提前预判未来几年哪些能力不会出现,从而避免在错误的方向上投入。
二、进行中:Web / HTML 渲染器
2.1 现状:移动端三平台已就绪
Valdi 目前已经能将组件渲染到iOS、Android 和 macOS。其工作方式(详见 docs/docs/start-about.md 与 docs/docs/faq.md)为:
- 开发者用 TypeScript / TSX 声明式编写视图与业务逻辑;
- 构建期由 Valdi 编译器将 TS/TSX 编译打包为
.valdimodule文件(代码可打包为 JS 源码、JS 字节码或直接编译为原生 C 代码); - 运行期由 Valdi Runtime(C++ 核心 + JavaScript 引擎 + Yoga 布局引擎)读取模块,并在各平台创建原生视图(iOS 上的
UIView/UILabel,Android 上的ViewGroup/TextView等)。
注意:当前所有平台都有"原生壳"——渲染发生在宿主应用进程内的原生视图树上。
2.2 目标:同一个组件在浏览器中无壳渲染
路线图中提到的 Web renderer 目标,是直接面向 HTML/CSS 渲染,让同一组件能在浏览器中渲染,"without a native shell"(无需原生壳)。这意味着未来可以:
- 将同一套 UI 代码直接跑在浏览器里,用于 Web 场景或跨端预览;
- 不依赖 JS 到原生桥接层,而是由渲染器直接操作 DOM / CSS。
2.3 可用性:今天就能试,但有粗糙之处
路线图明确说明:
The web renderer is available to try today—use it at your own risk and expect rough edges.
即 Web 渲染器目前已可试用,但并非生产就绪,使用时需自担风险并预期有粗糙的边界情况。docs/docs/faq.md 中的 "Does Valdi support a web / HTML target?" 一节与路线图完全一致:"actively in development and available to try today. Expect rough edges—it's not production-ready."
仓库中的 tools/valdi_web_devtools 目录即为围绕该方向搭建的配套工具链(详见 tools/valdi_web_devtools/README.md):
valdi-web-devtools:面向浏览器侧的入口包,提供mountRoot(挂载已编译的 Valdi 模块到 DOM)与attachHmr(接入热更新)两个浏览器安全 API;- webpack 配置助手:
createWebpackConfig({ npmPackageName, npmScope, playgroundDir, entry, ... })帮助把导出的 Valdi 库打包进 Web playground; valdi_web_playgroundBazel 宏:把"导出库 + webpack + HMR dev server + 集成测试脚手架"组装成一个可运行的 playground 目标;- HMR 开发服务器:
hmr-server.js/hmr.js,支持浏览器内热更新迭代。
其 README 还强调了一个工程细节:三处配置必须一致——valdi_exported_library(npm_scope, web_package_name)(BUILD.bazel)、valdi_web_playground(npm_package)(BUILD.bazel)与createWebpackConfig({npmScope, npmPackageName})(webpack.config.js)。编译产物中写死的require('<scope>/<name>')字符串依赖三者的对齐,一旦不一致,宏会在构建期"fail loudly"(大声失败),并给出指明两侧来源的错误信息。
此外,CLI 调试器也提供了 Web 侧能力:docs/docs/command-line-references.md 中的valdi debugger支持--web-preview-url参数,可启动本地浏览器调试界面并接入 Web 预览。
2.4 与现有渲染架构的关系
从 docs/docs/faq.md 对运行时机制的描述可以推断,Web 渲染器面临的挑战与移动端一致:Valdi 的 TSX 会转换为jsx.beginElement(...)/jsx.beginComponent(...)这类渲染器栈操作(而非 React 式的对象 diff),运行时据此以最高效的方式维护视图层级。Web 渲染器需要把这条"动态渲染指令流"重新映射到 DOM/CSS 上,这正是其"rough edges"可能集中的地方——布局(Yoga flexbox 到 CSS 的映射)、文本测量、滚动容器与手势处理都需要在 Web 语义下重新实现。
一句话建议:如果你的团队打算让 Valdi 组件在浏览器中直接运行,请把它当作"可提前验证的预览能力",而不是当前生产环境的依赖项。
三、进行中:bzlmod 支持
3.1 背景:从 WORKSPACE 到 MODULE.bazel
路线图指出,Valdi 目前要求使用者采用基于WORKSPACE的 Bazel 工程布局,团队正在迁移到bzlmod(MODULE.bazel)——这是 Bazel 的现代依赖模型,也是向 Bazel Central Registry(Bazel 中央注册表)发布模块的先决条件。迁移完成后,使用者将能像消费标准 Bazel 模块一样使用 Valdi,而无需手动管理WORKSPACE条目。
3.2 仓库证据:MODULE.bazel 已在根目录就位
仓库根目录的 MODULE.bazel 已经是一个完整、可运行的 bzlmod 模块定义,开头即声明:
module( name = "valdi", version = "0.1", )其后是大量声明式依赖管理,可作为理解 Valdi 构建依赖谱系的入口:
bazel_dep(...):声明对 Bazel Central Registry 上标准模块的依赖,例如toolchains_llvm 1.7.0、rules_pkg 0.9.1、rules_proto 7.1.0、rules_python 1.9.0、rules_cc 0.2.20、googletest 1.17.0、rules_rust 0.64.0、rules_android 0.6.5、rules_swift 3.1.2、rules_apple 4.0.0、aspect_rules_js 2.9.2、rules_nodejs 6.7.5、boringssl、curl 8.12.0等,覆盖 Android / iOS / macOS / Linux 全平台的工具链与三方库;single_version_override(...):对部分模块做版本钉死(如protobuf 29.3、rules_pkg 0.9.1、zlib 1.3.2),并可为指定模块叠加补丁(如rules_android_ndk、rules_android、rules_swift);use_extension(...)+use_repo(...):调用自定义模块扩展,例如:hermetic_android_sdk_extension(见 bzl/hermetic_android_sdk.bzl),配置api_level = 36、build_tools_version = "34.0.0",产出@androidsdk;hermetic_ndk_extension(见 bzl/hermetic_ndk.bzl),产出@androidndk;swift_toolchains_extension(见 bzlmod/swift_toolchains_extension.bzl),注册 Linux x86_64 的 Swift 工具链;valdi_compiler_repos/valdi_compiler_swift_deps,暴露编译器预构建产物与 SwiftPM 依赖;resvg_crate/pngquant_crate,通过 rules_rust 的 crate_universe 管理 Rust 依赖(用于图片解码与 PNG 压缩等);
register_toolchains(...):统一注册 LLVM、Android SDK/NDK、Swift、Rust 等工具链,注释中明确说明"consumers inherit these register_toolchains() without calling any extensions themselves"——即下游使用者无需再自行调用扩展;local_path_override(...):对仓库内部的子模块(如android_macros→ bzl/macros、snap_macros→ bzl/valdi/snap_macros、valdi_toolchain→ bin、skia_user_config→ third-party/skia_user_config)做本地路径覆盖,实现"库内自举"。
可以看到,MODULE.bazel 不只是把依赖平铺出来,还承载了hermetic(封闭式)构建的核心思路:SDK、NDK、工具链全部通过扩展按需下载固定版本,避免依赖宿主机ANDROID_HOME等环境变量(模块注释中专门解释了为什么要给rules_android打 hermetic SDK 补丁)。
3.3 仓库证据:registry 目录——Bazel Central Registry 的发布准备
路线图说 bzlmod 是"发布到 Bazel Central Registry 的前提",仓库中的 registry 目录正是这项工作的落地痕迹:
- registry/bazel_registry.json:Bazel 注册表的元数据描述文件(当前
mirrors为空、module_base_path为空,属于初始状态); - registry/modules 下为每个需要(重新)打包/打补丁的第三方模块建了
模块名/版本号/结构,内含:MODULE.bazel(该版本模块自己的声明);source.json(指向源码归档的描述);metadata.json(模块级元数据);patches/(Valdi 对该模块的定制补丁,如rules_android_hermetic_sdk.patch、rules_android_module_bzl.patch、rules_swift.patch、toolchains_llvm.patch、rules_kotlin.patch、rules_nodejs.patch、websocketpp.patch)。
目前 registry 覆盖的模块包括rules_android、rules_android_ndk、rules_kotlin(含 1.9.0 与 2.3.10 两个版本)、rules_nodejs、rules_swift、toolchains_llvm、websocketpp。这些"打了补丁的官方模块"是 Valdi 在 bzlmod 世界中保持 hermetic 构建的关键——它们既要跟随上游版本,又要带上 Valdi 的定制改动。
从这些文件的存在可以推断:Valdi 的 bzlmod 迁移不只是"改一个构建文件",而是围绕第三方模块的补丁治理、版本钉死与扩展封装建立了一整套配套机制。
3.4 对使用者的影响
迁移完成后,下游项目的体验将从"在WORKSPACE里手工写http_archive/git_repository拉取 Valdi 及一堆传递依赖"变成:
# MODULE.bazel(示意,发布后的最终用法) bazel_dep(name = "valdi", version = "<版本>")即标准 Bazel 模块的消费方式:依赖解析、版本选择、工具链注册均由 Bazel 的模块系统接管。不过需要说明:当前 MODULE.bazel 仍以local_path_override引用了大量仓库内部模块,且valdi版本号为0.1,尚未正式发布到 Bazel Central Registry——这正是路线图中"进行中"的状态。
四、明确不做(一):Swift / SwiftUI 运行时
4.1 事实
路线图明确:iOS 运行时当前是 Objective-C 实现,没有计划用 Swift 重写,也不会提供 SwiftUI interop 层。
4.2 替代方案:Polyglot 模块
这并不意味着不能用 Swift。路线图和 docs/docs/faq.md 都指向同一个解法:Polyglot 模块——让你用 Swift(以及 Kotlin、C++、Objective-C)写 Valdi 能调用的代码,覆盖绝大多数集成需求。
docs/docs/native-polyglot.md 给出了完整实操流程,要点如下:
- TypeScript 定义:在模块的
.d.ts文件中用@ExportModule注解声明 API,例如:
/* @ExportModule */ export const DEFAULT_DELIMITER: string; export function join(components: string[], delimiter: string): string;编译器会据此生成 Objective-C、Swift、Kotlin 等语言的绑定。
Bazel 侧接线:
valdi_module规则导出三个属性,分别挂接不同平台的原生实现:android_deps:Android 构建时引入的android_library(JVM 语言实现);ios_deps:iOS 构建时引入的apple_library/cc_library(Objective-C / Swift 等原生实现);native_deps:全平台(iOS/Android/桌面)引入的cc_library(C++ 跨平台实现)。
平台实现:
- iOS 侧写 Objective-C 实现类,实现生成协议,并在工厂类中用
VALDI_REGISTER_MODULE()注册、onLoadModule懒加载返回模块实例; - Android 侧写 Kotlin 实现类,用
@RegisterValdiModule注解(须经valdi_android_library规则编译,构建期会处理注解)注册; - C++ 侧因编译器暂不支持 C++ 代码生成,绑定需手写,通过
RegisterModuleFactory::registerTyped<MyJoinerModule>()注册。
- iOS 侧写 Objective-C 实现类,实现生成协议,并在工厂类中用
运行时行为:当 TypeScript 首次 import 该
.d.ts文件时,对应平台的工厂onLoadModule被调用,返回的实例即成为该模块的底层实现。
换句话说:"运行时必须是 Swift"不是 Valdi 的承诺,但"你的 Swift 代码能被 Valdi 调用"是现成的能力。
五、明确不做(二):WebSocket API
路线图明确:Valdi 不暴露 WebSocket API。官方给出的 workaround 是:在原生代码中实现 WebSocket 处理,再通过 Polyglot 模块暴露给 Valdi 使用;暂无在运行时增加一等公民 WebSocket 支持的计划。
从仓库现状看,MODULE.bazel 中虽引入了websocketpp 0.8.2.bcr.3(并打了fix_ios_lrt.patch)以及作为 HTTP 传输层的curl,但这些属于底层网络能力,服务于运行时自身的通信需求,并不等于面向 TS 业务层的一等 WebSocket API。业务侧需要长连接时,正确路径是:
业务 TS 代码 │ import ▼ Polyglot 模块(TS 定义 + 原生实现) │ ▼ 原生 WebSocket 客户端(iOS: NSURLSessionWebSocket / Android: OkHttp 等)这也与 Valdi"打破 Web 标准以换取移动端性能与工程效率"的设计哲学一脉相承(见 docs/docs/faq.md 中对 React Native 差异的讨论)——网络能力优先以原生形态提供,而不是在 JS 层重建一套。
六、明确不做(三):macOS Intel(x64)支持
路线图明确:macOS 开发环境与目标平台仅支持 Apple Silicon(arm64),没有添加 x64 支持的计划。
这意味着:
- 在 Intel Mac 上进行 Valdi 开发不可行;
- 以 macOS 为目标平台构建的产物仅面向 arm64;
- 若团队里还有 Intel Mac,需要将其排除在 Valdi 开发环境之外(或通过远程 arm64 构建机)。
仓库的 MODULE.bazel 也侧面印证了这一点:python.single_version_platform_override仅针对aarch64-apple-darwin打补丁;Swift 工具链扩展(bzlmod/swift_toolchains_extension.bzl)注册的是 Linux x86_64 工具链;Rust 的supported_platform_triples中 Apple 平台只包含aarch64-apple-darwin/aarch64-apple-ios等 arm64 变体。可以推断:官方构建矩阵已全面以 arm64 为主。
七、明确不做(四):Windows 开发环境
路线图明确:Valdi 不支持 Windows 作为开发宿主操作系统(host OS)。
这与 Valdi 的工具链现实相符:编译器由 Swift 编写(compiler/compiler),Bazel 工具链与脚本大量面向 macOS/Linux(见 scripts 下的macos_dev_setup.sh、linux_dev_setup.sh等),Android 构建依赖 hermetic SDK/NDK 与 LLVM 工具链。Windows 既不在构建矩阵中,也没有文档化的支持路径。若你的团队全员使用 Windows 开发机,Valdi 目前不适用;需要借助 CI 上的 Linux/macOS 执行环境。
八、综合判断:这些边界如何影响你的选型
将路线图的"进行中"与"明确不做"合起来,可以得到一张清晰的决策表:
| 关注点 | Valdi 现状 | 决策含义 |
|---|---|---|
| 移动端(iOS / Android)UI | 已支持,生产可用的核心场景 | 主战场 |
| macOS 桌面目标 | 已支持(仅 arm64) | Apple Silicon 团队可用 |
| Web / 浏览器渲染 | 开发中,可试用,非生产就绪 | 可提前验证,勿作生产依赖 |
| 依赖管理 | WORKSPACE → bzlmod 迁移中,MODULE.bazel 已就位 | 未来可标准模块方式消费 |
| Swift 集成 | 运行时仍是 Objective-C,但 Polyglot 模块可调 Swift 代码 | 原生能力用 native-polyglot.md 补齐 |
| WebSocket | 无一等 API,需原生实现 + Polyglot 暴露 | 长连接场景需自建 |
| Intel Mac / Windows | 明确不支持 | 开发环境需 arm64 Mac 或 Linux |
需要强调的两点:
- 路线图不是承诺。文档开头就写明优先级会变化,若某项能力对你至关重要,官方建议通过 GitHub Discussion 说明原因——社区的反馈会影响优先级的排序。
- 仓库状态以当前代码为准。本文对"进行中/未提供"的判断基于仓库当前内容(
ROADMAP.md、MODULE.bazel、registry、docs/docs/faq.md 等),能力与版本边界随时可能演进,落地前请以最新仓库为准。
九、反馈与参与
如果你对路线图中的任何条目有诉求(想加速 Web 渲染器、希望重新评估 x64/Windows、或推动某能力进入计划),官方渠道是仓库的 Discussions 与 Issues。结合本文梳理的边界,带着明确的使用场景去沟通,会让你的诉求更容易被评估。
参考与深入阅读(均位于当前仓库)
- 路线图原文:ROADMAP.md
- 常见问题与定位:docs/docs/faq.md
- 框架概述与架构分层:docs/docs/start-about.md
- Polyglot 模块完整教程(Swift/Kotlin/ObjC/C++ 实现):docs/docs/native-polyglot.md
- bzlmod 模块声明:MODULE.bazel、扩展示例 bzlmod/swift_toolchains_extension.bzl
- Bazel Central Registry 发布准备:registry/bazel_registry.json 与 registry/modules
- Web 方向配套工具链:tools/valdi_web_devtools/README.md
- CLI 调试器的 Web 预览参数:docs/docs/command-line-references.md
【免费下载链接】ValdiValdi is a cross-platform UI framework that delivers native performance without sacrificing developer velocity.项目地址: https://gitcode.com/gh_mirrors/val/Valdi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考