Mirrativ Tech Blog

株式会社ミラティブの開発者(バックエンド,iOS,Android,Unity,機械学習,インフラ, etc.)によるブログです

4ヶ月間のフロントエンドインターンで得られた学び

はじめまして!フロントエンドエンジニアのエンドー(@onikumaruBuu)です!

私は大学3年生で、普段は大学の友人と「学食モバイルオーダーアプリ」の開発をしています。フロントエンドに興味があり、React / TypeScriptを勉強中です!

8月中旬からインターンとしてミラティブに入社し、フロントエンド開発業務を行ってきました。

本記事ではフロントエンドとしてのミラティブでのインターンで身につけた知見を共有します。

目次

ミラティブでのフロントエンド開発

私は本インターンにて、ライブ配信プラットフォーム『Mirrativ』のフロントエンド開発に携わりました。Mirrativではゲーム企業様と連携したイベントなど様々なイベントが毎月行われています。各々のイベントのために小さなWebアプリを用意しますが、これをイベントLP(ランディングページ)と呼んでいます。イベントLPのほとんどはReact / TypeScriptのSPAで実装されておりサーバから渡ってきたオブジェクトによって描画する内容を切り替える仕組みになっています。つまり、アクセスしたユーザーや時期によってUIが複雑に変化します。その他、Mirrativのフロントエンドに関する詳しい情報はこちらの記事をご覧ください。

tech.mirrativ.stream

担当したフロントエンドの仕事

イベントLPのTailwind CSSへリプレイス

私はイベントLPのSCSSをTailwind CSSに置き換える&ESLintに対応した書き方に変更するタスクを担当しました。このタスクは当初1ヶ月ほどで終わる想定でしたが、QA期間も含めると結果的に2ヶ月ぐらいかかってしまいました。

なぜTailwind CSSに置き換える必要があるのか。

メンターの駒木さんからこのタスクを受けた時はなぜ置き換える意味があるのか理解できませんでした。全てのスタイル定義は綺麗にまとまっているように見えましたし、何よりそれぞれの命名もわかりやすく、コードを見るだけで何を表しているのか一目瞭然で、とても綺麗に見えたからです。例えば↓に、サーバからフェッチしたinfoの中のbannerがtruthyな場合に画像を表示させるコードがあります。

<section className="section section--expand" id="hogehoge">
    <div className="section__body">
        {info.banner ? (
            <img alt={info.banner.title} src={info.banner.image_url} />
        ) : null}
    </div>
</section>

とても綺麗に書かれていて一目見ただけで大体何をしているのかわかる気がしますし、見た目もスッキリしています。しかし、section__bodyでgrepしてみるとどうでしょう。

13 件の結果 - 2 ファイル

src/assets/style.scss:
   87  
   88:   .section__body {
   89      display: grid;

  163  
  164:   .section__body {
  165      > img {

  189  
  190:   .section__body {
  191      display: grid;

  296      #own {
  297:       .section__body {
  298          grid-template:

  319  
  320:   .section__body {
  321      display: grid;

  410  
  411:   .section__body {
  412      display: grid;

  441  
  442:   .section__body {
  443      display: grid;

  527  
  528:   .section__body {
  529      display: grid;

  732  
  733:   .section__body {
  734      display: grid;

  747    &.has-app-info {
  748:     .section__body {
  749        grid-template:

src/assets/common_style/_layouts.scss:
  12  #hero {
  13:   .section__body {
  14      align-items: center;

  49  
  50:     .section__body {
  51        padding: 0 var(--page-padding);

  55    &--full {
  56:     .section__body {
  57        max-width: var(--page-max-width);

大変な量がヒットしてしまいます。また、SCSSの仕様上↓みたいに書けるのでsection__bodyでgrepをかけてもヒットしないケースもあるので一つ一つ調べるしかありません。絶望です。

.section {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    margin-top: 20px;
  &__body {
    display: flex;
    flex-direction: column;
    width: 100%;
  }
}

これらの苦痛から解放してくれるのがTailwind CSSです。

<section
    className="mx-auto flex w-full max-w-[500px] flex-col items-center px-[auto]"
  style={{ backgroundColor: "var(--style4)" }}
>
    <div className="mb-10 mt-[10px] flex w-full flex-col justify-center">
        {info.banner ? (
                <img alt={info.banner.title} src={info.banner.image_url} />
        ) : null}
    </div>
</section>

Tailwind CSSはユーティリティーファーストなフレームワークで個々の要素にスタイル適用ができます。そして何より、新しい機能を追加する際にクラス名をいちいち考えなくて良くなるので、不毛な時間から解放されます。他にも、CSS in JSでCSSを直接書く方法もありますが、CSS in JSはPrettierによって不必要に行数を消費しやすく、レビューするときにロジックが見づらくなってしまいます。そのためMirrativではTailwind CSSを採用しています。

grid-templateの実用性

MirrativのLPはデザイナーさんの制作したfigmaを参考に、フロントエンドのエンジニアがLPを実装しています。また、新しい実装機能のほとんどはバックエンドで計算し、返り値をフロント側で表示して初めて一つのリリースとなります。そのため、フロントエンドに求められる能力として以下の項目が挙げられます。

  1. 可読性の高いコードを書く力
  2. スピーディな実装

これらの解決に非常に役立つのがCSSのgrid-template機能です。今回のインターンで初めて知った書き方でした。

import "./App.css";

function App() {
  return (
    <div
      className="w-full grid"
      style={{
        gridTemplate: `
        ".   .   .   . " 12px
        ". title img ." 30px
        ".   .   img ." 12px
        ".  disc img ." auto
        ".   .   .  ." 12px
        ". button button  ." 30px
        ".   .   .   ." 1fr/
        50px auto auto 50px
      `,
      }}
    >
      <h1 style={{ gridArea: "title" }} className="text-center">
        タイトル
      </h1>
      <p style={{ gridArea: "disc" }}>
        ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定
      </p>
      <button
        style={{ gridArea: "button" }}
        className="bg-blue-600 rounded-lg text-white"
      >
        ボタン
      </button>
      <img
        className="h-full"
        style={{ gridArea: "img" }}
        src="https://unsplash.it/630/400"
        alt="ランダムな写真"
      />
    </div>
  );
}

export default App;

このように親要素のHTMLタグに表のような形式でレイアウトを明示してあげると簡単にHTML要素をグリッドで分けることができます。便利ですね。また、動的にレイアウトを変更したい場面もあるかと思いますが三項演算子で簡単に実装できます。

import { useState } from "react";
import "./App.css";

function App() {
  const [isSwitchGrid, setIsSwitchGrid] = useState<boolean>(false);
  return (
    <div
      className="w-full grid"
      style={{
        gridTemplate: `
        ".   .   .   . " 12px
        ${
          isSwitchGrid
            ? `
          ". title img ." 30px
          ".   .   img ." 12px
          ".  disc img ." auto
        `
            : `
          ". img title ." 30px
          ". img   .   ." 12px
          ". img  disc ." auto
        `
        }
        ".   .   .  ." 12px
        ". button button  ." 30px
        ".   .   .   ." 1fr/
        50px auto auto 50px
      `,
      }}
    >
      <h1 style={{ gridArea: "title" }} className="text-center">
        タイトル
      </h1>
      <p style={{ gridArea: "disc" }}>
        ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定,ここに色々説明を書く予定
      </p>
      <button
        style={{ gridArea: "button" }}
        className="bg-blue-600 rounded-lg text-white"
        onClick={() => {
          setIsSwitchGrid(!isSwitchGrid);
        }}
      >
        レイアウト変更ボタン
      </button>
      <img
        className="h-full"
        style={{ gridArea: "img" }}
        src="https://unsplash.it/630/400"
        alt="ランダムな写真"
      />
    </div>
  );
}

export default App;

grid-templateでレイアウト変更

ちょっぴりバックエンド

今回のインターンではバックエンドにも触る機会をいただきました。私のバックエンド知識はFirebaseのCloud でちょっとデータ更新するぐらいの超ど素人です。

タスク内容はイベントが終了して60日経過したら”このイベントは終了しましたページ”にリダイレクトさせるという簡単なタスクでしたが、初めて触るGoに加え膨大なソースコード、何もわからない状態でメンターの駒木さんとチームの皆さんのお力を借りながらなんとかリリースできました。

Goの厳格なCIテストとの戦い

初めてバックエンドのコードを触りましたが、とにかくコーディングルールが厳格で驚きました。関数一つ作るだけでも、CIに”プログラムの効率的にこの関数より前に宣言しましょう”とか”一つの関数の中に処理を書きすぎなので分けましょう”などのテストエラーを吐かれるので苦戦しました。誰が書いても統一感のあるプログラムを維持できたり、バグを未然に防ぐための厳格なテストケースのおかげで、安定したサービスを運営できているのだと知り大変勉強になりました。

また、フロントエンドを専門にするとしてもサーバで何をしているのか、何が返ってくるのかぐらいは理解できないといけないのだと気付かされました。バックエンドは自分にとって敷居が高く、個人開発でもほとんど触る機会がなかったので敬遠していましたが、バックエンドの美に触れ少し興味が湧いてきました。

ミラティブのここがすごい!

某コンビニでよく流れる大学の広告みたいな見出しで失礼します。

私がミラティブのインターン中に魅力に感じたミラティブの制度や取り組みについて書きます。

スゴ飯会

11/8にスゴ飯会というミラティブ社員(業務委託、インターン等を含む)の食事会に参加するために出社しました!交通費+食事代(一人10,000円まで)を会社負担とのことでしたので奈良から参加しました。最高でした。恵比寿のシュラスコでミラティブ社員の方に囲まれて仕事と関係ないプライベートの話で盛り上がったり、人生相談に乗ってもらったりしてとても楽しかったです。

スゴ飯会にてみんなでお肉を食べている図

Unipos

日々の感謝を社員同士でポイントとして贈れるサービスです。毎週決まったポイントを貰えて、その週お世話になった方などにポイント付きで感謝を伝えることができます。

質問に答えていただきありがとう、レビューしてくれてありがとう、特に話してないけどお疲れ様!など、日々の感謝をチームのメンバーに伝えることができてわかりあえるサービスです。個人的にとても好きなサービスです。

フルリモートでのインターン

私のインターンは全てフルリモートでしたが、孤独とか不満を感じることはほとんどありませんでした。Slackでチームの皆さんとコミュニケーションを取ったり、インターン生同士で集まって雑談したりとても楽しく過ごせました。業務においても、わからないことがあったらSlackやGatherで質問すると、快く答えてくれる環境でしたのでとても助かりました。

大学に通いながらインターンに参加できていたのは、ミラティブのリモート環境の充実と、ミラティブの皆さんの温かい雰囲気のおかげだと思います。

終わりに

初めてのインターンでわからないことだらけでしたが、ミラティブの皆さんと一緒に業務をしていた4ヶ月間は、今まで過ごした中で最も濃密な4ヶ月でしたし、インターンを始める前の自分と比べると飛躍的な成長を実感しています。

最後になりますが、メンターである駒木さんをはじめとするミラティブの皆様、ありがとうございました。

We are hiring!

ミラティブでは新卒およびインターンを募集しています!

興味を持った方は、是非エントリーお待ちしています。

www.mirrativ.co.jp

Mirrativ Engineering - ミラティブのエンジニア情報を伝えるポータルサイト -

mirrativ.notion.site