本页内容

服务器适配器

官方适配器

符合习惯用法的 React Router 应用通常可以部署在任何地方,因为 React Router 会将服务器的请求/响应适配到 Web Fetch API。这是通过适配器实现的。我们维护了一些适配器。

  • @react-router/architect
  • @react-router/cloudflare
  • @react-router/express

这些适配器被导入到您的服务器入口,而不会在您的 React Router 应用本身中使用。

如果您使用除内置 React Router 应用服务器 (@react-router/serve) 之外的方式通过 npx create-react-router@latest 初始化了您的应用,您会注意到一个 server/index.js 文件,它导入并使用了这些适配器之一。

如果您正在使用内置的 React Router 应用服务器,您不会与此 API 交互。

每个适配器都有相同的 API。未来我们可能会提供特定于您部署平台的帮助程序。

@react-router/express

参考文档 ↗

这是一个使用 express 的例子。

const {
  createRequestHandler,
} = require("@react-router/express");
const express = require("express");

const app = express();

// needs to handle all verbs (GET, POST, etc.)
app.all(
  "*",
  createRequestHandler({
    // `react-router build` and `react-router dev` output files to a build directory,
    // you need to pass that build to the request handler
    build: require("./build"),

    // Return anything you want here to be available as `context` in your
    // loaders and actions. This is where you can bridge the gap between your
    // server and React Router
    getLoadContext(req, res) {
      return {};
    },
  }),
);

从 React Router 应用服务器迁移

如果您使用 React Router 应用服务器 启动了一个应用,但发现您希望控制 Express 服务器并对其进行自定义,那么从 @react-router/serve 迁移应该相当直接。

您可以参考 Express 模板 作为参考,但以下是您需要进行的主要更改。

1. 更新依赖项

npm uninstall @react-router/serve
npm install @react-router/express compression express morgan cross-env
npm install --save-dev @types/express @types/express-serve-static-core @types/morgan

2. 添加一个服务器

server/app.ts 中创建您的 React Router express 服务器。

import "react-router";
import { createRequestHandler } from "@react-router/express";
import express from "express";

export const app = express();

app.use(
  createRequestHandler({
    build: () =>
      import("virtual:react-router/server-build"),
  }),
);

server.js 复制到您的应用中。这是我们推荐的样板设置,以允许相同的服务器代码运行您应用的开发和生产构建。这里使用了两个独立的文件,以便主要的 Express 服务器代码可以用 TypeScript (server/app.ts) 编写,并由 React Router 编译到您的服务器构建中,然后通过 node server.js 执行。

3. 更新 vite.config.ts 以编译服务器

import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig(({ isSsrBuild }) => ({
  build: {
    rollupOptions: isSsrBuild
      ? { input: "./server/app.ts" }
      : undefined,
  },
  plugins: [reactRouter(), tsconfigPaths()],
}));

4. 更新 package.json 脚本

更新 devstart 脚本以使用您的新 Express 服务器。

{
  // ...
  "scripts": {
    "dev": "cross-env NODE_ENV=development node server.js",
    "start": "node server.js"
    // ...
  }
  // ...
}

@react-router/cloudflare

参考文档 ↗

这是一个使用 Cloudflare 的例子。

import { createRequestHandler } from "react-router";

declare module "react-router" {
  export interface AppLoadContext {
    cloudflare: {
      env: Env;
      ctx: ExecutionContext;
    };
  }
}

const requestHandler = createRequestHandler(
  () => import("virtual:react-router/server-build"),
  import.meta.env.MODE,
);

export default {
  async fetch(request, env, ctx) {
    return requestHandler(request, {
      cloudflare: { env, ctx },
    });
  },
} satisfies ExportedHandler<Env>;

@react-router/node

虽然不像上面那样是直接的“适配器”,但这个包包含了用于处理基于 Node 的适配器的实用工具。

参考文档 ↗

Node 版本支持

React Router 官方支持在任何给定时间点的活跃维护中Node LTS 版本。对已终止支持的 Node 版本的支持将在 React Router 的一个次要版本中移除。

文档和示例 CC 4.0
编辑