Future Flags

以下のFuture Flagsは安定しており、採用可能です。Future Flagsの詳細については、開発戦略 を参照してください。

最新のv2.xへのアップデート

まずは、最新のFuture Flagsを入手するために、v2.xの最新マイナーバージョンにアップデートしてください。

👉 最新のv2にアップデート

npm install @remix-run/{dev,react,node,etc.}@2

Vite Plugin

背景

Remixは、独自のクローズドコンパイラ(現在は「Classic Compiler」と呼ばれています)を使用しなくなり、代わりにVite を使用しています。Viteは、JavaScriptプロジェクト向けの強力で、パフォーマンスが高く、拡張可能な開発環境です。Viteのドキュメントを参照 して、パフォーマンス、トラブルシューティングなどの詳細を確認してください。

これはFuture Flagではありませんが、新しい機能と一部のFuture Flagは、Vite Pluginでのみ使用可能であり、Classic Compilerは次のRemixバージョンで削除されます。

👉 Viteをインストール

npm install -D vite

コードの更新

👉 Remixアプリのルートにあるremix.config.jsvite.config.tsに置き換える

vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
 
export default defineConfig({
  plugins: [remix()],
});

サポートされているRemix構成オプションのサブセット は、プラグインに直接渡す必要があります。

vite.config.ts
export default defineConfig({
  plugins: [
    remix({
      ignoredRouteFiles: ["**/*.css"],
    }),
  ],
});

👉 <LiveReload/>を削除し、<Scripts />を保持する

  import {
-   LiveReload,
    Outlet,
    Scripts,
  }
 
  export default function App() {
    return (
      <html>
        <head>
        </head>
        <body>
          <Outlet />
-         <LiveReload />
          <Scripts />
        </body>
      </html>
    )
  }

👉 tsconfig.jsonを更新する

tsconfig.jsontypesフィールドを更新し、skipLibCheckmodulemoduleResolutionがすべて正しく設定されていることを確認します。

tsconfig.json
{
  "compilerOptions": {
    "types": ["@remix-run/node", "vite/client"],
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "Bundler"
  }
}

👉 remix.env.d.tsを更新/削除する

remix.env.d.ts内の以下の型宣言を削除します。

remix.env.d.ts
- /// <reference types="@remix-run/dev" />
- /// <reference types="@remix-run/node" />

remix.env.d.tsが空になったら、削除します。

rm remix.env.d.ts

パスエイリアスの設定

Viteは、デフォルトでパスエイリアスを提供しません。~appディレクトリのエイリアスとして定義するなど、この機能に依存していた場合は、vite-tsconfig-paths プラグインをインストールして、Remixコンパイラの動作に合わせて、tsconfig.jsonのパスエイリアスをViteで自動的に解決することができます。

👉 vite-tsconfig-pathsをインストールする

npm install -D vite-tsconfig-paths

👉 Vite構成にvite-tsconfig-pathsを追加する

vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
 
export default defineConfig({
  plugins: [remix(), tsconfigPaths()],
});

@remix-run/css-bundleを削除する

Viteは、CSS副作用のインポート、PostCSS、CSS Modulesなど、他のCSSバンドル機能に対する組み込みのサポートを提供しています。Remix Vite Pluginは、バンドルされたCSSを自動的に関連するルートにアタッチします。

@remix-run/css-bundle パッケージは、Viteを使用する場合、冗長です。そのcssBundleHrefエクスポートは常にundefinedになります。

👉 @remix-run/css-bundleをアンインストールする

npm uninstall @remix-run/css-bundle

👉 cssBundleHrefへの参照を削除する

app/root.tsx
- import { cssBundleHref } from "@remix-run/css-bundle";
  import type { LinksFunction } from "@remix-run/node"; // or cloudflare/deno
 
  export const links: LinksFunction = () => [
-   ...(cssBundleHref
-     ? [{ rel: "stylesheet", href: cssBundleHref }]
-     : []),
    // ...
  ];

links内で参照されているCSSインポートを修正する

links関数でCSSを参照している場合、対応するCSSインポートをViteの明示的な?urlインポート構文を使用するように更新する必要があります。

👉 linksで使用されているCSSインポートに?urlを追加する

-import styles from "~/styles/dashboard.css";
+import styles from "~/styles/dashboard.css?url";
 
export const links = () => {
  return [
    { rel: "stylesheet", href: styles }
  ];
}

Tailwind CSSまたはVanilla Extractの移行

Tailwind CSSまたはVanilla Extractを使用している場合は、完全な移行ガイド を参照してください。

Remix App Serverからの移行

👉 devbuildstartスクリプトを更新する

package.json
{
  "scripts": {
    "dev": "remix vite:dev",
    "build": "remix vite:build",
    "start": "remix-serve ./build/server/index.js"
  }
}

👉 Vite構成にグローバルなNodeポリフィルをインストールする

vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
+import { installGlobals } from "@remix-run/node";
import { defineConfig } from "vite";
 
+installGlobals();
 
export default defineConfig({
  plugins: [remix()],
});

👉 Vite開発サーバーポートを設定する(オプション)

vite.config.ts
export default defineConfig({
  server: {
    port: 3000,
  },
  plugins: [remix()],
});

カスタムサーバーの移行

カスタムサーバーまたはCloudflare Functionsを移行している場合は、完全な移行ガイド を参照してください。

MDXルートの移行

MDX を使用している場合は、公式のMDX Rollup Plugin を使用する必要があります。ステップバイステップのチュートリアルについては、完全な移行ガイド を参照してください。

v3_fetcherPersist

背景

フェッチャのライフサイクルは、所有者コンポーネントがアンマウントされたときではなく、アイドル状態に戻ったときに基づいています。RFCを参照 して、詳細を確認してください。

👉 フラグを有効にする

remix({
  future: {
    v3_fetcherPersist: true,
  },
});

コードの更新

アプリケーションに影響を与える可能性は低いですが、useFetchersの使用方法を確認する必要があるかもしれません。それらは以前よりも長く保持される可能性があります。何をしているかに応じて、以前よりも長い時間レンダリングされる場合があります。

v3_relativeSplatPath

背景

dashboard/*(単なる*ではなく)のような複数セグメントのスプラットパスに対する、相対パスの一致とリンクを変更します。詳細については、CHANGELOGを参照 してください。

👉 フラグを有効にする

remix({
  future: {
    v3_relativeSplatPath: true,
  },
});

コードの更新

dashboard.$.tsxroute("dashboard/*")のように、パスとスプラットを組み合わせたルートがあり、その下に <Link to="../relative">のような相対リンクがある場合は、コードを更新する必要があります。

👉 ルートを2つに分割する

スプラットルートはすべて、レイアウトルートとスプラットを含む子ルートに分割してください。

 
└── routes
    ├── _index.tsx
+   ├── dashboard.tsx
    └── dashboard.$.tsx
 
// or
routes(defineRoutes) {
  return defineRoutes((route) => {
    route("/", "home/route.tsx", { index: true });
-    route("dashboard/*", "dashboard/route.tsx")
+    route("dashboard", "dashboard/layout.tsx", () => {
+      route("*", "dashboard/route.tsx");
    });
  });
},

👉 相対リンクを更新する

そのルートツリー内の相対リンクを持つ 要素をすべて更新し、同じ場所にリンクし続けるために、..`の相対セグメントを追加します。

// dashboard.$.tsx or dashboard/route.tsx
function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
      <nav>
-        <Link to="">Dashboard Home</Link>
-        <Link to="team">Team</Link>
-        <Link to="projects">Projects</Link>
+        <Link to="../">Dashboard Home</Link>
+        <Link to="../team">Team</Link>
+        <Link to="../projects">Projects</Link>
      </nav>
    </div>
  );
}

v3_throwAbortReason

背景

ローダーが完了する前にユーザーがページから移動するなど、サーバー側のリクエストが中止された場合、Remixはnew Error("query() call aborted...")などのエラーではなく、request.signal.reasonをスローします。

👉 フラグを有効にする

remix({
  future: {
    v3_throwAbortReason: true,
  },
});

コードの更新

以前のエラーメッセージと一致して、他のエラーと区別するカスタムロジックをhandleError内に記述していない限り、コードを調整する必要はありません。

unstable_singleFetch

Single Fetch の動作をオプトインします(フラグが安定したら、詳細が拡張されます)。

unstable_fogOfWar

Fog of War の動作をオプトインします(フラグが安定したら、詳細が拡張されます)。