チームラボはアートだけでなくWebやアプリの受託開発も行っています。
そんなチームラボのフロントエンドチームで使用しているアーキテクチャを実例を交えてご紹介します。
Frontend Conference Fukuoka 2019 にて登壇しました。 https://frontend-conf.fukuoka.jp/sessions#a-3
フロントエンドカンファレンス福岡 スポンサーセッションチームラボ株式会社 teamLab Incチームラボのフロントエンドアーキテクチャフロントエンドチーム 田村亮弥
View Slide
2公開先はこのあと、@teamlab_recruit にてツイートしますこのスライドは公開されます!
自己紹介3
自己紹介● 1997年6月28日生まれ(22歳)● 山口県下関市出身● 宇部工業高等専門学校 制御情報工学科卒● 2018年4月 チームラボに新卒入社● 好きなもの:鉄道、東京03● 好きなエディタ:VS Code○ テーマ:Netflix Red theme● 気になるもの: Parcel v2 / TypeScript 3.7田村 亮弥@lollipop_onlチームラボ株式会社フロントエンドチーム4
チームラボの紹介5
チームラボの各チーム6● Webアプリケーションチーム● フロントエンドチーム● スマホアプリチーム● インタラクティブチーム● 機械学習チーム● サーチ・レコメチーム● ハードウェアチーム など● UI / UX デザイナー● ビジュアルデザイナー など650人● カタリスト
チームラボの受託開発は、初期の提案フェーズから行う。エンジニアはすべてのフェーズに参加する。チームラボの受託開発7提案 見積もり、実現の可否1要件定義 仕様の詰め、外部ベンダーとの連携2設計 / 実装 考える、作る、レビューする3テスト 仕様通りに動作するか確認4リリース リリースしてからがスタート5保守・追加開発 不具合、障害対応・追加開発6
プロジェクトの規模● 人数○ 5人(カタリスト:1、デザイナー:1、フロントエンド:1、バックエンド:2)〜30人規模(カタリスト:3、デザイナー:3、フロントエンド:3、バックエンド:20、テスター:3)○ フロントエンドは平均3〜4名● 期間○ 3ヶ月 〜 数年(保守を含む)8
フロントエンドチーム● メンバー:12人(平均: 27歳)● 受託開発 / アート案件のJavaScript実装○ Node.jsでのツール開発やサーバー開発を行うこともある● 仕様やデザイン、API設計をそれぞれの担当者と検討○ プロジェクトの中心で各方面と連携● チーム内の活動○ 週定例・タスクチェック○ ナレッジ共有会 … 案件で利用した技術や体験の共有○ 勉強会 … 担当者持ち回りで隔週で開催。最近の話題はReasonML、Svelte、DIなど9
フロントエンドチームの実績10
成田空港リニューアル11
イノベーション自販機12
チームラボアプリ13
スマホサイフ14
マイナビバイト Webサイト15
本題16
ご注意17このスライドでのアーキテクチャは「フロントエンド開発の構成そのもの」を指し、プロジェクトごとのフレームワークや周辺ツール、コーディング規約まですべてを含みます。
採用されたことのある技術18
今回フォーカスする部分19Webpackでのマークアップ環境構築実案件への採用と苦労話社内で自作ルールを作成
実案件への採用と苦労話20
21● The Progressive Vue.js Framework● サーバーサイドレンダリング(SSR)● ルーティング○ ディレクトリ構成からのルーティングの自動生成● Webpack開発環境● 静的サイトジェネレータ○ SEOを意識したSPAアプリのビルド● TypeScriptの公式サポート(Nuxt TypeScript)Nuxt.js - The Vue.js Framework
22● 静的型付け、型推論○ 型による動作保証● 11/5に TypeScript 3.7.2 がリリースされた○ Optional Chaining■ ? をつけると値がなくても {} と解釈される○ Nullish Coalescing■ Null/Undefined のみ false となるOR比較TypeScript - JavaScript that scales.
採用実績23
RAKURU24
Nuxt採用の経緯● バックエンドはAPIを開発する● ページ表示速度の高速化のため、非同期ページ遷移(Pjax)をしたい● SEOも考慮しなければならない➢ SEO対応もできるSPA → Nuxt● 初めての採用は2018年10月(当時 Nuxt 2.1.0)● 現在は 7 案件で採用25
Nuxtでの苦労話26
Nuxt採用のメリット27● バックエンドとフロントエンドの責務分割○ バックエンドがメタタグの SSRだけ担当のようなことがなくなる○ CMS組み込みにするとSPAにしづらい● 初期コストの削減○ 開発環境、ルーティング、 Vuexなど必要な機能があらかじめ揃っている
苦労①:ライブラリの使用● ライブラリの読み込みがうまく行かない○ window or document undefined○ Tree Shakingはしたい➢ プラグインとして読み込み28window or document undefined - NuxtJS
苦労①:ライブラリの使用● Nuxtのドキュメントで紹介されている記法。29window or document undefined - NuxtJS
苦労②:lodash-esの使用● lodash-esを使いたい○ Tree Shakingしたい○ Nodeが import 文を解釈できないため実行時エラーになる30
苦労②:lodash-esの使用● build.transpile プロパティを使用する○ マッチしたモジュールを Babelでトランスパイルできる○ Nodeが参照するときにはトランスパイル済み31API: The build Property - NuxtJS
余談:Tree Shaking● Tree Shakingの力○ lodashのisEqualメソッドのみ使用した場合○ lodash:527.84 KB (Stat size)○ lodash-es:58.96 KB (Stat size)32
苦労③:Nuxtサーバーのメモリリーク● Nuxtサーバーがメモリリークを起こしていた○ ユーザーのアクセスに比例してメモリ使用率が上昇していた○ 当初はメモリ使用率 2GB前後でサーバーがダウンしていた332GB10/2 10/3 10/4
苦労③:Nuxtサーバーのメモリリーク● 原因予測○ VuexのSSR時のStateがメモリ内に残っている?○ パースしたテンプレートの文字列がメモリ内に残っている?● 暫定対応○ Nodeのメモリ上限を 7GB に変更34
苦労③:Nuxtサーバーのメモリリーク● 原因○ Nodeのインスペクタのメモリスナップショットで開放されていないメモリを調査○ クラスの静的メンバーの Mapへ値が追加され続けていた35
苦労④:複数のパスを持つページ● 同じページなのに複数のパスを用意しなければ行けない場合○ /pages/cart.vue と /pages/cart/_cartId.vue○ いずれかを参照して export すればパスを量産できる36
Webpackでのマークアップ環境構築37
38● JavaScript静的モジュールバンドラー○ 依存関係を解決して静的なファイルに書き出す● Webpack 5.0.0-beta.0が10/11に公開されたwebpack
フロントエンドとWebpack39● フロントエンドチームでの開発環境の主力は Webpack○ 少し前の案件はGulp + Webpackの構成が多い○ 小規模な案件ではParcelが使わることもある● マークアップをすることも多い● PugのためだけにGulpは使用したくない➢ Webpack でマークアップしたい
vs HTMLWebpackPlugin● HTMLWebpackPlugin○ HTMLをビルドするプラグイン○ 1ファイルにつき 1プラグイン必要○ 動的なファイル追加・HMRが難しい➢ HTMLWebpackPluginは使わない40
WebpackでPugをビルド① Pugのエントリーポイントファイルを作成● Pugのエントリーポイントになる js ファイルを作成41webpackだけでpugをビルドする環境を作る - Qiita
WebpackでPugをビルド② Pug関連のLoaderを追加42webpackだけでpugをビルドする環境を作る - Qiita
Pugファイル更新時のHMR● Pugファイル更新時にリロードされない○ webpack-dev-server の Hot Reload の設定と競合➢ browser-sync でHMRさせる○ webpackだけでpugをビルドする環境を作る - Qiita43webpackだけでpugをビルドする環境を作る - Qiita
社内で自作ルールを作成44
コーディング規約45● 社内でコーディング規約が統一できていなかった● ただ、各自に好みのルールがあるのは事実○ 個人的に comma-dangle は譲りたくない@team-lab/eslint-config - npm
ESLintルールの自作● フロントエンドチームでオリジナルのESLintルールを作成 @team-lab/eslint-config team-lab/eslint-config● サポート○ JavaScript / TypeScript46@team-lab/eslint-config - npm
ESLintルールを自作して● ソースコードの体裁を揃えるのは保守性が上がる● 社内ルールということでプロジェクトに導入しやすい● ルールに手を入れやすい● ルールを検討する中で、JavaScriptの知識が増えた○ no-caller○ @typescript-eslint/unbound-method47
ESLintの便利な機能● overrides プロパティ○ 対象のファイルでのルールを上書きする○ Vueファイルのみで以下の設定を変更■ this を使わないクラスメソッドの定義を許可■ $_veeValidate という変数名を許可48
ESLintの便利な機能● --max-warnings オプション○ エラーにしない警告の上限を設定○ --max-warnings 0 で警告があればチェック後にエラーとなる○ CIでのESLintチェックの際に警告も許したくない場合に便利49
おわりに50
チームラボではこういう人を募集しています51● ものづくりが好きな人● フロントエンドが好きな人● 自発的に動ける人● 面白い人teamLab recruit: https://www.team-lab.com/recruitWantedly: https://www.wantedly.com/projects/21489
ご清聴ありがとうございました52ブース出展もしているのでぜひお越しください!