作って捨てるも立派な成果♪ Reactパッケージ化から学んだこと(≧∇≦)

#技術#React#リファクタリング#ゲーム#設計
ねつきのトーク
ねつき
ねつき
作って捨てるも立派な成果♪ Reactパッケージ化から学んだこと(≧∇≦)
ねつき
ねつき

お兄ちゃん〜、スライドパズルをリリースしたよ!(≧∇≦)

お兄ちゃん
お兄ちゃん

おお、ミニゲームコーナーに追加したんだ。

ねつき
ねつき

うん!ねつきの寝顔がパズルになってるの♪

クリアすると起きるんだ(゚∀゚)

3×3と4×4で遊べるよ〜!

お兄ちゃん
お兄ちゃん

かわいいね。作るの大変だった?

ねつき
ねつき

それがね…面白い話があるの♪

実はReactでパッケージ化しようとしたんだ。

130件のテストを書いて、4層アーキテクチャで設計して…

お兄ちゃん
お兄ちゃん

すごいじゃん。

ねつき
ねつき

…で、全部捨てた(>_<)

お兄ちゃん
お兄ちゃん

え?

なぜReactパッケージ化しようとしたの?

ねつき
ねつき

最初の動機はこんな感じだったの♪

  1. テストを書きやすくしたい

    • Alpine.js版はテストが書きにくい

    • Reactなら純粋関数として切り出せる

  2. 将来のOSS化

    • 「好きな画像でスライドパズル」としてnpm公開できる

  3. 関心の分離

    • コンテンツサイト(Astro)とゲーム(React)を分ける :::

ねつき
ねつき

でしょ?

だからpnpm workspaceでモノレポ構成にして、tsupでビルドして、Vitestでテストして…

本気で作ったの(≧∇≦)

何を作ったの?

ねつき
ねつき

4層アーキテクチャで設計したよ♪

  1. SlidePuzzle.tsx - UIコンポーネント

  2. usePuzzleGame.ts - React状態管理

  3. solver.ts - IDA*アルゴリズム

  4. puzzle-logic.ts - 純粋関数

上から順に依存していて、下に行くほど純粋なの(´∀`)

一番下のpuzzle-logic.tsは、Reactに依存しない純粋関数だけで構成されてるよ♪

お兄ちゃん
お兄ちゃん

ちゃんとした設計だね。

ねつき
ねつき

うん!IDA*ソルバーのバグも見つけて修正したし、ヒント機能のタイミング問題も解決したし…

技術的にはすごく勉強になったの♪

なぜ捨てたの?

お兄ちゃん
お兄ちゃん

で、なぜ捨てたの?

ねつき
ねつき

うーん〜、お兄ちゃんと話してて気づいたの。

5年後のメンテナンス性を考えたら、どうなる?(´∪`)

お兄ちゃん
お兄ちゃん

5年後…

ねつき
ねつき

こう比較してみたの♪

Alpine.js版:

  • 依存関係 → CDNから3kb

  • ファイル数 → 1ファイル

  • フレームワーク消滅時 → VanillaJSに移行容易

React版:

  • 依存関係 → React 18 + tsup + Vite

  • ファイル数 → 10+ファイル

  • フレームワーク消滅時 → hooks/JSX全書き直し

お兄ちゃん
お兄ちゃん

Alpine.jsの方がシンプルだね。

ねつき
ねつき

そうなの!

5年後にReact 18が古くなって、hooks APIが変わって…ってなったら、全部書き直しになっちゃう(´;ω;`)

Alpine.jsなら、最悪CDNから読み込むだけで動くの。

お兄ちゃん
お兄ちゃん

依存が少ない方が長生きするか。

ねつき
ねつき

うん!

今カッコいいコードより、5年後も動くコードを選んだの♪

無駄じゃなかった理由

お兄ちゃん
お兄ちゃん

でも、130件のテストとか、無駄になったんじゃない?

ねつき
ねつき

ここが大事なポイント!(≧∇≦)

無駄じゃなかったの♪

お兄ちゃん
お兄ちゃん

どういうこと?

ねつき
ねつき

Reactパッケージ化の過程で、本当に必要な機能が明確になったの!

作り直すときに、1つ1つの機能を精査したでしょ?

そしたら「これ、要らないな」って機能がいっぱい見つかったの(゚∀゚)

お兄ちゃん
お兄ちゃん

例えば?

ねつき
ねつき
  • ヒントシステム → 誰も使わない

  • スコア計算 → ハイスコアを狙う人いない

  • 統計パネル → 本格ゲームじゃないし

  • プレイ履歴 → 同上

React版で「これらを実装するの大変だな〜」って思ったら、そもそも要らない機能だったって気づいたの♪

お兄ちゃん
お兄ちゃん

作ろうとしたから、要らないと分かった。

ねつき
ねつき

そう!

作って捨てるっていうプロセス自体が、機能の棚卸しになったの(≧∇≦)

ねつき
ねつき

React版を作ったからこそ、何が本当に必要かが見えて、結果的に半分以下のコードになったの♪

結果

ねつき
ねつき

React版の知見を、Astro版に逆輸入したよ♪

  • コード行数: 988行 → 433行(-56%

  • 削除した機能: ヒント、スコア、統計、履歴(4機能)

  • 追加した機能: モバイル拡大モード

お兄ちゃん
お兄ちゃん

機能を足したのに、コードは半分以下になったのか。

ねつき
ねつき

うん!

作って捨てたからこそ、本当に必要なものが見えたの♪

遊んでみてね♪

ねつき
ねつき

というわけで、スライドパズルができたよ!

  • 3×3(かんたん)と4×4(むずかしい)

  • スマホ対応(拡大モード)

  • クリアするとねつきが起きる

  • 手数とタイマーで挑戦

シンプルだけど、ちゃんと楽しめるパズルになったと思うの♪(≧∇≦)

ねつき的まとめ

ねつき
ねつき

今日のポイント!

  1. Reactパッケージ化を試みた

    • 130件のテスト、4層アーキテクチャ

    • 技術的には完成度高かった

  2. 5年後を考えて捨てた

    • 依存が少ない方が長生きする

    • Alpine.js版の方がメンテしやすい

  3. 無駄じゃなかった

    • 作り直す過程で「要らない機能」が明確に

    • 知見をAstro版に逆輸入

    • 988行 → 433行の大ダイエット

作って捨てるも、立派な成果だよね♪(≧∇≦)

無駄に見えるプロセスが、実は一番の近道だったりするの(´∀`)

ぜひ遊んでみてね!

お兄ちゃん
お兄ちゃん

遊んでみるよ。

ねつき
ねつき

わぁ〜、ありがとう♪(〃´∪`〃)

クリアしたらねつきが起きるから、見届けてね!

♪ 拍手 ♪
0 拍手