Pro Yearly is on sale from $80 to $50! »

Frontend Architecture of teamLab

04af2bd3a713a0d5da3b9c361681b65d?s=47 simochee
November 16, 2019

Frontend Architecture of teamLab

チームラボはアートだけでなくWebやアプリの受託開発も行っています。

そんなチームラボのフロントエンドチームで使用しているアーキテクチャを実例を交えてご紹介します。

Frontend Conference Fukuoka 2019 にて登壇しました。
https://frontend-conf.fukuoka.jp/sessions#a-3

04af2bd3a713a0d5da3b9c361681b65d?s=128

simochee

November 16, 2019
Tweet

Transcript

  1. フロントエンドカンファレンス福岡 スポンサーセッション チームラボ株式会社 teamLab Inc チームラボの フロントエンドアーキテクチャ フロントエンドチーム 田村亮弥

  2. 2 公開先はこのあと、@teamlab_recruit にてツイートします このスライドは公開されます!

  3. 自己紹介 3

  4. 自己紹介 • 1997年6月28日生まれ(22歳) • 山口県下関市出身 • 宇部工業高等専門学校 制御情報工学科卒 • 2018年4月

    チームラボに新卒入社 • 好きなもの:鉄道、東京03 • 好きなエディタ:VS Code ◦ テーマ:Netflix Red theme • 気になるもの: Parcel v2 / TypeScript 3.7 田村 亮弥 @lollipop_onl チームラボ株式会社 フロントエンドチーム 4
  5. チームラボの紹介 5

  6. チームラボの各チーム 6 • Webアプリケーションチーム • フロントエンドチーム • スマホアプリチーム • インタラクティブチーム

    • 機械学習チーム • サーチ・レコメチーム • ハードウェアチーム など • UI / UX デザイナー • ビジュアルデザイナー など 650人 • カタリスト
  7. チームラボの受託開発は、初期の提案フェーズから行う。 エンジニアはすべてのフェーズに参加する。 チームラボの受託開発 7 提案 見積もり、実現の可否 1 要件定義 仕様の詰め、外部ベンダーとの連携 2

    設計 / 実装 考える、作る、レビューする 3 テスト 仕様通りに動作するか確認 4 リリース リリースしてからがスタート 5 保守・追加開発 不具合、障害対応・追加開発 6
  8. プロジェクトの規模 • 人数 ◦ 5人(カタリスト:1、デザイナー:1、フロントエンド:1、バックエンド:2)〜 30人規模(カタリスト:3、デザイナー:3、フロントエンド:3、バックエンド:20、テスター:3) ◦ フロントエンドは平均3〜4名 • 期間

    ◦ 3ヶ月 〜 数年(保守を含む) 8
  9. フロントエンドチーム • メンバー:12人(平均: 27歳) • 受託開発 / アート案件のJavaScript実装 ◦ Node.jsでのツール開発やサーバー開発を行うこともある

    • 仕様やデザイン、API設計をそれぞれの担当者と検討 ◦ プロジェクトの中心で各方面と連携 • チーム内の活動 ◦ 週定例・タスクチェック ◦ ナレッジ共有会 … 案件で利用した技術や体験の共有 ◦ 勉強会 … 担当者持ち回りで隔週で開催。最近の話題はReasonML、Svelte、DIなど 9
  10. フロントエンドチームの実績 10

  11. 成田空港リニューアル 11

  12. イノベーション自販機 12

  13. チームラボアプリ 13

  14. スマホサイフ 14

  15. マイナビバイト Webサイト 15

  16. 本題 16

  17. ご注意 17 このスライドでのアーキテクチャは「フロントエンド開発の構成そのもの」を指し、 プロジェクトごとのフレームワークや周辺ツール、コーディング規約まですべてを含みます。

  18. 採用されたことのある技術 18

  19. 今回フォーカスする部分 19 Webpackでのマークアップ環境構築 実案件への採用と苦労話 社内で自作ルールを作成

  20. 実案件への採用と苦労話 20

  21. 21 • The Progressive Vue.js Framework • サーバーサイドレンダリング(SSR) • ルーティング

    ◦ ディレクトリ構成からのルーティングの自動生成 • Webpack開発環境 • 静的サイトジェネレータ ◦ SEOを意識したSPAアプリのビルド • TypeScriptの公式サポート(Nuxt TypeScript) Nuxt.js - The Vue.js Framework
  22. 22 • 静的型付け、型推論 ◦ 型による動作保証 • 11/5に TypeScript 3.7.2 がリリースされた

    ◦ Optional Chaining ▪ ? をつけると値がなくても {} と解釈される ◦ Nullish Coalescing ▪ Null/Undefined のみ false となるOR比較 TypeScript - JavaScript that scales.
  23. 採用実績 23

  24. RAKURU 24

  25. Nuxt採用の経緯 • バックエンドはAPIを開発する • ページ表示速度の高速化のため、非同期ページ遷移( Pjax)をしたい • SEOも考慮しなければならない ➢ SEO対応もできるSPA

    → Nuxt • 初めての採用は2018年10月(当時 Nuxt 2.1.0) • 現在は 7 案件で採用 25
  26. Nuxtでの苦労話 26

  27. Nuxt採用のメリット 27 • バックエンドとフロントエンドの責務分割 ◦ バックエンドがメタタグの SSRだけ担当のようなことがなくなる ◦ CMS組み込みにするとSPAにしづらい •

    初期コストの削減 ◦ 開発環境、ルーティング、 Vuexなど必要な機能があらかじめ揃っている
  28. 苦労①:ライブラリの使用 • ライブラリの読み込みがうまく行かない ◦ window or document undefined ◦ Tree

    Shakingはしたい ➢ プラグインとして読み込み 28 window or document undefined - NuxtJS
  29. 苦労①:ライブラリの使用 • Nuxtのドキュメントで紹介されている記法。 29 window or document undefined - NuxtJS

  30. 苦労②:lodash-esの使用 • lodash-esを使いたい ◦ Tree Shakingしたい ◦ Nodeが import 文を解釈できないため実行時エラーになる

    30
  31. 苦労②:lodash-esの使用 • build.transpile プロパティを使用する ◦ マッチしたモジュールを Babelでトランスパイルできる ◦ Nodeが参照するときにはトランスパイル済み 31

    API: The build Property - NuxtJS
  32. 余談:Tree Shaking • Tree Shakingの力 ◦ lodashのisEqualメソッドのみ使用した場合 ◦ lodash:527.84 KB

    (Stat size) ◦ lodash-es:58.96 KB (Stat size) 32
  33. 苦労③:Nuxtサーバーのメモリリーク • Nuxtサーバーがメモリリークを起こしていた ◦ ユーザーのアクセスに比例してメモリ使用率が上昇していた ◦ 当初はメモリ使用率 2GB前後でサーバーがダウンしていた 33 2GB

    10/2 10/3 10/4
  34. 苦労③:Nuxtサーバーのメモリリーク • 原因予測 ◦ VuexのSSR時のStateがメモリ内に残っている? ◦ パースしたテンプレートの文字列がメモリ内に残っている? • 暫定対応 ◦

    Nodeのメモリ上限を 7GB に変更 34
  35. 苦労③:Nuxtサーバーのメモリリーク • 原因 ◦ Nodeのインスペクタのメモリスナップショットで開放されていないメモリを調査 ◦ クラスの静的メンバーの Mapへ値が追加され続けていた 35

  36. 苦労④:複数のパスを持つページ • 同じページなのに複数のパスを用意しなければ行けない場合 ◦ /pages/cart.vue と /pages/cart/_cartId.vue ◦ いずれかを参照して export

    すればパスを量産できる 36
  37. Webpackでのマークアップ環境構築 37

  38. 38 • JavaScript静的モジュールバンドラー ◦ 依存関係を解決して静的なファイルに書き出す • Webpack 5.0.0-beta.0が10/11に公開された webpack

  39. フロントエンドとWebpack 39 • フロントエンドチームでの開発環境の主力は Webpack ◦ 少し前の案件はGulp + Webpackの構成が多い ◦

    小規模な案件ではParcelが使わることもある • マークアップをすることも多い • PugのためだけにGulpは使用したくない ➢ Webpack でマークアップしたい
  40. vs HTMLWebpackPlugin • HTMLWebpackPlugin ◦ HTMLをビルドするプラグイン ◦ 1ファイルにつき 1プラグイン必要 ◦

    動的なファイル追加・HMRが難しい ➢ HTMLWebpackPluginは使わない 40
  41. WebpackでPugをビルド ① Pugのエントリーポイントファイルを作成 • Pugのエントリーポイントになる js ファイルを作成 41 webpackだけでpugをビルドする環境を作る -

    Qiita
  42. WebpackでPugをビルド ② Pug関連のLoaderを追加 42 webpackだけでpugをビルドする環境を作る - Qiita

  43. Pugファイル更新時のHMR • Pugファイル更新時にリロードされない ◦ webpack-dev-server の Hot Reload の設定と競合 ➢

    browser-sync でHMRさせる ◦ webpackだけでpugをビルドする環境を作る - Qiita 43 webpackだけでpugをビルドする環境を作る - Qiita
  44. 社内で自作ルールを作成 44

  45. コーディング規約 45 • 社内でコーディング規約が統一できていなかった • ただ、各自に好みのルールがあるのは事実 ◦ 個人的に comma-dangle は譲りたくない

    @team-lab/eslint-config - npm
  46. ESLintルールの自作 • フロントエンドチームでオリジナルの ESLintルールを作成    @team-lab/eslint-config    team-lab/eslint-config • サポート

    ◦ JavaScript / TypeScript 46 @team-lab/eslint-config - npm
  47. ESLintルールを自作して • ソースコードの体裁を揃えるのは保守性が上がる • 社内ルールということでプロジェクトに導入しやすい • ルールに手を入れやすい • ルールを検討する中で、JavaScriptの知識が増えた ◦

    no-caller ◦ @typescript-eslint/unbound-method 47
  48. ESLintの便利な機能 • overrides プロパティ ◦ 対象のファイルでのルールを上書きする ◦ Vueファイルのみで以下の設定を変更 ▪ this

    を使わないクラスメソッドの 定義を許可 ▪ $_veeValidate という変数名を 許可 48
  49. ESLintの便利な機能 • --max-warnings オプション ◦ エラーにしない警告の上限を設定 ◦ --max-warnings 0 で警告があればチェック後にエラーとなる

    ◦ CIでのESLintチェックの際に警告も許したくない場合に便利 49
  50. おわりに 50

  51. チームラボではこういう人を募集しています 51 • ものづくりが好きな人 • フロントエンドが好きな人 • 自発的に動ける人 • 面白い人

    teamLab recruit: https://www.team-lab.com/recruit Wantedly: https://www.wantedly.com/projects/21489
  52. ご清聴ありがとうございました 52 ブース出展もしているのでぜひお越しください!