見出し画像

RemixでMUIを使う

MUIのドキュメントの通りにRemix上で使おうとするとサーバービルドでエラーとなります。その対処案の一つのメモです。


エラー

MUIのコンポーネントを導入してみると、npm run dev(もしくはbuild)を実行で以下のようなエラーとなります。

11:41:02 [vite] Internal server error: Cannot use import statement outside a module
      at wrapSafe (node:internal/modules/cjs/loader:1378:20)
      at Module._compile (node:internal/modules/cjs/loader:1428:41)
      at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
      at Module.load (node:internal/modules/cjs/loader:1288:32)
      at Module._load (node:internal/modules/cjs/loader:1104:12)
      at cjsLoader (node:internal/modules/esm/translators:346:17)
      at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:286:7)
      at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
      at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
      at async nodeImport (file:///path/to/project/node_modules/vite/dist/node/chunks/dep-CDnG8rE7.js:52999:15)

「Remix MUI」などで検索すると、対処方法が見つかります。
他ではあまり見かけなかった方法をメモしておきます。

環境

2024.9.26時点で試したバージョンです。

  • Node: 20.17.0

  • Remix: 2.12.1

  • MUI: 6.1.1

以下でセットアップした状態です。

% npx create-remix@latest
% npm i @mui/material @mui/icons-material @emotion/react @emotion/styled

対処方法

2段階の対処を行います。

  • クライアントのレンダリング時にコンポーネントが読み込まれるようにする

  • サーバービルドにMUIコンポーネントを含めないようにする

クライアントのレンダリング時にコンポーネントが読み込まれるようにする

app/root.tsx で useEffect を使い、クライアントのレンダリング時にコンポーネントが読み込まれるようにします。

export default function App() {
  const [outlet, setOutlet] = useState<ReactElement | null>(null);
  useEffect(() => {
    setOutlet(<Outlet />);
  }, []);
  return outlet;
}

サーバービルドにMUIコンポーネントを含めないようにする

Remixのドキュメントにあるように *.client.tsx のファイルを作成します。viteを使っている場合は .client ディレクトリも使えるようです。

app/routes/components/buttons.client.tsx にMUIコンポーネントを記述します。

import DownloadIcon from "@mui/icons-material/Download";

export { DownloadIcon };

app/routes/_index.tsx で buttons.client.tsx を読み込みます。

import { DownloadIcon } from "./components/buttons.client";

export default function Index() {
  return (
    <div className="flex h-screen items-center justify-center">
      <DownloadIcon />
      TEST
    </div>
  );
}

以上で、エラーとならずにMUIコンポーネントが使えました。

MUI Icon


いいなと思ったら応援しよう!