ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

使用 Nitro + Vite 实现 React SSR:流式渲染、资源自动管理与客户端水合完整指南

2026/9/15 12:04:36 拓冰建站 浏览量
使用 Nitro + Vite 实现 React SSR:流式渲染、资源自动管理与客户端水合完整指南 使用 Nitro Vite 实现 React SSR流式渲染、资源自动管理与客户端水合完整指南【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro本文基于 Nitro 官方示例 vite-ssr-react对应文档 docs/4.examples/vite-ssr-react.md系统讲解如何在 Nitro 中借助 Vite 构建 React 服务端渲染SSR应用。你将掌握如何配置 Nitro Vite 插件与 React 插件、通过?assetsclient/?assetsssr查询参数实现资源清单自动合并、使用react-dom/server.edge输出流式 HTML并让客户端通过hydrateRoot完成水合。读完本文你将能独立搭建一个可本地开发、可生产构建、可预览的 Nitro Vite React SSR 应用。技术概览在 Nitro 生态中服务端渲染SSR的推荐路径是与 Vite 深度集成Vite 负责将 React 组件分别构建为浏览器端client与服务端server两套产物Nitro 则作为最终的服务端运行时负责接收请求、渲染 HTML 并输出到任意部署目标Node.js、边缘运行时、静态托管等。整个搭建流程包含四个步骤在 Vite 配置中加入 Nitro 插件与 React 插件配置客户端与服务端入口编写服务端入口将 React 应用渲染为 HTML 流编写客户端入口对服务端渲染出的 HTML 执行水合这套方案的核心价值在于流式 HTML 响应提升首字节时间 TTFB、资源自动管理CSS/JS 清单自动收集与合并以及客户端水合无需重新渲染即可绑定事件。环境准备与项目骨架参考 examples/vite-ssr-react/package.json一个最小可运行的 SSR 项目依赖如下{ type: module, scripts: { build: vite build, preview: vite preview, dev: vite dev }, devDependencies: { types/react: ^19.2.14, types/react-dom: ^19.2.3, vitejs/plugin-react: ^6.0.1, nitro: latest, react: ^19.2.4, react-dom: ^19.2.4, react-refresh: ^0.18.0, vite: latest } }几个关键点type: module声明项目使用 ESM 模块体系与 Nitro 和 Vite 的原生 ESM 构建方式保持一致三个脚本全部走 Vitevite dev启动开发服务器含热更新vite build执行生产构建vite preview预览构建产物react-refresh与vitejs/plugin-react配合提供开发期的 React Fast Refresh 能力。对应的 TypeScript 配置examples/vite-ssr-react/tsconfig.json直接继承 Nitro 提供的预设并显式声明 JSX 运行时{ extends: nitro/tsconfig, compilerOptions: { jsx: react-jsx, jsxImportSource: react } }jsx: react-jsx启用 React 17 的新 JSX 转换无需显式import ReactjsxImportSource: react指定 JSX 运行时来源。第一步配置 Vite创建 vite.config.mjs同时挂载 Nitro 插件与 React 插件并声明client环境environmentimport { defineConfig } from vite; import { nitro } from nitro/vite; import react from vitejs/plugin-react; export default defineConfig({ plugins: [nitro(), react()], environments: { client: { build: { rollupOptions: { input: ./src/entry-client.tsx } }, }, }, });这里有三层含义nitro()来自nitro/vite这是 Nitro 面向 Vite 的官方集成插件。它接管了服务端构建与运行时装配在开发期提供 Nitro 开发服务器与热重载在生产期输出可部署的服务端产物。该插件的底层实现可参考 src/build/vite/plugin.ts其中包含对客户端构建产物目录、入口文件命名规则等 Vite 配置的自动改写。react()来自vitejs/plugin-react负责 JSX 编译、开发期 Fast Refresh 等 React 专属能力。environments.client告诉 Vite 以./src/entry-client.tsx作为浏览器端打包入口。这是 Vite 5.1 引入的多环境client/ssr构建模型Nitro 插件在此模型下同时管理 SSR 环境的构建。服务端入口的自动发现Nitro 会自动从app/、src/或项目根目录下查找名为entry-server的文件作为 SSR 入口因此示例中的src/entry-server.tsx无需在配置中显式声明。这一点在源码 src/build/vite/plugin.ts 中得到印证——插件通过resolveModulePath(./entry-server, ...)来定位服务端入口模块。第二步编写共享的 App 组件创建一个在服务端与客户端同时运行、完全共享的 React 组件 examples/vite-ssr-react/src/app.tsximport { useState } from react; export function App() { const [count, setCount] useState(0); return ( h1 classNameheroNitro Vite React/h1 button onClick{() setCount((c) c 1)}Count is {count}/button / ); }该组件同时被服务端入口用于渲染 HTML与客户端入口用于水合绑定事件引用。注意它使用了useState这类交互式 Hooks服务端渲染时初始状态被序列化进 HTML客户端水合后用户点击按钮即可交互这正是 SSR 与 CSR 共享同一组件树的典型形态。第三步编写服务端入口流式渲染服务端入口 examples/vite-ssr-react/src/entry-server.tsx 是整套方案的核心负责把 React 应用渲染为 HTML 流并作为 Nitro 请求处理器返回import ./styles.css; import { renderToReadableStream } from react-dom/server.edge; import { App } from ./app.tsx; import clientAssets from ./entry-client?assetsclient; import serverAssets from ./entry-server?assetsssr; export default { async fetch(_req: Request) { const assets clientAssets.merge(serverAssets); return new Response( await renderToReadableStream( html langen head meta nameviewport contentwidthdevice-width, initial-scale1.0 / {assets.css.map((attr: any) ( link key{attr.href} relstylesheet {...attr} / ))} {assets.js.map((attr: any) ( link key{attr.href} relmodulepreload {...attr} / ))} script typemodule src{assets.entry} / /head body idapp App / /body /html ), { headers: { Content-Type: text/html;charsetutf-8 } } ); }, };默认导出即请求处理器文件默认导出一个包含async fetch(_req: Request)方法的对象。这是 Nitro 的通用运行时契约任何能响应Request、返回Response的处理器都可以作为 Nitro 服务端入口这意味着同一套 SSR 逻辑既能跑在 Node.js也能直接部署到各类边缘运行时。流式渲染renderToReadableStream从react-dom/server.edge导入的renderToReadableStream会在组件渲染的过程中边渲染边输出 HTML 流而不是等待整棵组件树全部渲染完成才返回。对于首屏依赖异步数据或组件较重的页面这能显著缩短首字节时间TTFB浏览器可以更早开始解析与加载样式脚本。选择server.edge入口也保证了渲染代码对边缘环境的兼容性。资源自动管理?assetsclient与?assetsssr服务端入口通过两条特殊的 Vite 查询参数导入资源清单./entry-client?assetsclient收集浏览器端入口产出的 CSS 与 JS 资源./entry-server?assetsssr收集服务端入口自身关联的资源例如这里被import的styles.css。Nitro 会将各入口收集到的资源整理为清单对象clientAssets.merge(serverAssets)把它们合并为一份完整清单。合并后的assets对象提供assets.css样式表标签属性数组可直接展开为link relstylesheet {...attr} /assets.js脚本标签属性数组示例中配合relmodulepreload使用以提前预加载模块assets.entry客户端入口的 URL注入script typemodule src{assets.entry} /以启动浏览器端代码。从源码角度看这套?assets导入机制由 Nitro 集成的hiogawa/vite-plugin-fullstack插件提供见 src/build/vite/plugin.ts 的导入与 第 56 行 的按需启用逻辑并且可通过 Nitro 配置中experimental.vite.assetsImport选项开关见 src/build/vite/types.ts。样式导入import ./styles.css位于服务端入口顶部配合?assetsssr导入使得该 CSS 能被收集并渲染进 HTML 的head。示例样式 examples/vite-ssr-react/src/styles.css.hero { color: orange; } button { background-color: lightskyblue; }第四步编写客户端入口水合客户端入口 examples/vite-ssr-react/src/entry-client.tsx 负责在浏览器端接管服务端渲染好的 DOMimport vitejs/plugin-react/preamble; import { hydrateRoot } from react-dom/client; import { App } from ./app.tsx; hydrateRoot(document.querySelector(#app)!, App /);两行关键代码import vitejs/plugin-react/preamble这是vitejs/plugin-react提供的前置模块用于在开发模式下初始化 React Fast Refresh模块热替换时保留组件状态。它是该插件的约定要求不可省略。hydrateRoot(document.querySelector(#app)!, App /)React 19 的水合 API。它把 React 事件系统挂载到服务端已渲染出的 DOM 之上而不会重新渲染或替换已有节点从而保留服务端输出的 HTML 与首屏内容。挂载目标#app与 服务端模板 中body idapp的 id 一一对应。从开发到生产运行方式参照 examples/vite-ssr-react/package.json 中的脚本# 开发模式启动 Vite 开发服务器内置 Nitro 运行时支持 HMR 与 Fast Refresh pnpm dev # 生产构建Vite 构建客户端与服务端产物Nitro 组装最终可部署输出 pnpm build # 预览本地运行生产构建产物 pnpm preview开发模式下Nitro 插件把 Nitro 的开发服务器与 Vite 的开发服务器整合在一起Vite 负责模块转换与热更新Nitro 负责路由与运行时 API二者协同后浏览器访问即可看到实时更新的 SSR 页面。原理解读Nitro 如何在构建期整合 Vite结合源码可以进一步理解示例背后的机制服务端入口定位Nitro Vite 插件在配置阶段通过resolveModulePath(./entry-server, ...)自动解析 SSR 入口src/build/vite/plugin.ts因此示例只需要约定文件命名无需在配置里重复声明双环境构建插件基于 Vite 的environments模型管理 client 与 SSR 两套构建并为输出资源指定带哈希的目录与文件名见 src/build/vite/plugin.ts 中assetsDir相关的entryFileNames/assetFileNames规则保证生产资源可长期缓存?assets清单机制由插件内部集成的assetsPlugin提供src/build/vite/plugin.ts并在 Nitro 配置中通过experimental.vite.assetsImport控制启停src/build/vite/types.ts部署灵活性由于服务端入口采用通用的fetch(Request) Response契约构建产物可以平移到 Nitro 支持的各种预设Node、边缘运行时等部署详见 docs/2.deploy 下的运行时与平台指南。扩展阅读本示例只是 Nitro SSR 体系中的一环Nitro 还为其他前端框架提供了同等模式的 SSR 示例Preactexamples/vite-ssr-preact、Solidexamples/vite-ssr-solid、Vue Routerexamples/vite-ssr-vue-router等均遵循“Vite 双环境构建 Nitro 运行时装配”的同一范式。更进一步可结合 Nitro 官方文档深入Renderer渲染器指南了解渲染器renderer的配置方式与 Nitro 管理 HTML 输出的机制Server Entry服务端入口指南掌握服务端入口的编写规范、与路由和中间件的协作方式完整的 示例索引 与 Vite 集成说明获取更多组合玩法。【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考