TL;DR: 다중 스레드 Rust 서버에서 React를 실행할 수 있는 프레임워크와 유사한 경험을 보려면 Tuono를 확인하세요. 자세한 내용은 아래에서 확인하실 수 있습니다.
여기에서 전체 프로젝트에 액세스하세요.
이 예에서는 Vite.js를 사용하여 프로젝트를 설정하고 React 소스 코드를 컴파일합니다.
npm create vite@latest react-rust -- --template react-ts
초기화된 프로젝트는 클라이언트 측 애플리케이션 전용으로 설계되었습니다. 다음 섹션에서는 이를 풀 스택 번들링에 적용하는 데 필요한 것이 무엇인지 살펴보겠습니다.
React에는 다양한 환경에 맞게 조정된 두 가지 개별 빌드가 필요합니다.
두 출력의 차이점은 무엇인가요?
클라이언트 빌드에는 모든 하이드레이션 로직이 통합되어 있어 React가 서버에서 생성된 HTML과 원활하게 연결할 수 있습니다. 이에 비해 서버 빌드는 서버에서 받은 props를 기반으로 HTML을 렌더링하는 데만 초점을 맞춘 더욱 간소화된 버전입니다.
이제 서버 빌드의 진입점 역할을 할 ./src/server.tsx라는 새 파일을 만들고 다음 코드를 삽입해 보겠습니다.
import "fast-text-encoding"; // Mandatory for React18 import { renderToString } from "react-dom/server"; import App from "./App"; export const Server = () => { const app = renderToString(<App />); return `<!doctype html> <html> <head> <title>React + Rust = ❤️</title> <script type="module" crossorigin src="/index.js"></script> </head> <body> <div> <blockquote> <p>If you're working with React 18 or a newer version, it's essential to run npm install fast-text-encoding. This step is necessary because the Rust server lacks the Node.js objects and functions and the Web APIs. As a result, we need to provide a polyfill for TextEncoder, which is required by react-dom/server (in fact it is declared beforehand).</p> </blockquote> <p>We need to modify the vite.config.ts file to include the two outputs:<br> </p> <pre class="brush:php;toolbar:false">import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; export default defineConfig({ build: { rollupOptions: { output: { format: "iife", dir: "dist/", }, }, }, ssr: { target: "webworker", noExternal: true, }, plugins: [react()], });
다음으로 package.json 파일에 새 스크립트를 추가해야 합니다.
-- "build": "tsc && vite build", ++ "build": "tsc && vite build && vite build --ssr src/server.tsx",
이 예에서는 tokio 위에서 작동하는 웹 프레임워크인 axum을 사용합니다.
시작하려면 다음 세부 정보가 포함된 Cargo.toml 파일을 기본 디렉터리에 생성하여 Rust 프로젝트를 설정해 보겠습니다.
[package] name = "react-rust-ssr-example" version = "0.1.0" edition = "2021" [[bin]] name = "ssr" path = "src/server/server.rs" [dependencies] ssr_rs="0.7.0" tokio = { version = "1", features = ["full"] } axum = "0.7.4" tower-http = {version = "0.6.0", features = ["fs"]}
이것은 Rust 매니페스트입니다. JavaScript package.json 파일과 매우 유사합니다.
다음으로 Rust 서버를 시작하기 위한 진입점 역할을 할 src/server/server.rs라는 파일을 설정하겠습니다.
use axum::{response::Html, routing::get, Router}; use ssr_rs::Ssr; use std::cell::RefCell; use std::fs::read_to_string; use std::path::Path; use tower_http::services::ServeDir; thread_local! { static SSR: RefCell<Ssr<'static, 'static>> = RefCell::new( Ssr::from( read_to_string(Path::new("./dist/server.js").to_str().unwrap()).unwrap(), "" ).unwrap() ) } #[tokio::main] async fn main() { Ssr::create_platform(); // build our application with a single route let app = Router::new() .route("/", get(root)) .fallback_service(ServeDir::new("dist")); // run our app with hyper, listening globally on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } async fn root() -> Html<String> { let result = SSR.with(|ssr| ssr.borrow_mut().render_to_string(None)); Html(result.unwrap()) }
여기서 마법이 펼쳐집니다. 프로그램 시작 시 Ssr::create_platform()으로 JavaScript V8 엔진을 초기화하여 작업을 시작합니다. 다음으로, thread_local!을 사용하여 각 스레드에 V8 컨텍스트를 생성합니다. 마지막으로 SSR.with(|ssr| ssr.borrow_mut().render_to_string(None));을 사용하여 HTML을 렌더링합니다. http://localhost:3000/ 경로가 요청되면 클라이언트에 보냅니다.
서버를 시작하려면 Vite로 자산을 컴파일한 다음 Rust 서버를 시작하면 됩니다.
npm run build && cargo run
? Rust 서버를 사용하여 전체 스택 React 애플리케이션을 실행하고 있습니다. 마지막으로 React는 다중 스레드 서버 내에서 실행됩니다(여기에서 일부 벤치마크를 찾을 수 있습니다).
풀 스택 React 애플리케이션을 관리하는 것은 Node.js에서는 쉽지 않습니다. 이를 지원하기 위해 많은 도구가 추가로 구축되었기 때문입니다. Rust에서 볼 수 있듯이 이는 더욱 어렵습니다.
Tuono는 유용성과 속도 모두에 중점을 두고 고성능 Rust 애플리케이션 개발을 단순화하는 것을 목표로 하는 실험적인 풀 스택 프레임워크입니다.
위 내용은 Rust를 사용한 서버측 렌더링 React에 대한 단계별 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!