react ssr

继续创建增强的服务器端渲染实现。 在第一部分中,我们准备了带有SSR脚本的ReactJS应用程序,该脚本可让我们为Web服务器选择最佳技术。

为SSR Web服务器选择技术堆栈

Rust是当今安全性和高速性最强大的组合(您可以在此处查看原因-www.rust-lang.org )。 另外,根据TechEmpower Framework Benchmark ,Actix-web框架是最快的。

因此,让我们对强制Web服务器使用最佳技术。

设置Rust应用

在计算机上设置Rust很容易-只需转到rustup.rs网站并安装rustup CLI。

下一步是初始化一个新的应用程序。 货物,Rust包管理器可以提供帮助:在存储库文件夹中运行cargo init 。

每个包装的Cargo.toml文件称为清单。 它包含设置和依赖性。 新的应该是这样的:

[package]
name = "rust-ssr-webserver"
version = "0.1.0"
authors = [ "Alex Tkachuk <alex@pagespeed.green>" ]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

现在我们可以添加依赖项:

actix-web = { version = "^2.0.0" , features = [ "rustls" ] }
actix-rt = "^1.0.0"
actix-files = "^0.2.1"
env_logger = "^0.7.1"
futures = "^0.3.4"
mime_guess = "^2.0.1"
serde_json = "^1.0.40"
lazy_static = "^1.4.0"
rustls = "^0.16.0"

使用actix-web很容易创建Web服务器。 首先,我们需要阅读SSL密钥以支持HTTPS和HTTP / 2:

let mut config = ServerConfig::new(NoClientAuth::new());
let cert_file = & mut BufReader::new(File::open( "cert.pem" ).unwrap());
let key_file = & mut BufReader::new(File::open( "key.pem" ).unwrap());
let cert_chain = certs(cert_file).unwrap();
let mut keys = rsa_private_keys(key_file).unwrap();

config.set_single_cert(cert_chain, keys.remove( 0 )).unwrap();

请注意在生产环境中使用unwrap()-如果失败,则应用程序将崩溃(出现紧急情况)。

现在,我们准备好实际使用Web服务器代码:

HttpServer::new(|| {
        App::new()
            .wrap(middleware::Logger::default ())
            .service(Files::new( "/static" , "static" ))
            .default_service(
                web::resource( "" )
                    .route(web::get().to(index))
                    .route(
                        web::route()
                            .guard(guard::Not(guard::Get()))
                            .to(|| HttpResponse::MethodNotAllowed()),
                    ),
            )
    })
    .bind_rustls( "0.0.0.0:3001" , config)?
    .run()
    .await

这行代码: .service(Files::new("/static", "static")用于处理我们通过运行前一篇文章中的npm build:ssr创建的所有静态断言-( 如何使用SSR和Rust改进React App性能 [第一部分:SSR] )。 为了处理来自ReactJs AppHTML文件请求,我们需要使用.default_service()通过使用带空字符串的web::resource("")来服务所有路由。 index函数是此类请求的处理程序:

asyncfn index (req: HttpRequest) -> impl Responder {
    let path_req = req.match_info().query( "tail" ).get( 1 ..).unwrap_or_default().trim().clone();
    let path = if path_req.len() == 0 {
        "home_page"
    } else {
        match ROUTES.get(path_req) {
            Some (r) => r,
            None => "index"
        }
    };

    match std::fs::File::open( format! ( "static/{}.html" , path)) {
        Ok ( mut file) => {
            let mut contents = String ::new();
            file.read_to_string(& mut contents).unwrap_or_default();

            HttpResponse:: Ok ()
                .content_type( "text/html; charset=utf-8" )
                .header( "Cache-Control" , "no-cache, no-store, max-age=0, must-revalidate" )
                .header( "pragma" , "no-cache" )
                .header( "x-ua-compatible" , "IE=edge, Chrome=1" )
                .body(contents)
        },
        Err (e) => {
			// error handling
        }
    }
}

该函数实现了路由逻辑,因此我们的Web服务器可以通过路由返回正确HTML文件(呈现的React服务器)。 ROUTES常量基本上包含来自React端生成的routes.json数据。

您可以为此实现做的一项改进是使用现金而不是直接从磁盘读取文件。

最后,麻烦地将文件夹dist / web复制到静态,这应该是自动步骤,并通过cargo r运行我们的Web服务器。

完整示例位于 在GitHub仓库中 。

服务器端渲染的最后一篇文章是关于测试此解决方案与Node.js之间的性能的

您可以通过获取PageSpeed Green网站的Google PageSpeed Insights性能得分来检查这种方法在生产中的速度。

编码愉快!

react ssr