18 个不稳定版本 (3 个重大更改)
新版本 0.5.8 | 2024 年 8 月 18 日 |
---|---|
0.5.7 | 2024 年 7 月 26 日 |
0.5.5 | 2024 年 6 月 27 日 |
0.4.0 | 2024 年 3 月 9 日 |
0.2.3 | 2021 年 5 月 23 日 |
#1122 in Web 编程
每月下载量 435
在 tuono_lib 中使用
39KB
260 行
🚀 Rust 服务器端渲染
该软件包旨在以最简单和最轻量级的方式启用 Rust 服务器上的服务器端渲染。
它使用 V8 JavaScript 引擎的嵌入版本(rusty_v8)来解析和评估构建的捆绑文件,并返回一个包含渲染 HTML 的字符串。
[!注意] 此项目是 tuono 的基础;一个内置 SSR 的全栈 React 框架。
目前它与 Vite、Webpack、Rspack、React 18 和 Svelte 4 一起工作 - 检查 examples/
文件夹。
在此处查看基准测试结果。
入门
将此添加到您的 Cargo.toml
cargo add ssr_rs
示例
要渲染捆绑的 React 项目到字符串,应用程序应执行以下调用。
use ssr_rs::Ssr;
use std::fs::read_to_string;
fn main() {
Ssr::create_platform();
let source = read_to_string("./path/to/build.js").unwrap();
let mut js = Ssr::new(&source, "entryPoint").unwrap();
let html = js.render_to_string(None).unwrap();
assert_eq!(html, "<!doctype html><html>...</html>".to_string());
}
什么是 "entryPoint"?
entryPoint
可以是
- 返回具有一个或多个属性的对象的函数,这些属性是函数,当调用时返回渲染结果
- 具有一个或多个属性的对象本身,这些属性是函数,当调用时返回渲染结果
如果捆绑的 JS 是 IIFE 或普通对象,则 entryPoint
是空字符串。
// IIFE example | bundle.js -> See vite-react example
(() => ({ renderToStringFn: (props) => "<html></html>" }))() // The entryPoint is an empty string
// Plain object example | bundle.js
({renderToStringFn: (props) => "<html></html>"}); // The entryPoint is an empty string
// IIFE variable example | bundle.js -> See webpack-react example
var SSR = (() => ({renderToStringFn: (props) => "<html></html>"}))() // SSR is the entry point
// Variable example | bundle.js -> See webpack-react example
var SSR = {renderToStringFn: (props) => "<html></html>"}; // SSR is the entry point
导出结果由打包器直接管理。
带有初始属性的示例
use ssr_rs::Ssr;
use std::fs::read_to_string;
fn main() {
Ssr::create_platform();
let props = r##"{
"params": [
"hello",
"ciao",
"こんにちは"
]
}"##;
let source = read_to_string("./path/to/build.js").unwrap();
let mut js = Ssr::new(&source, "entryPoint").unwrap();
let html = js.render_to_string(Some(&props)).unwrap();
assert_eq!(html, "<!doctype html><html>...</html>".to_string());
}
带有 actix-web 的示例
不同 Web 框架的示例可在 示例 文件夹中找到。
尽管V8引擎允许从不同的线程访问相同的isolate
,但这在此crate中被禁止,原因有两个
- rusty_v8库尚未实现V8 Locker API。从不同的线程访问Ssr结构体会导致V8引擎panic。
- 渲染HTML不需要在多个线程间共享状态。
由于上述原因,并行计算是一个更好的选择。以下是actix-web的配置
use actix_web::{get, http::StatusCode, App, HttpResponse, HttpServer};
use std::cell::RefCell;
use std::fs::read_to_string;
use ssr_rs::Ssr;
thread_local! {
static SSR: RefCell<Ssr<'static, 'static>> = RefCell::new(
Ssr::from(
read_to_string("./client/dist/ssr/index.js").unwrap(),
"SSR"
).unwrap()
)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
Ssr::create_platform();
HttpServer::new(|| {
App::new()
.service(index)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
#[get("/")]
async fn index() -> HttpResponse {
let result = SSR.with(|ssr| ssr.borrow_mut().render_to_string(None).unwrap());
HttpResponse::build(StatusCode::OK)
.content_type("text/html; charset=utf-8")
.body(result)
}
贡献
任何帮助或建议都将受到赞赏。
已知的待办事项
- 添加与其他Rust后端框架的示例
- 添加与其他前端框架(例如vue、quik、solid)的示例
- 添加基准测试设置以测试与Deno和Bun的对比
- 探索对V8快照的支持
- 探索将JS编译成WASM(例如javy)
许可证
本项目采用MIT许可证 - 请参阅LICENSE_MIT或LICENSE_APACHE文件以获取更多信息。
依赖关系
~65MB
~1.5M SLoC