MUI v4 のプロジェクトを段階的に v5 に上げてみる

MUI v5 のMigration from v4 to v5ページのキャプチャ

こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

今回は、あるプロジェクトで MUI (Material-UI) v4 から段階的に v5 に移行していく機会があったので、その際に気をつけたことについてまとめます。

https://mui.com/material-ui/guides/migration-v4/

また、v4 => v5 のアップデートに関しては公式で方法等のアナウンスがなされていますのでそちらもご覧ください。この記事ではより実際的なハマりポイントをご紹介できたらと思います。

MUI v4 => v5 の違い

MUI v4 から v5 にメジャーアップデートされた際に様々な変更が加えられましたが、移行する観点で意識しておくべき変更は以下の通りです。

  • ライブラリ名が変更されている
  • スタイルシステムが変更されている

ライブラリ名が変更されている

移行に取り掛かる際に遭遇する最初にして最大の変更点として、MUI v5 ではライブラリ名自体が @material-ui/* から @mui/* に変更されています。

そのため、別ライブラリとして新たに npm install し、 import を書き換える必要があります。

これはかなり大規模な変更ですが、これにより v4 と v5 を同居させて1ファイル単位で段階的に v5 にアップデートさせていくことも可能です。

v4 のコンポーネントが意図せず壊れているようなことも現状では起こっていないため、これはありがたい措置です。

スタイルシステムが変更されている

v5 では大々的にスタイルシステムが変更され、 makeStyles と withStyles が非推奨になりました。

内部的にもJSSを採用していたのを v5 では emotion が採用されています。

今回移行しているプロジェクトでは makeStyles をメインのスタイルシステムとして使っていました。これは MUI v5 で非推奨にはなりましたが、 import を @mui/styles に変更することで変わらず使えます。(非推奨のため、置換していく必要はあります)

しかし特定の状況で発生する、ただ import を書き換えるだけでは対応できないハマリポイントがあるので気をつける必要があります。

Storybook v6.3.7 でコンポーネントのスタイルの当たり方がおかしくなる

Storybook v6.3.7 を使用している場合、 Storybook 上でコンポーネントのスタイルの当たり方がおかしくなるという問題が発生します。

これを解消するには、.storybook/main.js に以下の記述を追加します。

module.exports = {
  features: {
    emotionAlias: false,
  },
};

この問題については公式から解決策がアナウンスされています。

Now that the web is moving to Emotion 11 for styling, popular libraries like MUI5 and ChakraUI are breaking with Storybook 6.3 which only supports emotion@10.
Unfortunately we’re unable to upgrade Storybook to Emotion 11 without a semver major release, and we’re not ready for that. So, as a workaround, we’ve created a feature flag which opts-out of the previous behavior of pinning the Emotion version to v10.

https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#emotion11-quasi-compatibility

Storybook の現バージョンでは Emotion 11 に対応していないために発生する問題のようです。

createTheme の styleOverrides で font-face を配列で渡すと最後の要素だけ適用される

createTheme についてはこちらの記事の createMuiTheme を使用する方法 もご覧ください。

今回のプロジェクトではベースのスタイルを createTheme で当てていました。

createTheme に渡せる styleOverrides に、以下のように font-face を配列で渡していると最後の要素だけ適用されるという問題が発生します。

const theme = useMemo(
() =>
    createTheme({
    typography: {
        fontFamily: "inherit",
    },
    components: {
        MuiCssBaseline: {
        styleOverrides: {
            "@font-face": [NotoSansJP400, NotoSansJP700],
            body: {
...

これを解消するには以下のようにフォールバックを用意します。

const theme = useMemo(
() =>
    createTheme({
    typography: {
        fontFamily: "inherit",
    },
    components: {
        MuiCssBaseline: {
        styleOverrides: {
            "@font-face": [NotoSansJP400],
            fallbacks: [
            {
                "@font-face": [NotoSansJP700],
            },
            ],
            body: {

おわりに

今回は MUI v4 のプロジェクトを段階的に v5 に上げた際に気をつけるポイントについてまとめました。

まだ移行作業中のため、今後もハマりポイントに遭遇する可能性はありそうです。都度、知見として共有できたらと思っています。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Ishigaki Shotaro

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。