Closed16
Kanazawa.js 22/3/26 もくもく会のログ
Material UI v4 -> MUI v5 についてまとめる
2021年9月のアップグレードについての記事。
経緯とかゴール
- v5のゴールはMaterialDeisgnのカスタマイズにかける苦労を軽減して開発体験を上げること。
- 2019年からv5の開発に取り組み、それと同時にv4の開発をストップした。長期的に見て良い面があれば破壊的変更の取り込みも自由に行ってきた。
- ブランドをMaterial UIからMUIに変更した。
- https://mui.com/blog/material-ui-is-now-mui/
- パッケージ名を
@material-ui
から@mui
に変更。
カスタマイズ性の改善
- JSSからemotionに移行
- JSSはCSSの静的な生成についてはemotionより早かったんだけど動的なスタイルの生成が遅くカスタマイズの体験を妨げていた。
- スタイリングソリューション選定のissue
- 同じインターフェイス(
styled()
) で emotion(デフォルト)と styled-componentsを選べる様になっている - emotion に月1000ドルのスポンサーをしている
- emotionに移行してすぐに得られる価値はパフォーマンス。
<Box>
コンポーネントはv4に比べて5倍から10倍高速。
sx
プロパティ
-
styled()
APIは複雑なコンポーネントや再利用性の高いコンポーネントを作るのに優れている。 - 3年前からBoxコンポーネントによる問題解決に取り組んできた
- スタイル定義とあちこち行き来することに時間がかかる問題
- スタイリングコンポーネントのネーミングから開放されたい問題
- 一貫性を保つのがむずい問題。チームならなおさら。
- v5は
sx
プロパティでそのへんを更に進化させた。- たとえば
<Slider sx={{ my: 1 }} />
こんな感じ。
- たとえば
- なお、Box、Stack、Typography、Grid は、sx propのサブセットをフラットpropとして公開している。
- API tradeoff によるとスタイルに関することをsxプロパティに寄せることでコンポーネントPropsと区別するのは「関心の分離」的に重要とのこと。
- そのためBox、Stack、Typography、Grid だけが システムプロパティ を受け付ける。
- これはCSSの問題を解決にするためのCSSユーティリティとして設計されている。
- たとえば
<Typography color="grey.600">
は<Typography sx={{ color: 'grey.600' }}>
と同じ結果がえられる
Dynamic props
- Reactは合成するもの。あるコンポーネントをインポートして拡張してラッパーを再エクスポートできる。
- 新しいコンポーネントを作るとそのたびにインポートするコンポーネントの選択肢が増えて正しいのが使われているか気をつけないといけない
- 新しい色を追加するのに暗黙的なCSSカスタマイズが必要。ホバーとか全ての状態の色が一貫してることを確認する方法は?
- ボイラープレートを用意した
- ひとつめ。既存のスタイルマッピングが使える。新しい名前の中間色をpaletteに追加するとボタンがいい感じで計算してくれる。→ サンプル
- 2つめ。カスタムバリエントをテーマに追加できる。特定のコンポーネントのPropsの組み合わせに対してCSSを上書きできる。→ [サンプル]((https://codesandbox.io/s/sharp-sky-xwz3d?file=/src/App.tsx)
Global class names
- v3ではclassesAPIをただしく使うのがフラストレーションだった。
- v4ではグローバルClass名を追加できるようになったが複数のThemeProviderはこの限りじゃなかった。
- v5ではホストDOMノードにグローバルクラスをつけること複雑なコンポーネントのカスタマイズも簡素な方法で適応できるようになる。 → サンプル
これ以降は別日に追記した内容。
スタイルなしコンポーネント
- React hooks もいい感じになってきたのでMUIとしてもヘッドレスコンポーネントみたいな柔軟性の高いものを出そうとしている。
- MUIを選択するのはUIを高速に組みたいからだけどMUIに依存するというトレードオフもある。
- そのトレードオフがチームのサイズや特性、プロダクトの用途によってはすげーうまくいくけど、最大限に自由度が高いがスクラッチではない手段が提供されるべきじゃないか。
- というわけでこの問題に取り組み始めて、マテリアルデザインのロジックを分離しHooksとUnstyledコンポーネントに詰め込んだよ。
- いまのところ使える機能
- Autocomplete
- Button
- Modal
- Pagination
- Slider
- Switch
- [Unstyledコンポーネントのサンプル]https://codesandbox.io/s/7lc1r?file=/demo.tsx()
- これまでの議論と進捗
開発体験の改善
ドキュメントのデモをより小さなものに
- この移行をデモを作り直したよ。
- 多くのデモはもともとメンテナンス作業者のことを考えて追加されたものだけど、その代わりに開発者の利用を第一にするように優先度を反転した。
- つまり複雑なデモをより小さいものに分解してインラインプレビューをできるかぎりたくさん用意することで、デモを開く1クリックと画面の箇所とコードの対応を把握する心理的な負担を節約できるようにしたよ。
IntelliSenseにPropsの説明を出す
- 開かなくていいドキュメントがあればベストだよね。propの説明をTypeScriptに移動したのでエディタのIntelliSenseで見れるようになったよ。
- TypeScriptのpropの説明文はドキュメントのAPIページを生成するのにも使われていて一つの情報源が正になる。
EnzymeからTestingLibraryに移行
- v4でClassコンポーネントからhooksに移行したけど、エンザイムで書かれたテストの多くは壊れた。
- テストがReact内部に連動しすぎてるのでテストスイーツをTesting Libraryに移行することに決めた。
- ここ2年くらいではTesting LibraryはReactコミュニティでもっとも一般的な選択肢。
- めでたいことに全部のコードベースを移行できたので参考にしてくれていいし、実装を見直すこともできたしコンポーネントが簡単にテストできるようになった。
TypeScriptへの移行
- MUI CoreのTSへの完全な移行はまだ終わっていない。v4では全てのデモでTSファーストで書いたよ。
- v5ではTSを統合するのに新たな手順を計画した。
- APIのページのソースをTS定義にして、新しいリリースのときに古い定義が入り込む可能性を減らした。
- 移行した最初のコンポーネントはTSで書かれたものにした。
- 新しいコードはTSで書いている。
- その結果Githubのステータスで達成率を見ると TSの割合が2019年2月で1.6%だったのが最近だと36%になった。
- この作戦によって2年くらいで終わる気がしている。
(React.)StrictMode に対応
-
React.StrictMode
に互換性のあるリリースです。テストもドキュメントもstrict modeです。 - ボーナスポイントはこれからリリースされるReact 18でstrict modeで動かしてもテストが落ちることはありません。
新しい製品:X
- 新しいMUI Xというプロダクトはここ2年でとったデベロッパーへの調査で報告された主なペインを解消するもの。みんな多くのコンポーネントがほしい。
- 実際には全部のニーズをカバーできるわけないし巨大な仕事だから代わりに最も要望が強くてしんどいコンポーネントに注力してそれ以外のもろもろはコミュニティの人らに任せたい。
- なんで別のリポジトリでやるのかっていうとめちゃくちゃ時間がかかって大変そうだしマネタイズ戦略も違うものが必要。
- MUI CoreとMUI Xは別のビジョン・ミッションを持つけど互いに補完する関係。
- MUI Core :
- ビジョン:UIを構築する堅牢な下地を作る。堅牢はいかに多くの開発者がそれに依存して決定するかで測られる。
- ミッション:デザインスキルを開発者に解放して、高速にUIを作れるようにする。
- MUI X:
- ビジョン:開発者がほしい最終的なコンポーネントライブラリを作る。高品質で一貫性があり高機能で最も頻繁あるいはめんどくさいユースケースを賄う。
- MUI Coreはスポンサーやいろいろな協力によりキャッシュフローがいい感じなのでMITライセンスでうまくいっているが、MUI Xを作るのに必要な作業量には見合っていない。だからオープンコアライセンスモデルを使い3つのプランがある。
- コミュニティ:オープンソースコミュニティのコントリビューターで維持されるMITのコンポーネントを使える。ずっと無料です。
- プロ:オープンソースで維持できない機能が含まれる。たとえばとても網羅的なコンポーネントの種類で、価格的にもプロが使いやすい設計になっている。
- プレミアム:もっとも高度な機能が含まれる。
Data Grid
- Reactの最高峰のデータグリッドを目指してDateGridとDataGridPrpを1年前から提供し始めた。
- 2つのライセンス体系で、DataGridはMITで相対的に簡単に実装できる機能を実現していてオープンソースで維持できている。DataGridProはより高度な機能を提供するために商用ライセンスでで使える。
- デモ
Date Picker
- Dmitriy Kovalenko の
@material-ui/pickers
の所有権を移譲して@mui/lab
の一員になった。 - 一貫性を保つのに苦労したけど他のCoreコンポーネントと同じレベルで到達しようとしてる。コードベースで最初のTSのコンポーネント。
- ほかのDatePickerはMITだけど、日付の範囲選択のやつはProプランになる予定。
新しいコンポーネント
8つの新しいコンポーネントがあるよ。
改善されたGrid
- Gridの開発はJSSの静的生成されるCSSのサイズに阻まれて長いこと保留されていた。
- emotionに移行して次のようなよくある変更の要望に対応した。
- 行と列のスペーシングに対応
-
<Grid container rowSpacing={1} columnSpacing={2} />
-
- すべてのPropsのレスポンシブに対応
-
<Grid container spacing={{ xs: 2, md: 3 }} />
-
- 12より多いカラム数に対応
-
<Grid container columns={16}>
-
- CSS Gridによる別の実装。
Material Design Iconの追加
- Googleのマテリアルデザインチームはv4がリリースされて以降に5つの異なるテーマの中で600の新しいアイコンを公開してきた。それを
@mui/icons-material
使えるようにしました。 - Material Icons
Stack
- 1方向のレイアウトを制御する新しい
<Stack>
コンポーネントを提供した。それはFigmaのAuto Layoutに似てる。 - ※ すでに
<Box display="flex" gap={1}>
でも同じことができるけどブラウザサポートで flexbox gap がSafariで壊れることに気をつけてね。 - 詳しくはドキュメントを見て
labから(Coreへ)昇格したコンポーネント
2年間のフィードバックを回した結果、labの6つをメインパッケージに移動した。
- Autocomplete
- Pagination
- Rating
- Skeleton
- Speed Dial
- Toggle Buttons
labの新しいコンポーネント
- LoadingButton
- TrapFocus
- Masonry
v4からの移行
パッケージ名が変わった
スタイリング方法が変わった
サポートする環境が変わった
デザインキット
次はどうするの?
公開したロードマップ
スタイルなしコンポーネントとHooks
MUI X
デザインキット
だいたい読みたいところは読めたのでいったんこのへんで。emotionについてはまた改めて掘ってみる予定。
このスクラップは2022/03/29にクローズされました