符合习惯用法的 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
文件,它导入并使用了这些适配器之一。
每个适配器都有相同的 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 应用服务器 启动了一个应用,但发现您希望控制 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
脚本
更新 dev
和 start
脚本以使用您的新 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 的适配器的实用工具。
React Router 官方支持在任何给定时间点的活跃和维护中的 Node LTS 版本。对已终止支持的 Node 版本的支持将在 React Router 的一个次要版本中移除。