@react-router/serve

React Router 应用服务器

React Router 旨在让您拥有自己的服务器,但如果您不想设置服务器,可以改用 React Router 应用服务器。它是一个生产就绪但基础的 Node.js 服务器,使用 Express 构建。

根据设计,我们不提供自定义 React Router 应用服务器的选项,因为如果您需要自定义底层的 express 服务器,我们希望您完全管理服务器,而不是创建一个抽象来处理您可能需要的所有可能的自定义。如果您发现需要自定义它,可以迁移到 @react-router/express 适配器

您可以在 packages/react-router-serve/cli.ts 中看到底层的 express 服务器配置。默认情况下,它使用以下 Express 中间件(请参阅其文档以了解默认行为)

HOST 环境变量

您可以通过 process.env.HOST 配置您的 Express 应用的主机名,该值将在启动服务器时传递给内部的 app.listen 方法。

HOST=127.0.0.1 npx react-router-serve build/index.js
react-router-serve <server-build-path>
# e.g.
react-router-serve build/index.js

PORT 环境变量

您可以使用环境变量更改服务器的端口。

PORT=4000 npx react-router-serve build/index.js

开发环境

根据 process.env.NODE_ENV 的不同,服务器将以开发模式或生产模式启动。

server-build-path 需要指向在 react-router.config.ts 中定义的 serverBuildPath

因为只有构建产物(build/, public/build/)需要部署到生产环境,所以不保证 react-router.config.ts 在生产环境中可用,因此您需要使用此选项告诉 React Router 您的服务器构建在哪里。

在开发环境中,react-router-serve 会通过清除每个请求的 require 缓存来确保运行最新的代码。这对您的代码有一些您可能需要注意的影响:

  • 模块作用域中的任何值都将被“重置”

    // this will be reset for every request because the module cache was
    // cleared and this will be required brand new
    const cache = new Map();
    
    export async function loader({ params }) {
      if (cache.has(params.foo)) {
        return cache.get(params.foo);
      }
    
      const record = await fakeDb.stuff.find(params.foo);
      cache.set(params.foo, record);
      return record;
    }
    
    If you need a workaround for preserving cache in development, you can set up a [singleton][singleton] in your server.
    
    
  • 任何模块副作用将保持不变!这可能会导致问题,但无论如何都应该避免。

    // this starts running the moment the module is imported
    setInterval(() => {
      console.log(Date.now());
    }, 1000);
    
    export async function loader() {
      // ...
    }
    

    如果您需要以具有这些类型的模块副作用的方式编写代码,您应该设置自己的 @react-router/express 服务器,并在开发中使用像 pm2-devnodemon 这样的工具来在文件更改时重启服务器。

在生产环境中,这种情况不会发生。服务器启动,然后就结束了。

文档和示例 CC 4.0
编辑