はじめに
この度、エキサイト株式会社でインターンをしました雨宮です。 本稿では、私のインターンでの経験をまとめます。
TL;DR
自己紹介
早稲田大学3年の雨宮光汰です。私は文系学部に所属しています。大学では CS は学んでおらず経済、経営学を学んでいます。 趣味は、銭湯、筋トレです。退勤後に、筋トレを行うのが日課になっています! プログラミング経験は 8 ヶ月ほどで、個人開発で web アプリは作成したことがあります。開発のアルバイトも以前にしたことがありますが、個人開発に近い形だったので、本格的なチーム開発は初めてになります。
インターン内容
インターンでは、SaaS 事業部の「KUROTEN」というサービスの React を用いたフロントエンド開発を担当しました。
コンポーネント作成、ページ作成、ルーティング設定などを担当しましたが、本稿ではPannelコンポーネント作成についてまとめます。
Pannel コンポーネントについて
Pannelコンポーネントは、UI の一部として動作する React のコンポーネントです。このコンポーネントは、Card コンポーネント中の特定の情報や内容を強調して表示する機能を持っています。
このコンポーネントの実装には、React、CSS Modules、Vitest、および Storybook といった技術を使用しました。
以下では、これらの技術について学んだことをまとめ、Pannelコンポーネントにおけるそれら適用を説明します。
React
Meta 社製の フロントエンド構築のための JavaScript ライブラリです。
Pannelコンポーネントのコードは以下のようになっています。
import clsx from "clsx"; import { CSSProperties, FC, ReactNode } from "react"; import { Margin, Padding } from "@/styles"; import s from "./Pannel.module.css"; type PannelProps = { children: ReactNode; width?: string; height?: string; } & Margin & Padding; const Pannel: FC<PannelProps> = (props) => { const { children, width, height, ...spacing } = props; const pannelStyle: CSSProperties = { width: width, height: height }; const rootClassName = clsx( s.root, Object.entries(spacing).map(([key, value]) => value && `${key}-${value}`) ); return ( <div className={rootClassName} style={pannelStyle}> {children} </div> ); }; export default Pannel;
type PannelPropsにより、Pannel コンポーネントが受け取ることができる Props の型が明確になります。これにより Pannelコンポーネントを型安全に使用することができます。
type PannelProps = { children: ReactNode; width?: string; height?: string; } & Margin & Padding;
Pannelコンポーネントは下記に示すように children を受け取り、呼び出し先でPannelの中身を定義することができます。
return ( <div className={rootClassName} style={pannelStyle}> {children} </div> );
以下のように使用することができます。
<Pannel> <Flex justify="space-between" align="center"> <div> <Text variant="h4" color="primary"> Input Text Area </Text> </div> <div> <Flex justify="end"> <Button theme="text-base" mr="2"> キャンセル </Button> <Button theme="filled-primary">保存</Button> </Flex> </div> </Flex> </Pannel>
CSS Modules
CSS Modules は、スタイルのスコープが局所的になり、他のコンポーネントやスタイルとの名前の衝突を避けることができるライブラリです。
例えば、Pannelコンポーネントでは、Pannel.module.cssを以下のようにインポートして使用しています。
import s from "./Pannel.module.css";
sとしてインポートしている CSS は以下のようなコードになっています。
.root { align-items: center; justify-content: space-between; min-width: fit-content; padding: 8px 16px; overflow: scroll; background-color: var(--primary-container); border-radius: 4px; }
CSS module を使用していることにより、.rootというクラス名が他のコンポーネントで使用されていても、Pannelコンポーネントが影響を受けることはありません。
また、clsx というライブラリを使用することにより動的にクラス名を生成することも可能になります。動的なクラス名をつけることにより、イベントにより UI を変更することや今回のように clsx と CSS Modules 組み合わせを使用することで、生成されるクラス名はユニークになるため、他のスタイルとの衝突を避けることができ、コンポーネントとして再利用することができます。
const rootClassName = clsx( s.root, Object.entries(spacing).map(([key, value]) => value && `${key}-${value}`) ); //rootClassName には、s.rootと、spacingオブジェクトに基づいて動的に生成されたクラス名が含まれる文字列が格納される。
参考記事
- https://github.com/css-modules/css-modules
- https://developer.hatenastaff.com/entry/2022/09/01/093000
- https://qiita.com/taqm/items/c38855d8158cdd9d5a3e
Storybook
Storybook は、UI コンポーネントを独立して開発・表示するためのツールです。これにより、開発者はアプリケーションのコンテキストから切り離された環境で、コンポーネントをビジュアルに確認しながら開発することができます。 Storybook では各コンポーネントの状態やスタイルを確認することもできるので、コンポーネントの再利用性やデザインとの整合性を逐一確認しながら開発をすることができます。 Pannel コンポーネントの Storybook では、SamplePannel というサンプルのコンポーネントを使用して、Pannel の見た目や挙動を確認することができます。 まず、サンプルとなる SamplePannel コンポーネントを定義しています。
const SamplePannel: FC = () => { // ... (コンポーネントの内容) };
そして、この SamplePannel を使用して、Pannel コンポーネントのストーリーを定義しています。
export default { component: Pannel } as ComponentMeta<typeof Pannel>; export const Index: ComponentStoryObj<typeof Pannel> = { args: { children: <SamplePannel /> } };
参考記事
- https://storybook.js.org/tutorials/intro-to-storybook/react/ja/get-started/
Vitest
Vitest は Vite 環境で動くテスト実行のためのツールです。ReactTestingLibrary と組み合わせて React コンポーネントのテストを効率的に行うことができます。 私は、Jest は勉強したことがあるのですが、Vitest は初めて使いました。ですが、大まかな書き方は変わらなかったため、非常にスムーズに進めることができました。 例えば、Pannel コンポーネントのテストでは、コンポーネントが正しくレンダリングされるか、また、Props を変更したときの挙動が正しいかを確認しています。
it("change default props", () => { const { container } = render( <Pannel width="300px" height="200px"> Test Content </Pannel> ); const pannelElement = container.firstChild; expect(pannelElement).toHaveStyle({ width: "300px", height: "200px" }); expect(screen.getByText("Test Content")).toBeInTheDocument(); });
参考記事
Pannel コンポーネントまとめ
- CSS modules
- CSS をローカルに当てるための仕組み
- Storybook
- ビジュアル、状態を確認しながら開発ができるツール
- vitest
- vite 環境で実行できる高速なテストツール pannel コンポーネントは難しい実装ではありませんが、フロントの重要な技術を多く使っており、実装を通して大きな学びになりました!
インターンで学んだこと
チームでの開発は初めてで不安もありましたが、メンターの方々が git の使い方から基本的なことを丁寧に教えてくれたおかげで、スムーズに取り組むことができました。また、自分が学ぶべき点や勉強すべき内容についてもアドバイスをいただき、これからのスキルアップに役立てられそうです。 インターンシップを通じて得た経験は、私のエンジニアとしてのキャリアにおいて非常に価値のあるものでした。特に以下の二つの点で大きな学びを得ることができました。
・チームビルディングとコミュニケーションの重要性
以前は主に個人開発を行っていたため、チーム開発の重要性やその中でのコミュニケーション技術を深く理解していませんでした。ですが、今回のインターンを通じて、以下のような点を学びました。
- PR のタイミング
- どのタイミングで PR を出すと、チーム全体の作業フローがスムーズになるのかを学びました。
- PR の文言の工夫
- レビュアーが内容を理解しやすく、効率的にフィードバックをしてもらえるような PR の書き方の重要性を学びました。
- コードの可読性
- 他のメンバーが後からコードを読んだときに理解しやすいよう、見やすいコードの書き方や適切なコメントの残し方の重要性を学びました。
・フロントエンド技術の学び
React を中心としたフロントエンドの技術について、より深く学ぶことができました。特に、今回のインターンで使用した Jotai, useSWR,React Hook Form などの React のサードパーティツールについての知識が増えました。これらのツールは、効率的な開発をサポートしてくれるものであり、今後の開発においても大変役立つと感じています。
最後に
1ヶ月間のインターンでは多くの学びがありました。技術面はもちろんのこと、様々な社員の方とお話しさせていただいたことにより、自分のキャリアについて活かせることも多かったです。 ここで学んだことを活かし、強いエンジニアになれるように今後も頑張っていきます!