フロントエンドで循環参照を起こさない仕組み化
ハロー、@setoh です。
この記事は株式会社エス・エム・エス Advent Calendar 2025の5日目の記事です。
弊プロジェクトのフロントエンドのコードでの循環参照を解消し、再発しないように仕組み化した取り組みについて書きます。
きっかけ
弊プロジェクトではかなり前から循環参照の解消をするというチケットは切られていたのですが、顕在化した問題はなく、しばらくの間誰も着手しておらずパンドラの箱と化していました。
そんな中、今年6月に「フロントエンドの設計について話す会」というタスクフォースチームが発足しました。
その中で設計以外にも見直した方がよいこととして循環参照問題が上がりました。放置された結果として問題の全体像すら見えておらず、そろそろ目をそらせないタイミングということで調査をすることになりました。
循環参照の見える化
まずは循環参照がどのくらい起こっているのかを知るため、循環参照を検出できるツールを導入しました。
Dependency Cruiser, Madge, import/no-cycleなどを試しましたが、実行時間と検出の精度からDependency Cruiserを使うことにしました。Madgeは検証時点ではbarrel file経由の循環参照を検知できず、import/no-cycleはlintの実行時間が大幅に伸びたため、実質的にDependency Cruiser以外の選択肢はありませんでした。
循環参照の分析
Dependency Cruiserを使って循環参照を検出したところ、当初は150以上の循環参照が検出されました。
軽く白目をむくような数字でしたが、詳細を見ると半数以上はpathpidaというライブラリによる生成ファイルが原因でした。この生成ファイルの循環参照によってbundle sizeが大きくなるなどの問題はなく、pathpidaは乗り換えを検討予定だったこともあり、こちらは一旦無視する方針としました。
他の循環参照についても、幸いにも顕在化している問題はなさそうでした。が、コードベースが大きくなるにつれて問題が起こる可能性も修正コストも大きくなるため、解消に動くことにしました。
後々分かりましたが150以上の循環参照はメインのパッケージだけの数で、依存するサブパッケージを含むと300近い循環参照がありました。
循環参照の修正
前述のpathpidaを除く循環参照を解消していきました。
多くが2つのファイル間の相互参照やbarrel fileによるものだったため、地道に変数や型の定義を整理していきました。
主に自分がメイン業務の片手間で行い、1ヶ月程度で循環参照を解消できました。
循環参照の監視
循環参照が再発しないように監視するCIを作りました。
循環参照は直近では新規に作られることはほぼなかったため、平日の早朝にDependency Cruiserでの循環参照の検出を実行するようにしました。
循環参照を検出すると、循環参照のリストのファイルを作るPRが自動でマージされるようになっており、エンジニアはそれを元に修正をする運用になっています。
監視が始まってから検出された循環参照は恥ずかしながら自分の作った1件のみで、健康的な依存状態が続いています。
循環参照を起こさない実装方針の制定
百個以上の循環参照を解消してある程度パターンが見えたため、循環参照を起こさない実装方針をまとめました。
方針の内容はシンプルで、型を定義するtypes.tsからは実装ファイルを依存しないようにするなど、依存の方向を明確化しただけです。
これを意識するだけでも弊プロジェクトにあった循環参照のほとんどは防げるものでした。
実装方針通りになるようにlintで実装を縛るという方向も考えましたが、弊プロジェクトのエンジニアは自分で循環参照を直せないレベルの人はいないので、毎日の検出で気付いて直せば十分と考えてやめました。
循環参照を起こさない方針として書いていますが、万が一うっかり循環参照を作ってしまった場合にこの方針を元に修正の方針を考えるのに使ってもらうのが正しい用途かもしれません。
最後に
循環参照は弊プロジェクトで長期間放置されていた問題でしたが、分析→修正→再発防止とステップを踏むことで、今後起こりにくい状態まで持っていくことができました。
自分はプロダクトの様々な質を上げることを好んでいますが、今回の取り組みはコードの品質を上げるアクションの1つとして成果を出すことができたと思います。
以上!
近況 ~2025年10月下旬~
ハロー、@setoh です。
近況
急に近況をブログで書く人は休職したり退職したり転職したりするパターンが多いですが、特にそういった予定はないです。
プライベートの時間の多くを家庭に使っているため、完全に筆不精になっていただけです。
社内向けには毎月雑な月報を書いていますが、具体的なタスク内容について書いていることが多いので社内向けとなっています。いい感じのことを書いたり書かなかったりしていますが、一番人気なのは酒についてのコーナーなので複雑な気持ちです。
今年のDroidKaigiはタイミング悪く体調を崩し、最終日だけの参加になりました。懇親会も参加できず挨拶できた人は少なかったので残念でした。
そんな感じで変わったり変わらなかったりしながら生きています。今年のBMIは18くらいだったので相変わらず物理的には細く長く生きています。
SNS離れ
去年子が生まれたあたりからスマホを使う時間を減らしていたので徐々にSNSを見なくなり、最近は旧Twitterは全く見ていません。blueskyとmixi2はたまに見ています。プログラミング関連の情報キャッチアップがしにくくはなりましたが、知らない人が怒っているのが目に入らなくなったので良かったかなと思います。
YUKIの揺れるスカートという曲の「そうやって皆して不平不満ばっかり言って つぶやいてりゃいいじゃない 私には関係ない」という歌詞の世界観に近づけたかなと思います。この曲の発表から14年経っていますが。
Kotlin Fest 2025
月末といえばノハナですが、来月の月初といえば11/1にKotlin Fest 2025が開催されます。
自分が働いている株式会社エス・エム・エスはKotlin Fest 2025のスポンサーをします。
弊社のスポンサーブースでは自分も説明をする予定なので、Kotlin Festに参加する人は是非立ち寄ってもらえればと思います。
自分は相変わらずTypeScriptでフロントエンド開発をしているので、TypeScriptとKotlinについてやReactとJetpack Composeについてなどはお話できると思います。
弊社のKotlin事情については同僚が説明してくれると思います(丸投げ)。
Kotlin Festに参加されない方はまたどこかでお会いしましょう。
以上!
フロントエンド開発のテスト方針でうまくいったこと・うまくいかなかったこと
ハロー、@setoh です。
この記事は株式会社エス・エム・エス Advent Calendar 2024 vol.1の12/6の記事です。担当の日に有休を入れたせいで完全に公開を忘れていました。今日は12/9です。
---
ここ1年はテスト方針を考えて試行錯誤をしたので、いくつか取り上げます。
うまくいったこと: Testing trophyの考えに従う
昨年のAdventCalendarの記事でも取り上げましたが、フロントエンド界隈ではTesting trophyという考えが有名です。
Testing trophyに従い、コンポーネント単位ではなく画面単位でテストを書くようにしました。
更に、下記の記事の Even better betterのような書き方にし、複数の観点をまとめてテストするということも試してみました。
このような書き方にするとユーザーストーリー単位でテストが書けるので、テストを見れば画面の機能がわかるというメリットがあります。
また、テストでrenderを呼び出す回数が少なくて済むため、コンポーネント単位でテストを書くよりも実行時間の総計が少なくなりました。
うまくいかなかったこと1: Testing trophyの考えになんとなく従う
うまくいったことでも取り上げましたが、うまくいかなかったこともありました。うまくいかなかったのは一部のテストが非常に遅くなるという問題です。
機能が多い画面では複雑なDOM構造になります。画面単位でテストを書くため、そのような画面でDOM構造を変えるような機能のテストを書くと恐らくDOM構造の更新に非常に時間がかかってしまうようで、実行時間がかなり延びてしまいました。
こういった場合は画面単位ではなくコンポーネント単位でのテストに切り替えることで、最大で1/10くらいの実行速度になりました。
とはいえテストが遅い場合だけコンポーネント単位のテストにするというのは方針として一貫性に欠けるので、テストで使っているjsdomを他のライブラリに変えて高速化を目指すことなどを検討予定です。
テストの問題を全て解決する銀の弾丸はないので、流行だからと行って採用するのではなく、内容をしっかりと理解して使いどころを考えて行く重要性を再認識しました。
うまくいかなかったこと2: ユーザー操作のテストを厚めに書いてバグの数を0に近づける
Propsで受け取った値をそのまま表示することやサーバーから取ってきた値をシンプルに表示することでは複雑なバグは生まれにくく、またバグがあっても気付きやすく簡単に修正可能です。
複雑なバグが生まれやすいのはロジックやユーザー操作部分であり、その部分をしっかりテストすればバグをかなり減らすことができ、0に近づけていけるのではと考えました。ロジックについては当然テストを書いているので、ユーザー操作のテストを厚めにする方針を立てました。
結果としてはうまくいかず、バグはそれなりに存在しました。
理由としてはバグが出るのは複雑な操作やエッジケースが多く(モーダルを2回開くと前回の値が残ってしまう、キャンセル後に再実行すると動作不正になる、etc…)、全機能でこれらのテストを書くとコストに見合うかが怪しくテストの実行時間の問題が起こりそうだという印象でした。
とはいえテストを書いた部分についてのバグについては検知できるので、ロジックとユーザー操作にテストを書くという方針は間違ってはいなかったかなと思っています。バグが0に近づくであろうというもくろみが過剰でした。バグを0に近づけるならば仕様からアプローチしないと難しいですね。
来年もテスト方針について試行錯誤していきたいと思います。
以上!
---
株式会社エス・エム・エスではソフトウェアエンジニアを募集しています。
自分と一緒にフロントエンドの開発をしたり、フロントエンドのテストの方針を考えませんか?
採用情報はこちら!
8月の振り返り
ハロー、@setoh です。
今月も振り返ります。
仕事
今月も働きました。
先月よりも働く時間が伸びたので色んなタスクに手を出したりしていました。
開発チームのスクラムイベントのファシリテーションを担当することになり、新しい刺激を受けています。
ファシリテーション能力と他人を巻き込む能力はブランクがあるとどんどん落ちていくと思っているので(だいたい能力はやらないと落ちますが)、リハビリしつつやっていきたいと思います。
有休
今月は2日取りました。
仕事に打ち込みがちだったので有休でリラックスできてよかったです。
育休中は平日に出かけることが多かったので土日の人の多さに耐えられなくなりつつあり、有休でガッと用事を済ますことが増えました。土曜に働いて平日に休みたいです。
スマホの利用時間
2月のブログでスクリーンタイム制限をかけた話をかけましたが、最近は制限時間を越えて触ることが当たり前になりました。良くないですね。
ちょうど調べないといけないことが多いタイミングということもあり、調べごとをしてその後にダラダラスマホを触るというパターンが多かったように思います。
スマホ触る時間を減らして読書しなきゃなと思っているので、今月は本を多めに買いました。積まずに読もうと思います。
以上!
7月の振り返り
今月もブログを書きます。
仕事復帰
育休から復帰しました。
育休中はMAXでも1日4時間くらいしか集中時間を取れなかったんですが、割と普通に毎日働けてます。訓練された社会人だなと気付いてしまって悲しいです。
仕事はぼちぼち大変ですが、それ以上に寝不足の方が大変なので仕事の本来の大変さを認識せずに済んでいます。
給与
育休前以来、半年ぶりに給与が振り込まれました。最高です。一番好きな与です。
景気づけにすき焼きにしましたが、翌日かなり胃もたれしました。辛いです。
運転
学生の夏休み期間に入るので飛び出しなどに気をつけて運転しないとと思っていましたが、暑すぎて外出している学生をあまり見ないです。良かったと思いつつ車が暑いのでむしろマイナスくらい。
今月読んだ本
なんと0冊です。
色々やりすぎて1冊読みかけなだけです。
来月は夏休みもあるし読書時間を増やします。
平日に色々していたのが仕事に置き換わったのであまり書くことないですね。
以上!
6月の振り返り
ハロー、 @seto_hi です。または@setoh です。
育休5ヶ月目も終わりなので今月も振り返ります。来月から復職します。働きたくないです。
やったこと
細々と家の環境を整えていたら6月が終わっていました。
車の運転
ペーパードライバーでしたが、必要性を感じたので練習して運転できるようになりました。
歯医者の通院
不規則な生活で歯を磨き忘れることが増えた結果、虫歯になりました。厳しいです。
プログラミング
Androidアプリの開発を少しだけやりました。完全に忘れたと思ってましたが、Android Studioのショートカットを指が覚えていたのでリハビリしたらAndroidエンジニアに戻れそうです。知らんけど。
人に会う
元同僚に会いました。みんなそれぞれ頑張っていて刺激をもらいました。
読んだ本
今月は他のことをやっていたので、1冊だけ読んで2冊読みかけです。
数学入門
小難しいことを勉強したくなったので読みました。期待に反してスルスル読めました(スルスル読めてしまっていい本なのかは不明)。
遠山 啓さんの数学入門とどちらを読むか迷ったのですが、こちらの本は遠山さんの本のアップデートとして書かれたようなので、こちらで良かったのかな。
育休は今月で終わりですが、ブログの更新は毎月続けていけたらいいですね。
以上!
5月の振り返り
ハロー、 @seto_hi です。または@setoh です。
育休4ヶ月目も終わりなので今月も振り返ります。もう少し育休は続きます。
やったこと
外出
いい気候なので。
子連れだと親切にしてもらうことがあり、本当にありがたかったので自分も親切を返していきたいと思いました。
集中タイム
育休に入ってからがっつり時間を取って集中することがなく、業務に復帰した際にキツそうだったので、子を妻に任せて仕事部屋に籠もる時間を作るようにしました。
今月は平日毎日やろうと思ってたんですが、実際は3回くらいしかできませんでした。集中タイムをやろうと思うと子が大泣きしたりして、仕事に復帰した際にはこういう感じなんだろうなと察しました。この記事を書いている今も子が荒ぶる声が聞こえます。
プログラミング
育休に入る前以来、4ヶ月ぶりにプログラミングしました。
ON AIRのサインランプを仕事部屋の入り口に飾っているので、Switchbotのコンセントに繋いで、Googleカレンダーの予定と連動して点灯/消灯できるようにしました。簡単な実装なので使い慣れているGASで作りましたが、触ったことない構成とかでそのうち作り直そうかと思っています。そのうち...
来月はComposeでなんかAndroidアプリ作ろうと思ってます。
読んだ本
はじめてのUXリサーチ
昔UXリサーチについていくつか本を読んだけど、実践しないまま忘れたので再度学ぼうと思って読んだ本。サクッと読めました。実践しないと。
カント入門(ちくま新書)
論理的な思考について学ぶならカントは避けられないなと思ったので読んだ本。
難しいですね。難しいです。
多少癖はありつつも、この本はかなりわかりやすく書かれていると思います。
入門 公共経済学
育休中は育児休業給付金で生きているので、こういったことがどう決まるのかが気になって読んだ本。
当たり前だけどちゃんと考えられて政策はやられているんだなと。課題と解決法と評価があるのでプロダクトの施策とだいたい一緒ですね。
プロダクトマネジメントのすべて
昔もらったけど、分厚さの圧に負けてなかなか読めてなかった本。
PdMでないメンバーでも、この本を読んでおけば良いプロダクトを作るのに役に立つはず。
この本も実践しないと身につかない部分が多いと思うので、個人プロダクトでも作りたいなという気持ちに。
6月はコードを書く時間を増やしてリハビリしたいと思います。
以上!