Slide 1

Slide 1 text

新規事業で Remixを採用した 理由と対策 Frontend Up! 〜放課後 LT大会! / Ryo Iinuma メディカル事業本部 ウェルビーイング事業部 DXソリューション部 ソリューション開発グループ グループリーダー

Slide 2

Slide 2 text

自己紹介 Ryo Iinuma / @mizuki_r - DeNA from 2022 - Engineering Manager from 2018 - Web Engineer from 2011 - Perl, PHP, Node, MySQL - Remix, Next, Nuxt(2), AngularJS - DeNA TechCon 2023 Track C

Slide 3

Slide 3 text

今日話すこと ● 新規事業でRemixを採用してみた(3年前〜現在) ○ 背景 ○ 決定に至った理由 ● 実際に3年使ってみて ○ 良かった点 ○ 課題になった点 ● やってきた工夫・改善 ● ライブラリ・フレームワークとの付き合い方 ● まとめ

Slide 4

Slide 4 text

新規事業で Remixを採用してみた

Slide 5

Slide 5 text

背景:技術選定に至るまで ● 当時の私 ○ PHPer のフルスタック ○ Nuxt v2でBFFを組んでいた ● 当時の事業 ○ 健診に対する理解を深めたい ○ 1ヶ月くらいFigma上で議論をしているがなかなか結論がでない ○ サクッと動くものを作りたい ● 当時のチーム ○ フロントエンド専属は自分のみ ○ 新卒・インターン、業務委託の参加はあり ○ React経験者は少なめ

Slide 6

Slide 6 text

背景:技術選定を始めてから ● 当時のフロントエンド情勢 ○ Nuxt2 → Nuxt3 Beta ■ 不安定 + 学び直し でうーん ○ Next ■ 戦略・構造の熟考が必要。 MVPで使うには重い ■ Reactに理解が深いメンバーばかりではない ● 求めていたこと ○ フロントエンド専属人員でなくても書ける ○ 書き始め→動かす速度までの時間が短い ○ JSをなるべく書かない

Slide 7

Slide 7 text

決定に至った理由 ● まず公式サイトとチュートリアルを読んだ ○ 名前はX等で見たことはあるが、当時は言及がかなり少なかった ● Loader, Action, Form周りを実装して決意 ○ 説明が理想的すぎて「ほんまか?」とは思った ○ 疑ったので実際に触り、なんとなく仕組みを理解した ○ 「これです。これで行きましょう」我、大歓喜 ● 特に反論はなかったけど、驚かれた ○ 当時はほぼ僕一人だったので ... ○ Ne(u)xtじゃないの? ○ 「MVPでダメだったら本実装は Nextにしよう」

Slide 8

Slide 8 text

実際に3年使ってみて

Slide 9

Slide 9 text

良かった点 : Loader ● Loader関数から返したデータを stateとして利用できる ● 通信系の処理を実装しなくて済む ので考えることが減る ● state管理不要

Slide 10

Slide 10 text

良かった点 : Action / Form ● Formコンポーネントと組み合わせる とほぼJS不要になる ● 返り値はstateなので通信のpromise が不要

Slide 11

Slide 11 text

課題になった点 ● loader / action 関数に渡されるのが Requestオブジェクト ○ 様々なパース処理は自前で実装が必要 ○ 肥大化しやすく、処理の見通しが悪化 ● Express等のエコシステムの再利用ができない ○ Remixの前にexpressおけばできた ● Formバリデーションは非サポート(良し悪し) ○ Remix-Validated-Form を使った結果、様々な問題を内包することに ● Promiseで通信しないので、直感的ではない ○ toastとかnotificationみたいな UIの作り方 ● Storybookがサポートされてない ○ context周りの解消が難しかった ○ 2023-24年くらいにサポートされて助かった

Slide 12

Slide 12 text

やってきた工夫・改善

Slide 13

Slide 13 text

expressを前に起き、 AppLoadContextで渡す ● HTTP Handler and Adapters を参考に設定すれば expressを前における ● Expressのエコシステムを利用可能 ○ logger, sessionをAppLoadContext経由でRemixのloader, actionに ○ passport等も利用可能

Slide 14

Slide 14 text

Request/Responseを隠蔽するフレームワークの作成 ● Requestオブジェクトをパースする層が必要だったのでフレームワーク化した ○ QueryStringのパース ○ Bodyのパース ○ エラーハンドリング ○ ミドルウェア ● 社内で使っているものとは別だが、以下のようなものを作成 ○ nakadachi ○ nakadachi-adapter-remix

Slide 15

Slide 15 text

Inversifyを導入し、 BFFの処理から Remixを切り離した ● DIライブラリのInversifyを利用 ○ FWに依存しない構造を作る ○ 機能を変更しやすくする ○ Logger, APIClientなどのカスタ マイズ意図 ● Remixを完全に隠蔽 ○ クラスを実行する関数を、直接 loader, actionに渡す ○ 最悪Remix捨てても動くように

Slide 16

Slide 16 text

UI Componentの責務を分離 ● pages直下以外でuseLoaderDataなどのRemix固有のhooksを使わないこ とを徹底 ○ Remixを剥がすかもしれないので ○ ーーが、 RemixValidatedFormのhookを持っちゃって部分的に破綻 ■ RVFの内部で RemixのContextを参照する ... ● Visual, FeatureでComponentを分離してデザイン的関心を分離 ○ buttonのような link, linkのような buttonをclickableというコンポーネントを用意 することで解消 ○ ーーが、 CSSプロパティ直接渡せる機能によって部分的に破綻 ■ 好きに書き換えられちゃうと、 I/Fを用意する意味がなくなる

Slide 17

Slide 17 text

emotion、突然の死。 1年かけてPandaCSSへ ● React Server Componentの台頭 ○ StyledComponentの思想が廃れ、Zero Runtimeへ ○ emotionめっちゃええやんって思ってたところへ大打撃 ● 若手が勉強会でZeroRuntimeCSS, PandaCSSなどを発表 ○ MVPから本実装に切り替えるタイミングで「やっちゃう?」 ○ ほとんどのComponentがそのまま移管されたので、 emotionも残ってし まっていた ○ が、インターンや新卒たちのお陰で 1年越しにemotionを脱却した

Slide 18

Slide 18 text

話題は尽きない ... ● TurboRepoの運用周り ● Formバリデーション周り ● Zodの運用周り ● PandaCSS周り ● APIClient周り ● Logger周り ● エラー・例外設計周り ● テスト周り ● etc… いっぱい話題があるので、 Frontend Up!を追ってくれれば知れるかも!!

Slide 19

Slide 19 text

まとめ

Slide 20

Slide 20 text

まとめ ● Remix使ってみたけどいい感じだったよ ○ HTTP通信をクライアントで設計しなくていいのがマジで楽 ○ 癖の強いところもあるけど、抽象化して隠蔽してなんとかしたよ ● このフレームワークから離れるときが来るかも ○ ーーという考えを持つことは大事だよ ○ 「突然の死」は、フロントエンド界隈では当たり前に繰り返されてきた ● RR?Remix3? ○ ふふ... ままならない、ね ● 疎結合な構造を目指しましょう ○ 他人の書いたコードに依存しない。する場合は、層を一枚挟む ○ 捨てられるように疎結合にしておく