Remixアプリサーバー

Remixはサーバーを自分で管理することを想定していますが、サーバーをセットアップしたくない場合は、代わりにRemixアプリサーバーを使用できます。これは、Expressを使用して構築された、本番環境対応のシンプルなNode.jsサーバーです。

設計上、Remixアプリサーバーをカスタマイズするためのオプションは提供していません。基盤となるexpressサーバーをカスタマイズする必要がある場合は、すべての可能なカスタマイズを処理するための抽象化を作成するのではなく、サーバーを完全に自分で管理することをお勧めします。カスタマイズが必要な場合は、代わりに@remix-run/expressアダプターを使用してください。

基盤となるexpressサーバーの設定は、packages/remix-serve/cli.tsで確認できます。デフォルトでは、以下のExpressミドルウェアを使用します(デフォルトの動作については、それぞれのドキュメントを参照してください)。

HOST環境変数

process.env.HOSTでExpressアプリのホスト名を構成でき、その値はサーバー起動時に内部のapp.listenメソッドに渡されます。

HOST=127.0.0.1 npx remix-serve build/index.js
remix-serve <server-build-path>
# 例:
remix-serve build/index.js

PORT環境変数

環境変数を使用してサーバーのポートを変更できます。

PORT=4000 npx remix-serve build/index.js

開発環境

process.env.NODE_ENVに応じて、サーバーは開発モードまたは本番モードで起動します。

server-build-pathは、remix.config.jsで定義されたserverBuildPathを指している必要があります。

本番環境にデプロイする必要があるのはビルドアーティファクト(build/public/build/)のみであるため、remix.config.jsは本番環境で必ずしも使用できるとは限りません。そのため、このオプションを使用してRemixにサーバービルドの場所を指示する必要があります。

開発環境では、remix-serveは、すべてのリクエストごとにrequireキャッシュをパージすることで、最新のコードが実行されるようにします。これにより、コードにいくつかの影響があります。注意が必要な場合があります。

  • モジュールのスコープ内の値は「リセット」されます。

    // モジュールキャッシュがクリアされ、これが新しくrequireされるため、これはリクエストごとにリセットされます。
    const cache = new Map();
     
    export async function loader({
      params,
    }: LoaderFunctionArgs) {
      if (cache.has(params.foo)) {
        return json(cache.get(params.foo));
      }
     
      const record = await fakeDb.stuff.find(params.foo);
      cache.set(params.foo, record);
      return json(record);
    }

    開発環境でキャッシュを保持するための回避策が必要な場合は、サーバーにシングルトンを設定できます。

  • すべてのモジュールの副作用はそのまま残ります!これにより問題が発生する可能性がありますが、とにかく避けるべきです。

    import { json } from "@remix-run/node"; // または cloudflare/deno
     
    // モジュールがインポートされた時点で実行が開始されます。
    setInterval(() => {
      console.log(Date.now());
    }, 1000);
     
    export async function loader() {
      // ...
    }

    このタイプのモジュールの副作用を持つコードを作成する必要がある場合は、独自の@remix-run/expressサーバーと、pm2-devやnodemonなどの開発ツールを設定して、ファイルの変更時にサーバーを再起動する必要があります。

本番環境ではこれは発生しません。サーバーは起動し、それで終わりです。