Phoenix Liveview と Tailwind CSS でデザイナーと協業した Tips とハマりどころ

こんにちは！
この記事は 8/22 に開催される Elixir コミュニティイベント LiveViewJP の LT 記事です！

https://liveviewjp.connpass.com/event/289000/

# 背景
最近開発で LiveView を使ってデザイナーと協業することが増えました。
その際の Tips やハマりどころを紹介します。

## Tips 
### LiveView にはデフォルトで Tailwind CSS がついている
Phoenix LiveView には Tailwind CSS が同梱されています。
Tailwind CSS は最近はやりのユーティリティベースの CSS ライブラリです。
コンポーネントと相性が良く、コンポーネントベースで機能と UI を集約できる LiveView との相性が良いです。
デザイナーさんには Tailwind で開発することを事前にお伝えしておくと Figma とかでも考慮してくれるかもなのでおすすめです。

https://tailwindcss.com/

https://hexdocs.pm/phoenix/asset_management.html#css

### Tailwind CheatSheet は便利
Tailwind のあのクラスってなんだっけ...って思うことありませんか？
そんな場合はこのようにチートシートが用意されているので便利です！
デザイナーさんにもぜひ共有してあげましょう :thumbsup: 

https://tailwindcomponents.com/cheatsheet/

### コンポーネント化できるので、コンポーネント化前提でデザイナーさんに依頼すると良い
Phoenix は Phoenix.Component などで簡単にコンポーネントを作ることができます。
なのでコンポーネントで共通化することを事前に伝え、HTML やデザインをできるだけ共通化するよう設計すると非常にはかどります！

https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#module-attributes

### Phoenix Storybook でデザインシステムも作れる
Storybook というコンポーネントを管理できるライブラリがあります。React とかでは有名ですね。

https://storybook.js.org/

なんとこれの LiveView 版もあります！これをガッツリ使うことで LiveView でもデザインシステムが作れてしまいます...!

https://github.com/phenixdigital/phoenix_storybook

もし UI チームに Elixir + LiveView を使える人がいたら...夢が広がりますね :thumbsup: 

### heex が HTML そのままでも動作するので HTML ポン置きでも動く
逆にデザインシステムなんかいらないよ～俺は気軽に開発したいんだ、という方にも対応しています。

LiveView は heex という拡張子で UI を記述しますが、これは HTML のスーパーセットになっているので、なんと HTML ポン置きしても動いてしまいます！

デザイナーからもらった HTML をポン置きしてとりあえず動作を見たいんだ、という場合でもお気軽に試すことができます。

### 困ったら Javascript も使える
js hook を用いることで LiveView でも javascript を使うことができます。
LiveView でできるならそちらに統一したほうがいいので、乱用厳禁ですが canvas 使いたいときなどは便利ですね。
デザイナーさんが javascript まで書いてくれる方であれば、それをとりあえず動かしてみることだってできます。

https://hexdocs.pm/phoenix_live_view/js-interop.html

また簡単な動作の場合は JS モジュールを使うこともできます。

https://hexdocs.pm/phoenix_live_view/bindings.html#js-commands

ただし Javascript を使ってしまうと LiveViewTest がしにくくなるという欠点もあります。

その場合はブラウザの動作をエミュレートする hound などのライブラリを使ってみてください！

https://github.com/HashNuke/hound

## ハマりポイント
逆にハマりポイントもいくつかハマったので紹介します。

### Phoenix.LiveView.HTMLFormatter がたまに予期せぬ動作をする
Phoenix 1.7 くらいから HTML のフォーマッタが入りました。
ただ、こいつがくせ者で、たまにインライン要素を改行することで微妙に空白が出てしまいます。

https://zenn.dev/jiin/articles/370909a1c56f5a

ドキュメントを読む限り、インライン要素に無駄な改行が入らないように気を付けてくれてそうですがたまに動作しないので、その場合はフォーマッタの設定を削除することで対応できます。
（頑張ってPR出したい）

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.HTMLFormatter.html#content

### core_component との付き合い方
Phoenix 1.7 から `core_component` というモジュールが `phx.new` した際に生成されるようになりました。
これを用いることで簡単に UI が作れる...！と思いきやこいつがくせ者。

モーダルやフラッシュメッセージなどはそのままでも使いやすいのですが、`input` 要素など他の部品については「コンポーネントにCSSがべた書きされている」ので微妙に使いにくいものになっています。

https://hexdocs.pm/phoenix/components.html#corecomponents

事前にある程度設計できているのであれば core_component ベースで開発開始してもいいかと思うのですが、そうでないのであれば既存のものは破棄して新しく作っていく方がいいのかな...とは思っています。
（他の方の意見も募集ｗ）

### tailwind.config 
デフォルトで生成される tailwind.config は色々とデフォルトでプラグインが入ったりしています。
これで私はハマりましたｗ

デザイナーさんからいただいた HTML を反映したらどうもズレが合っておかしいなぁと思っていたら `require("@tailwindcss/forms")` が記載されていたことで `form` 要素に微妙にスタイルがあたってしまっていたのです。だいぶハマりました :innocent: 

https://github.com/tailwindlabs/tailwindcss-forms

これを避けるにはデザイナーさんが使う `tailwind` のバージョンや `config` を事前に合わせておくことが大事です。

`tailwind.config` はこれ以外にも `extend` 以下に書かないとデフォルトのカラーなどをすべて上書きしてしまうなどいくつかハマりどころがあるので注意です。

https://fuqda.hatenablog.com/entry/2023/05/04/231538

### 文字列展開していると prod 環境で反映されない現象がある
開発環境では問題ないがいざデプロイして確認するとなぜか崩れる...ということがありました。
これは prod 環境では tailwind が不要なスタイルを削除して軽量化することが原因で発生します。

これ自体は非常に便利なのですが、LiveView で文字列結合してスタイルを生成している場合などで、不要なスタイルと判断されて削除されてしまうので要注意です！
`tailwind.config` に `safelist` を記述することで避けることができるのでぜひ覚えておいてください。

https://blog.kumano-te.com/activities/tailwindcss-unresolved-class-on-release

# まとめ
Tailwind や LiveView での UI 開発にはハマりどころもありますが、事前に LiveView + Tailwind の特性を意識してデザイナーさんと協業することで、パワフルなツールを使って **爆速でリッチなUI開発** を進めることができます。

ぜひみなさんもこの魅力を味わってみてください！