Rust真全栈开发快速入门
虚假的全栈开发,前端后端分离然后分别使用不同的编程语言来开发前后端,真实的全栈开发,前后端全用Rust编程语言,无需打开两个项目分别维护,本文使用的技术栈是Leptos
, tailwindcss
, trunk
。
Cargo.toml的依赖如下:
[dependencies]
leptos = { version = "0.5.4", features = ["csr"] }
环境准备
增加编译目标
最终的前端代码会以wasm
文件存在
rustup target add wasm32-unknown-unknown
首先需要安装构建项目的必要命令行工具
cargo install trunk wasm-bindgen-cli
安装wasm-bindgen-cli其实非必要,因为当trunk找不到这个命令行工具的时候会自动到github下载,但是, 因为众所周知的原因,可能访问失败,所以建议直接手动安装
安装tailwindcss命令行工具
安装tailwindcss命令行工具也是非必要,因为trunk也会尝试自己安装,之所以手动换安装和上面的原因一样。
这有两个办法,一个是通过npm安装,一个是直接使用tailwindcss提供的二进制执行文件。
如果你已经有node环境的话,那就直接使用npm安装吧,不过要保证能够直接在终端执行tailwindcss
命令。
npm install -g tailwindcss
手动安装的话可以去这个地址https://github.com/tailwindlabs/tailwindcss/releases下载对应平台最新的二进制文件,然后放到PATH
路径中的某个目录, 只有能在终端执行的时候找到tailwindcss
命令即可。
快速入门
创建项目
cargo new leptos-demo
# 没错, leptos还支持ssr
cargo add leptos --features=csr
然后进入开发目录创建index.html
cat > index.html <<EOF
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>
EOF
将src/main.rs
文件的内容替换如下
use leptos::*;
fn main() {
mount_to_body(|| view! { <p>"Hello, world!"</p> })
}
现在目录结构如下
leptos-demo
├── src
│ └── main.rs
├── Cargo.toml
├── index.html
然后我们就可以在rust项目的根目录执行以下命令启动项目了。
trunk serve
trunk
提供了一个和当下前端开发差不多的开发体验,它包括打包,热加载等功能,所以当我们修改代码的时候,trunk
会检测到并重新编译,前端的页面也会自动刷新。
Tailwindcss
上面虽然很快的构建了一个可以运行的页面,但是前端很重要的是用户体验,也就是有一些必要的CSS样式,所以需要一个CSS框架,大家可以根据自己的需要选择,而我选择的是TailwindCSS
, 我很喜欢这个框架。
我们可以创建以下文件。
tailwind.config.js
module.exports = {
content: {
files: ["./src/**/*.rs", "index.html"],
},
darkMode: "media", // 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};
src/tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;
创建完上述两个文件之后,文件结构如下
.
├── Cargo.lock
├── Cargo.toml
├── index.html
├── src
│ ├── main.rs
│ └── tailwind.css
└── tailwind.config.js
第一个文件是为了使用编辑器的时候获得tailwindcss
的提示, VSCode对应的插件名是: Tailwind CSS IntelliSense
。
在VSCode似乎光是tailwind.config.js
文件不生效,所以我还设置了以下配置。
{
"emmet.includeLanguages": {
"rust": "html",
"*.rs": "html"
},
"tailwindCSS.includeLanguages": {
"rust": "html",
"*.rs": "html"
}
}
最后将index.html
修改成如下内容。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link data-trunk rel="tailwind-css" href="src/tailwind.css"/>
</head>
<body>
</body>
</html>
上面的重点主要是<link data-trunk rel="tailwind-css" href="src/tailwind.css"/>
这一行,通过这一行的设置, trunk
会在编译的时候也调用tailwindcss
命令行工具生成对应的CSS, 所以可以实时的预览tailwindcss
的显示效果。
至此,前端开发的主要问题解决了,可以愉快的开发,不过还有一些问题没有提,这主要是因为这是一篇单独的文章,以后有机会再写相关的系列文章吧。
一个更具体的例子
如果你对上面的例子不够满意,那么可以将main.rs
替换成以下内容,下面的例子是创建了一个可以交互的页面,显示效果如下:
use leptos::*;
#[component]
pub fn SimpleCounter( initial_value: i32) -> impl IntoView {
// 创建一个信号, 一个类似于其他前端框架的state
let (value, set_value) = create_signal( initial_value);
// 为三个按钮分别创建对应的事件函数
// value和set_value都实现了Copy trait所以不需要额外的调用clone方法
let clear = move |_| set_value.set(0);
let decrement = move |_| set_value.update(|value| *value -= 1);
let increment = move |_| set_value.update(|value| *value += 1);
view! {
<div class="container flex items-center mt-20 flex-col">
<div class="">
<span class="text-gray-500">"Value: " {move || value.get().to_string()} "!"</span>
</div>
<div class="flex gap-2 items-center mt-2">
<button on:click=clear
class="hover:bg-red-400 rounded-md bg-blue-500 text-white text-sm font-medium pl-2 pr-3 py-2 shadow-sm">
"Clear"
</button>
<button on:click=decrement
class="hover:bg-yellow-400 rounded-md bg-yellow-500 text-white text-sm font-medium pl-2 pr-3 py-2 shadow-sm">
"-1"
</button>
<button on:click=increment
class="hover:bg-green-400 rounded-md bg-green-500 text-white text-sm font-medium pl-2 pr-3 py-2 shadow-sm">
"+1"
</button>
</div>
</div>
}
}
pub fn main() {
mount_to_body(|| view! { <SimpleCounter initial_value=3 /> })
}
SSR
就像本文标题所说的那样,我要的是全栈开发,而不是用某种技术来替代前端开发,leptos
的设计之初就考虑到了SSR, 它可以跟其他web框架集成,然后前后端都是Rust编程语言开发,本文暂时不具体说明了。
Leptos的其他特性
Leptos非常接近其他的前端框架,几乎该有的都有了,比如路由,控制流,动态属性,组件传参和上下文等,有兴趣的可以查阅官方文档: https://book.leptos.dev/getting_started/index.html
不足
如果你真的准备跟我一样拥抱本文所说的全栈开发,在此之前, 请容许我先说说这个技术栈的一些不足。
-
社区资源不够强大
因为
wasm
和leptos
都比较新,所以相较于react
,vue
之类的前端框架社区, 肯定是不够后者强大的,所以开发可能会遇到很多新的问题,然后不知道怎么解决。 -
UI框架不多
还是一样的问题,因为积累相较于
JavaScript
的前端框架还是太少,所以可能需要自己写很多东西,而没有现成的UI框架和组件, 不过也不是完全没有, 可以参考这个地址里的资源: https://github.com/leptos-rs/awesome-leptos -
入门门槛高
Rust的学习是一道坎,而新的概念也是一道坎。
-
稳定性
由于
leptos
还没到1.0版本,所以在此之前可能会有破坏性升级,那么就可能需要在开发过程中维护这些差异,而且在学习过程中会发现很多教程里的内容过时了。
总结
这篇文章算是之前diss前端开发复杂性的文章的后续,我感觉终于找到了适合自己的全栈开发实践,以后还是有相关内容的文章,可能是leptos的系列文章,就像axum系列文章一样。