Rust 生态的前端框架 Yew!对标 Vue!

家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

前言

WebAssembly,俗称 WASM,彻底改变了 Web 应用程序的构建方式。 它允许开发人员使用最喜欢的编程语言来构建 Web 应用程序。

有了这些可能性,开发人员在构建前端应用程序时就无需承担学习 JavaScript 框架的负担。 可以利用自己喜欢的编程语言特性(如静态类型、模式匹配、内存安全等)来构建前端应用程序。

本文将学习如何使用 Yew 的开放 API 构建 Web 应用程序。

1. 什么是Yew

Yew 是一个现代 Rust 框架,用于使用 WebAssembly 创建多线程前端 Web 应用程序。Yew具有一个宏,用于使用 Rust 表达式声明交互式 HTML。 在 React 中使用过 JSX 的开发人员在使用 Yew 时应该会很轻松。

Yew通过最小化每个页面呈现的 DOM API 调用并轻松将复杂处理交给后台Web Worker来实现高性能。同时,Yew支持与JavaScript 的互操作性,允许开发人员利用 NPM 包并与现有的 JavaScript 应用程序集成。

注意:Yew 还未达到稳定的1.0版本,后续版本改动可能会带来破坏性改动。

2.Yew特性

组件化

Yew是基于组件化的框架,可以轻松创建交互式 UI。具有 React 和 Elm 等框架经验的开发人员很容易上手。

比如可以通过在函数名称前面添加#[function_component]属性来轻松声明函数式组件:

#[function_component(HelloWorld)]
fn hello_world() -> Html {
    html! { "Hello world" }
}

函数式组件是普通组件的简化版本。它们由一个接收 props 的函数组成,并通过返回Html来确定页面应该渲染的内容。本质上,是一个简化为view方法的组件,只能创建纯组件,如果有其他需求只能通过Hooks完成。

HTML宏

Yew具有一个宏,用于使用 Rust 表达式声明交互式 HTML。html! 宏允许开发者为组件编写声明式的 HTML 和 SVG。如果使用过 React 的 JSX,将会感觉到非常熟悉。但是有几个点需要注意:

  • html! 宏调用中只能有一个根节点
  • 空的 html! {} 宏调用是有效的但不会渲染任何内容
  • 常量必须始终被引号括起来并被包含在大括号里,比如:html! { "Hello, World" }

服务器端渲染

默认情况下,Yew 使用客户端渲染。 当访问网站时,服务器会向浏览器发送一个没有任何实际内容的框架 HTML 文件和一个 WebAssembly 包。 一切都由 WebAssembly 包在客户端渲染。 这称为客户端渲染。

这种方法适用于大多数网站,但有一些注意事项:

  • 在下载整个 WebAssembly 包并完成初始渲染之前,用户看不到任何内容,从而体验较差
  • 一些搜索引擎不支持动态呈现的网页内容,而那些支持动态网站的搜索引擎通常在搜索结果中将动态网站排在较低的位置。

为了解决这些问题,Yew可以在服务器端渲染网站。比如下面的例子:

use yew::prelude::*;
use yew::ServerRenderer;

#[function_component]
fn App() -> Html {
    html! {
{"Hello, World!"}
} } // #[tokio::main] // 使用 `flavor = "current_thread"` 所以这个片段可以在 CI 中测试, // 其中测试在 WASM 环境中运行,也可以使用`multi_thread` #[tokio::main(flavor = "current_thread")] async fn no_main() { let renderer = ServerRenderer::::new(); let rendered = renderer.render().await; // 打印:
Hello, World!
println!("{}", rendered); }

Yew 提供了一个 ServerRenderer 来在服务器端渲染页面。要在服务器端渲染 Yew 组件,可以使用 ServerRenderer::::new() 创建渲染器并调用 renderer.render().await 将 渲染成字符串。

3.Vue和Yew对比

请看下图,以下是两种技术之间的相似之处:

4.使用Yew开发

4.1 开发环境设置

首先,需要确保在机器上安装了最新版本的 Rust。可以通过运行以下命令升级到稳定版本:

rustup update

接下来,需要安装一个 WASM 工具,这是一个帮助开发者将 Rust 源代码编译成基于浏览器的 WebAssembly 并使其在 Web 浏览器上运行的工具。可以通过运行以下命令来安装它:

rustup target add wasm32-unknown-unknown

最后,需要安装 Trunk,这是一个用于管理和打包 WebAssembly 应用程序的工具。

cargo install trunk

4.2 开发开发

首先,需要导航到所需的目录并在终端中运行以下命令:

cargo new yew-starter && cd yew-starter

此命令创建一个名为 yew-starter 的 Rust 项目并导航到项目目录。cargo 是 Rust 的包管理器, 它的工作方式类似于 Vue 生态系统中的 npm。运行命令时,cargo 将生成一个包含基本文件的项目目录,如下所示:

  • main.rs 是应用程序的入口。
  • Cargo.toml 是用于指定项目元数据(如包、版本等)的清单文件,作用类似于 Vue 应用程序中的 package.json。

接下来,继续通过修改 Cargo.toml 文件的 [dependencies] 部分来安装所需的依赖项,如下所示:

// 其他代码
[dependencies]
yew = "0.19"
serde = "1.0.144"
gloo-net = "0.2"
wasm-bindgen-futures = "0.4"
  • yew = "0.19" 是一个基于 Rust 的前端框架
  • serde = "1.0.136" 是一个用于序列化和反序列化 Rust 数据结构的框架。 例如。 将 Rust 结构转换为 JSON。
  • gloo-net= "0.2" 是一个 HTTP 请求库,工作方式类似于 Vue 生态系统中的 axios。
  • wasm-bindgen-futures = "0.4" 是一个基于 Rust 的库,用于通过弥合 Rust 异步编程(futures)和 JavaScript Promises 之间的差距在 Yew 中执行异步编程。 基本上,它有助于在 Rust 中利用基于 Promise 的 Web API。

需要运行以下命令来安装依赖项:

cargo build

4.3 设置应用入口

安装项目依赖后,需要修改 src 文件夹中的 main.rs 文件,如下所示:

use yew::prelude::*;

#[function_component(App)]
fn app() -> Html {
    html! {
        

{ "Yew for Vue developers" }

} } fn main() { yew::start_app::(); }
  • yew::prelude::* :通过指定 * 导入所需的 yew 依赖项及其关联项
  • #[function_component(App)]:将app函数声明为一个以App为名称的Functional组件。 这里使用的语法称为 Rust 宏; 宏是编写其他代码的代码。
  • fn app() -> Html {…..} :使用 html! 为 Vue 开发人员标记创建 Yew 的宏。 该宏的工作方式类似于 Vue 中的模板语法。
  • yew::start_app::():通过将 App 组件安装到文档主体来启动 Yew 应用程序。 它的工作方式类似于 Vue 中的 createApp(App).mount() 函数。

4.4 HTML渲染

与 Vue 渲染到 DOM 的方式类似,同样的原则适用于 Yew。接下来,需要在项目的根目录中创建一个支持 Bootstrap CDN 的 index.html 文件,并添加以下代码片段:




    
    
    
    
    Yew Starter



接下来,可以通过在终端中运行以下命令来启动开发服务器来测试应用程序:

trunk serve --open

下面是浏览器看到的内容:

5.本文总结

本文主要和大家介绍下Rust 生态的前端框架 Yew,对标 Vue!文章从什么是Yew 、Yew特性 、Vue和Yew对比 、如何使用Yew开发等几个维度展开。总体来看只是做了一个简短的介绍,但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。如果大家有什么疑问欢迎在评论区留言。


参考资料

https://github.com/yewstack/yew

https://yew.rs/zh-Hans/docs/next/advanced-topics/server-side-rendering

https://dev.to/hackmamba/exploring-yew-the-rust-based-frontend-framework-as-a-vue-developer-3915

https://swc.rs/docs/configuration/minification