2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

非デザイナーがUI・UX改善をやってみたら、リファクタの沼にはまった話

Posted at

はじめに

最初はUI・UXの基礎的なノウハウについて書こうと思ったのですが、結局よくあるリファクタリングについての話に着地しました。この記事ではデザインに役立つ内容は含まれておりません。

リファクタ楽しい!ね!!

ことの発端

はじめまして。株式会社StoDのStanakaです。
普段はフルスタックのWebエンジニアとして、自社サービスの開発に携わっています。

自社サービスのGittyが現在絶賛βテスト中でして、ありがたいことにユーザー様からUI・UXに関して貴重なフィードバックをいただいていたので、「そろそろ本腰をいれて改善に勤めなければなー」とチームの皆が思っていました。

現在、われわれの開発チームにはフルタイムのUI・UXエンジニアは所属していないため、Web開発(特にフロントエンド)の経験があり、UI・UXに関する基礎知識がチーム内で最も豊富であろう私に白羽の矢が立ったのが、ことの発端です。

主な技術スタック

  • Next.js
  • Tailwind CSS
  • shadcn/ui

バックエンドではもっと色々使っていますが、このお話でキーとなってくるのは以上の3つなため、他は割愛させていただきます。
バックエンド側の話は同開発チームのandyさんの記事で読めるので、気になる方はぜひどうぞ。

よっしゃー!デザイン直すぞー!...あれ?

エンジニアにデザインを指示すると、何が始めるのか

私はデザイナーというわけでは無いので、Figma等のデザインツールを使うのに慣れていません。
「コード変えた方が早いじゃん!」となってしまうんですね。
そんな個人開発時代からの悪癖(?)が今回も発揮された結果、私は頭で思い描いた修正案を実装すべくコードベースの奥地へと向かいました。

AIが書いたコードとご対面

多くの開発チームと同様、われわれもAIツール(主にCursor)を使用して開発しています。
Cursor Rule等で出力の制御を行わずに使用すると、その時々で異なったコードを出力するため、プロジェクト全体でのコードの一貫性が損なわれるという懸念があります。

この事例で具体的に見受けられた例が以下です:

  • 明らかに複数箇所で使いまわされているクラス名たちがその都度ハードコーディングされていた(重度)
  • デザインのカラーパレットに無い色が使われていた(軽度)

なぜ起こったのか

ハードコーディング(コードが再利用されていない)問題に関して。

AIにコードを書いてもらう前は、このような使いまわされているスタイルはコンポーネント等に分離し、再利用性を高める事を意識的にやってきました。

「コードが動くか」だけではなく、「このコードがどこにあるべきか」までを熟考していたのですが、AIツールの使用に伴ってスピード感が高まった開発現場では「動けばいいや」というメンタリティがより強固なものになっていたと感じます。(このメンタリティにはメリットもありますが、一長一短ということで)

以前は、コードを書くときに「すでに似たもの(関数、コンポーネント)があるなら使い回そう」と思っていたのが、「とりあえず仕様をAIに投げてみよう」となってしまっていたため、既存のコードにあるものを新しく書き直してしまうという問題が発生していました。

デザインのカラーパレットにない色が使われている問題に関しても、コードベースの一貫性を保つルールが指定されていなかったゆえに発生したものです。

解決までの道のり

この事例のリファクタリングは主にフロントエンドのコード(主にJSX)の共通している部分を発見し、コンポーネントとして分離し、再利用するというものです。

アプリ上のUIを見て、同じ見た目の部分は、ちゃんとコンポーネントとして切り出せているかを確認し、出来ていなければ切り出すという作業を繰り返しました。

コンポーネント分離時の法則

私がコンポーネント分離時に設けている個人的な法則があります。

  • 複数のページ・コンポーネントで再利用されるものは、新しいファイルに分離する
  • 一つの親コンポーネント内でのみ再利用されるものは、親コンポーネントのファイル内で新しいコンポーネントに分離する

この法則は、数多のファイルが乱立し、コードベース内で迷子になることを防ぐために設けています。

Cursor Ruleを作ってみたけど、あんまりうまくいかなかった

この法則に基づき、作成したのが以下のCursor Ruleです。

Given a .tsx file, I want you to extract the common elements with common styles or logic into a own component.

Create the new components within the same file, do not create new files unless the user specifies to create them.

Make sure to pass appropriate props to the newly created components.

The aim of this task is mainly to minize code duplication of common styles.

AIエージェントにコンポーネントの分割を頼んだ場合、まず新しくファイルを作成しようとするので、このルール内では基本的に同じファイル内に分離されたコンポーネントを定義するように指定しています。

ただ、このルールを使っても、想定した通りに分離してくれない事がありました。

よく起こったのが以下の挙動です:

リファクタ前:同じスタイルのdivが複数あるので、コンポーネントとして切り出したい

<Parent>
    <div className="p-3 text-primary-500 ...">...</div>
    <div className="p-3 text-primary-500 ...">...</div>
</Parent>

やりたかった事:

function NewComponent(){
    return (
        <div className="p-3 text-primary-500 ...">...</div>
    )
}

...

<Parent>
    <NewComponent/>
    <NewComponent/>
</Parent>

Cursor Ruleを適用したときに起こったこと:

function NewComponent(){
    return (
        <Parent>
            <div className="p-3 text-primary-500 ...">...</div>
            <div className="p-3 text-primary-500 ...">...</div>
        </Parent>
    )
}

...

<NewComponent/>

違う。そうじゃない。

この様な挙動のせいで、結局ほとんど手直しでリファクタすることになりました。

自分の手でリファクタするメリット

「コードベースの理解度が深まる」の一言に尽きます。

どのコードを変更したらどこに影響があるのかを把握できるという状態はAIにコードを書かせるだけでは獲得できず、生成されたコードを読み込む必要があります。
手動でリファクタする場合、共通の要素を発見し分離するために強制的にコードの理解を迫られるので、非常に有意義な作業でした。
refactoring-source-code.jpg

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?