写惯 Swift 的开发者做一个网页,往往得重新搭一套 JavaScript 工程。语言换了,状态管理、组件组织和构建工具也要重新适应。这种“从 Swift 到 Web”的跨栈问题在云栈社区里也被反复提起。ElementaryUI 尝试缩短这段距离:用 Swift 描述界面,编译成 WebAssembly,在浏览器里驱动真正的 HTML 元素。
北京时间 10 月 31 日凌晨发布的 0.9.0,把这件事向前推进了一步。新版给视图加入基础的服务端渲染与静态生成支持,也重做了列表身份识别的一部分接口。对已经在用 Swift、又想做内部网页或交互组件的团队,这比一句“Swift 也能做前端”更值得仔细看。
我喜欢它的一点,是没有假装浏览器不存在。它借用了 SwiftUI 的 View、State 等思路,但界面里依然写 div、p、button,排版依然遵循 CSS。熟悉的语言负责组织逻辑,网页自己的规则负责呈现。这也解释了它的边界:已有 SwiftUI 应用不能原封不动搬进去,原生组件与浏览器元素之间仍然需要重新设计。
官方 README 的计数器很能说明这种关系。下面是放在 ElementaryUI 应用里的一个视图片段:状态变化后,框架负责更新对应的页面内容。
@View
struct Counter {
@State var count = 0
var body: some View {
div {
p { "Count: \(count)" }
button { "Increment" }
.onClick { count += 1 }
}
}
}
小例子之外,列表才是界面框架容易露出真实成本的地方。待办项删除、排序、插入时,页面要知道哪一行还是原来的对象,才能保留正确的节点与状态。0.9 支持用任意 Hashable 值作为 ForEach 的 id,也能直接接收 Identifiable 元素;同时优化了逐行跟踪、响应式更新和属性修改。官方没有给出可直接套到业务上的统一提速倍数,我也不会把减少分配等同于所有页面都更快。
这次新增的 .render() 则让 ElementaryUI 视图可以输出 HTML。静态页面不必等浏览器把整套交互逻辑启动起来才有内容,这是服务端渲染值得投入的原因。
但版本说明的用词是“基础支持”。能生成 HTML,并不自动等于拥有成熟的客户端 hydration、路由与完整的全栈工程体系。选型时要把已经交付的能力和未来的方向分开看。
要试用,官方入门文档提供了 Vite 模板。准备好 Swift 6.4 或更新工具链、匹配的 WebAssembly SDK,以及 Node.js 22 以上环境后,可以按下面的步骤建立试验项目;具体依赖版本以模板当前配置为准。
npx degit elementary-swift/starter-vite my-elementary-project
cd my-elementary-project
npm install
npm run dev
开发服务器启动后,浏览器访问终端提示的本机地址即可。Vite 负责开发流程,Swift 源码变化后可以热重载;这条路并没有消除前端工具链,而是让 Swift 加入了现成的 Web 开发流程。框架对 Embedded Swift 的兼容也有实际意义:尽量减少运行时负担,为较小的 Wasm 产物留出空间。最终体积仍要看应用代码与依赖,不能仅凭框架介绍下判断。
升级到 0.9 还要留意几处明确变化:旧的 key: 与 .key() 接口被弃用,转向 id: 与 .id();ForEach 要求 RandomAccessCollection,且不再是 Sendable;macOS 最低版本提升到了 26。对于靠旧系统跑开发环境的团队,最后这一条可能比任何新功能都更先影响决策。
我会把它用于一个边界清楚的小组件或内部工具,观察编译、调试和交互的完整体验。让 Swift 真正进入网页工程,最有说服力的进展,正是这样一项项补齐列表、渲染和开发流程中的具体缺口。
项目地址:https://github.com/elementary-swift/elementary-ui
|