MUI-v5のスタイルエンジンについて
mui-v5をNext.jsで使おうと思ってエラーが出たので調べてみました。
結果
mui-v5には2つのスタイルエンジンが採用されている
- @mui/styled-engine・・・emotionをwrapしたもの
- @mui/styled-engine-sc・・・styled-componentsをwrapしたもの
(そもそもエラーというよりは、自分が雰囲気でライブラリを使ったり開発してるから起きたことであって、mui-v5のinstallationをちゃんと読めばエラーは起きないと思われます。)
styled-componentsを使おうと思い下記をinstallしました。
yarn add @mui/material @mui/styled-engine-sc styled-components
するとこんなエラーが。
Import trace for requested module:
../../node_modules/@mui/styled-engine/GlobalStyles/index.js
../../node_modules/@mui/styled-engine/index.js
../../node_modules/@mui/system/esm/index.js
../../node_modules/@mui/material/styles/index.js
../../node_modules/@mui/material/index.js
./src/pages/_app.tsx
https://nextjs.org/docs/messages/module-not-found
wait - compiling...
error - ../../node_modules/@mui/styled-engine/GlobalStyles/GlobalStyles.js:3:0
Module not found: Can't resolve '@emotion/react'
どうやら_app.tsxでエラーが起きてるらしい。
なので、node_modulesを遡ってみると確かにnode_modules/@mui/styled-engine/GlobalStyles/index.jsで**@emotion/react**をimportしていました。
mui-v4ではこんなエラーは出なかったので不思議に思いdocument読みました。
MUIのstyled-engineでは
ページ上部の結論と一緒のことを書くのですが、mui-v5には2つのスタイルエンジンが採用されています。
- @mui/styled-engine・・・emotionをwrapしたもの
- @mui/styled-engine-sc・・・styled-componentsをwrapしたもの
スタイルソリューションが見直された経緯はRFCにあります。
簡単に言うと、JSSの動的にスタイルを変更するパフォーマンスが悪かったり、ReactコミュニティがJSSを大規模に使うことに賛成していなかったりするため見直したとのことです。
その中で14.3kb以下だと嬉しいよねとか、パフォーマンスは良いに越したことはないけどDXとトレードオフになるなら多少の性能差は仕方ないねとか、スタイルソリューションを変更するにあたって何を必須とするのかがまとめられていました。
そこで候補となったのが以下のライブラリです。
- styled-components
- emotion
- JSS (currently wrapped in material-ui)
- styletron
- Aphrodite
- fela
このライブラリの中から何を使うかというのを決めていくのですが、ライブラリを選定する目線も勉強になりました。
もちろんPerformanceだったりnpmのダウンロード数だったりもあるのですが、Userが何を使っているのかという基準も設けていました。
あとはSSRに対応してるのか等。
そして、選定後styled-componentsとemotionが残ったのですが公式としては、複数のエンジンに対応することになったとしても、ドキュメントではどちらか一方のデモは用意する必要があるよねと。
結果的にemotonが採用されたのですが、採用理由は以下。
- styled-componentsからの移行コストが小さいこと
これはemotionとstyled-componentsのドキュメント見てもらうと分かるのですが、記述方法にあまり違いがありません。
- emotionはcxが使用できるのでオーバーライドする際に、ラッパーコンポーネントを作成したくない場合有効
- emotionでは複数のクラスを使ってスタイルを定義するのではなく、一つのクラスにCSSをまとめることを推奨している。また、emotionではスタイルが一つにまとめられるため、muiで定義されたスタイルの順序の問題が解決される。
とのことでした。
エラーが出た背景
もちろん@emotion/reactをinstallしていなかったという理由なのですが、そもそもmuiのシステムを理解していなかったり「styled-componentsが使いたいのになぜemotionがいるんだ?」と思ってinstallationを飛ばしたことが原因です。
今は、@mui/styled-engine-scとstyled-componentsはremoveして@mui/styled-engineで開発していくようにしたので解決はしています。
まとめ
document読むって大事だなと思いました。
また可能であればissueを読んで背景を含め理解すると自分の知見が増えるんだろうなと感じました。
でも、support concurrent modeというのがいまいち理解できなかった。。。
分かる方がいればご教授いただけると嬉しいです。