TL;DR : Découvrez Tuono pour une expérience de type framework qui vous permet d'exécuter React sur un serveur Rust multithread. Vous pouvez trouver plus de détails ci-dessous.
Accédez au projet complet ici.
Pour cet exemple, nous utiliserons Vite.js pour mettre en place le projet et compiler le code source de React.
npm create vite@latest react-rust -- --template react-ts
Le projet initialisé est conçu exclusivement pour les applications côté client. Dans la section suivante, nous explorerons ce qui est nécessaire pour l'adapter au regroupement full-stack.
React nécessite deux versions distinctes adaptées à différents environnements :
Qu'est-ce qui distingue ces deux sorties ?
La version client intègre toute la logique d'hydratation, permettant à React de se connecter de manière transparente au HTML généré par le serveur. En revanche, la version du serveur est une version plus simplifiée axée uniquement sur le rendu HTML basé sur les accessoires reçus du serveur.
Maintenant, créons un nouveau fichier nommé ./src/server.tsx, qui servira de point d'entrée pour la construction du serveur, et insérons le code suivant :
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()], });
Ensuite, nous devrions ajouter un nouveau script dans le fichier package.json.
-- "build": "tsc && vite build", ++ "build": "tsc && vite build && vite build --ssr src/server.tsx",
Pour cet exemple, nous utiliserons axum, un framework web qui fonctionne sur tokio.
Pour commencer, configurons le projet Rust en créant un fichier Cargo.toml dans le répertoire principal, contenant les détails suivants :
[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"]}
Il s'agit du manifeste Rust - assez similaire au fichier JavaScript package.json.
Ensuite, nous allons créer un fichier nommé src/server/server.rs, qui servira de point d'entrée pour lancer le serveur Rust.
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()) }
C'est ici que la magie opère. Au début du programme, nous commençons par initialiser le moteur JavaScript V8 avec Ssr::create_platform(); Ensuite, nous créons un contexte V8 dans chaque thread en utilisant thread_local !. Enfin, nous rendons le HTML avec SSR.with(|ssr| ssr.borrow_mut().render_to_string(None)); et envoyez-le au client lorsque la route http://localhost:3000/ est demandée.
Pour démarrer le serveur, compilez simplement les actifs avec Vite puis lancez le serveur Rust.
npm run build && cargo run
? Vous exécutez une application React full-stack à l’aide d’un serveur Rust. Enfin, React s'exécute au sein d'un serveur multithread (vous pouvez trouver quelques benchmarks ici).
Gérer une application React full-stack n'est pas facile avec Node.js car de nombreux outils ont été construits au fil du temps pour la prendre en charge, et comme vous avez pu le voir avec Rust, c'est encore plus difficile.
Tuono est un framework full-stack expérimental visant à simplifier le développement d'applications Rust hautes performances, en mettant l'accent à la fois sur la convivialité et la vitesse.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!