Slide 1

Slide 1 text

大型フロントエンド開発における TypeScriptとDDD FRONTEND CONFERENCE 2016 / March 5, 2016

Slide 2

Slide 2 text

自己紹介 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 奥野 賢太郎 @armorik83 • ChatWork株式会社 サービスデザイン部 • フロントエンドチーム • 京都市出身 • ng-kyoto代表 2

Slide 3

Slide 3 text

チャットワークとは? 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 3 メール・電話に代わるクラウド型ビジネスコミュニケーションツールです

Slide 4

Slide 4 text

チャットワークの規模 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 4 • 累計メッセージ数(2011年3月〜2016年1月) • 10億メッセージ以上 • 導入企業数(2016年2月末) • 92,000社 • 導入国・地域数(2016年2月末) • 205

Slide 5

Slide 5 text

本日お話しすること 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 現行の問題点と
 次の技術選定 5 過 去 現 在 未 来 • 大型開発での
 チーム運営 • TypeScriptとDDDの
 工夫 • Viewフレームワーク
 との付き合い方 • 二槽式アーキテクチャ

Slide 6

Slide 6 text

λΠτϧ © ChatWork All rights reserved. 現行の問題点と次の技術選定 2016/03/05 6

Slide 7

Slide 7 text

現行のWeb版チャットワーク 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • まだmoduleという概念が無い • グローバル変数に名前空間を切る • そこに神オブジェクト • jQuery • ノンフレームワーク • 繰り返される機能拡張 = 増築 • 変わっていかねばならない 7

Slide 8

Slide 8 text

TypeScript 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • ES2015は弊社フロントエンド全員が習得済み • 初期はBabel • 試行錯誤していた • 型が無いと今後厳しいと悟る • TypeScriptに全て書き直し 8

Slide 9

Slide 9 text

AngularJS 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • なぜAngularJS • プロトタイピングに採用 • チームがすでに慣れていた • 私自身の経験が豊富(2年半) • 問題への対策・提案が素早く行えた • Angular 2が控えていることは承知 9

Slide 10

Slide 10 text

λΠτϧ © ChatWork All rights reserved. 大型開発でのチーム運営 2016/03/05 10

Slide 11

Slide 11 text

チームは日々拡大 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 最初はワンマン • 1ヶ月後に1人 • 2週間後にさらに1人加入 • 現在は8〜10人程度 • 構成 • プロジェクト・マネージャ: 1人 • フロントエンド・エンジニア: 3人 + 2人(外注) • バックエンド・エンジニア: 1人 • UIデザイナー: 2人 11

Slide 12

Slide 12 text

チームが大きくなると特有の問題が発生 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • コメント、ドキュメント、コーディング規約 • デザイナーとの連携 • テスト • ビルド、タスクランナー 12

Slide 13

Slide 13 text

コメント 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 指針を持つ • 各行の日本語訳のようなコメントは極力残さない • なぜそう書かざるを得なかったのか、意図をたくさん残す • だいたい思い出せなくなる 13

Slide 14

Slide 14 text

ドキュメント、コーディング規約 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 初期は少人数で、暗黙知が多かった • チームが大きくなってきた際に疑問点のヒアリングを行った • ヒアリングの結果 • 開発環境構築の手順をドキュメント化 • 主要な処理はエントリポイントからコメント付きでフォロー • コーディング・スタイル統一にはtslintを使用 14

Slide 15

Slide 15 text

デザイナーとの連携 (1) 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • デザイナーがSCSSを扱う頻度が高い • JS側には原則としてスタイルを書かない • 逆にデザイナーがHTMLテンプレートを触ることはない • SCSS, BEMを採用 (block__element--modifier) • 手書きだとメンテナンスしにくいのでBEMライブラリを使用 • github.com/axross/bemmer • BEMで影響範囲を特定できリファクタリングは進めやすい 15

Slide 16

Slide 16 text

デザイン仕様書の取り扱い 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 最初はGitHub Wiki • 全文検索できない • 更新に気付かない • 全てをMarkdownにしてPR必須とした • リポジトリ内で検索しやすい! • 更新に気付くだけでなくレビューで必ず目を通す! • dialog/dialog.ts, dialog.scss, dialog.mdのように
 ひとまとめにしている 16

Slide 17

Slide 17 text

単体テスト 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 17 • mocha + power-assert • モックを扱ったり、型違反を意図的に扱ったりする • テストはES 2015で記述 • 不安なロジックはしっかりテスト • ただし盲目的にカバレッジ100%を目指したりはしない • もし実装を変更するたびにテストも修正していたら
 「そもそも何をテストしたい?」に立ち返る • テスト自体も負債化する • テスト内の負債を無視しない

Slide 18

Slide 18 text

E2Eテスト 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 18 • PageObjectパターンを導入 • テストのシナリオと、そのための実現方法を分離 • すべてをPageObjectのメソッド内に隠蔽 • it()の中でElement取得やEventの発火を行わない • テスト側は数行のコードとassert()のみになる • CI上でのE2E実行はSauce Labsで

Slide 19

Slide 19 text

Karmaテスト 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 19 • 開発初期のテストはmochaとE2Eだけだった • 徐々に書ききれない領域が出た • Karmaを追加 • ただしモックのメンテナンス量も増えてしまう • どういうときにKarmaか • やむを得ずViewがステートを保持する場合の検証 • イベントハンドリング周りの検証 • なるべくmochaの単体テストに寄せたほうがいい

Slide 20

Slide 20 text

タスクランナー 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 20 • gulpを使用 • 属人性に気をつける • あっという間に秘伝のタレ化 • gulpファイルの差分を追えるように工夫 • タスクをファイルごとに分割 • 各オプションも細かく行ごとに分ける

Slide 21

Slide 21 text

検証環境の構築 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 21 • 検証は環境構築のコストが高い • VM保守、DBのダミーデータ構築、更新、誰がやる? • 検証環境へのデプロイもgulpで構築 • 弊社@kyo_ago謹製 • 実際のAPIレスポンスを用いて開発できるようになった • フロントエンド・エンジニア内で完結 • CIが回るごとにデプロイを実行 • PR単位でデプロイ、全PRのbundle.jsが残る • バグを追いやすい • 社内の非エンジニアにもドッグフーディングしてもらいやすい

Slide 22

Slide 22 text

ビルド 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 22 • ビルド時間はモチベーションに直結 • 約400ファイルあるTypeScriptのビルド時間が開発上問題に • トータル約60秒! • Browserifyをwebpackに替えたら5分の1! • tsc: 7秒 • Browserify: 30秒 → webpack: 6秒 • tslint: 20秒 • ストレス無くビルドできるよう改善 • SCSSのコンパイルを分ける • tslintの実行順を変える

Slide 23

Slide 23 text

λΠτϧ © ChatWork All rights reserved. TypeScriptとDDDの工夫 2016/03/05 23

Slide 24

Slide 24 text

TypeScriptとDDDが必要になったワケ 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 約400のソース • Component, Service, Utility, API... • 一人で全て把握するなんて無理 • チーム全員で漏れなく共有するのも大変 • TypeScriptの型はチームメンバープロダクト全体の把握を助け、
 揺るぎない情報となる • 大きなシステムほど「膨大な知識」が要求される • Domain-Driven Design ドメイン駆動設計 • チーム内で関心事を掘り下げ共通言語の定義が必要 24

Slide 25

Slide 25 text

TypeScript 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • TypeScript 1.8 • 全ソースがES2015ベース + 型付け • Generics, abstract classの使用 • import前提、namespace(旧: 内部モジュール)は不使用 • tsconfig.jsonでのオプション管理 • 型定義ファイルは全てリポジトリにPush • 微妙に.d.tsを手修正している • 型定義管理ツールよりPullする方がチーム開発において確実という判断 • 強行なので、美しい手段とはいえない 25

Slide 26

Slide 26 text

型の恩恵 (1) 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 一ヶ月後の自分は他人 • コンパイラはJSDocと違って嘘をつかない • むしろ@paramに型情報を書かない • 短いコメントを付けるくらいなら型名を • IDEでのメリット • 全員がIDE "WebStorm"を使用 • ショートカットやクリックでファイルを辿れる • 型名を打つとメソッドが補完される → 開発効率アップ! • TypeScriptの導入コストと、Docs・コメントの保守コスト
 どっちがいい? 26

Slide 27

Slide 27 text

型の恩恵 (2) 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • テストの捉え方が変わる • ロジックの振る舞いそのものの検証に集中できる • サーバレスポンス値など、稀にtscをすり抜けて型違反が起こる場合 • 実行時assertで拾う • 自信を持ってリファクタリングできる • 複雑な計算を含むならばテストを書くことが前提 • スコープが狭ければ型違反が起こらない限り維持できている • コンパイラが守ってくれる安心感 27

Slide 28

Slide 28 text

ドメイン駆動設計 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 28 • バックエンドチームが採り入れている • Vaughn Vernon (実践本) • Eric Evans (原典) • 完璧なDDDの実践は難しい • 言語的な側面もあるし、チーム共有の側面も • フロントエンドチームは、まだDDDが実践できている
 とは言いがたい • TypeScriptを活かすために触れた

Slide 29

Slide 29 text

ユビキタス言語とコンテキスト 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • ユビキタス言語 • エンジニア、デザイナー、ビジネス間での共通言語 • User, Message, Task • 「顔アイコンはIconではなくAvatar」などの共通認識 • 人によって記述がブレないように • コメント、Docs、仕様書、議事録 • コンテキストを分ける • Viewフレームワークに適したデータ構造と抽象概念は必ずしも一致しない • これは開発側の事情 29

Slide 30

Slide 30 text

Coreドメイン 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • User, Message, Taskなどのドメインモデル • すべてAbstractEntityを継承 • コレクションごとのclass • ArrayではなくUsersというclassを作成 • ユビキタス言語内の語彙を増やす • OOP的利点でみると、実装の隠蔽とユニットテストの容易化 • AbstractEntitiesを継承 30

Slide 31

Slide 31 text

Applicationドメイン (1) 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • フレームワーク寄りのデータ構造を定義 • CoreのUserに対する、BindableUser classを定義 • たとえば • 正規化されてIDしか持たないCoreに対して、文字列の値を持つBindable • 画面上でチェックマークが付いているかどうかのbool値 • Iteration protocolsは実装せずJS Arrayとして扱う • Arrayとする 31

Slide 32

Slide 32 text

Applicationドメイン (2) 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • UI上のラベルは、原則Viewレイヤーで計算しない • 「3人」という文字列 • "{{users.length}}人"とせずに"{{labelUsersCount}}"とする • 事前にApplicationドメイン・レイヤーで生成する • 多言語表示に対応しやすい • テストを書きやすい • 頑なに守るとパフォーマンスが出ない箇所もあるので、そこは柔軟に 32

Slide 33

Slide 33 text

TypeScriptとDDD - プリミティブを型で表現 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • たとえば、myidというグローバル変数 • TypeScript上でもnumberとしてしか表現できず貧弱 • 追えない! • Myid classとMyidServiceを実装 • MyidService.getMyid() • Myidインスタンスはvalueプロパティにmyid値を持つ • 引数はmyid: numberにせず、myid: Myidとする • Scalaサイドの知見 • TypeScriptで全てに適用しようとすると煩雑 • 今回は、仕様上やむを得ないグローバル変数にのみ適用 • 追える! 33

Slide 34

Slide 34 text

TypeScriptとDDD - Generics活用 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 34 class AbstractService,
 U extends AbstractEntity> { constructor() { // ... } } • F-Bounded Polymorphism • TypeScript 1.8で動くようになった • 型クラス!!

Slide 35

Slide 35 text

λΠτϧ © ChatWork All rights reserved. Viewフレームワークとの付き合い方 2016/03/05 35

Slide 36

Slide 36 text

Angular? React? 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • どれがいい? • 今どれがオワコン? 36

Slide 37

Slide 37 text

Angular? React? 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • どれがいい? • 今どれがオワコン? • その考え自体を改める 37

Slide 38

Slide 38 text

Angular? React? 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • どれがいい? • 今どれがオワコン? • その考え自体を改める • 長期で取り扱っていくプロダクトほど界隈の変動には巻き込まれる • フレームワークの変動に強いアーキテクチャの検討が必要 • 恐れない • 焦らない 38

Slide 39

Slide 39 text

フレームワーク・ロックインへの考え方 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 今回はAngularJS 1.5 • いつでもAngular 2へ進めるように • 極端な言い方をすると、いつフレームワークを
 捨てても大丈夫な状態を保つ • Applicationドメインに表示用・描画用のロジックを集約 • window, document絡みの処理も全て抽象化 • AngularJSからは単に切り出された処理を使うのみ 39

Slide 40

Slide 40 text

Angular 2化 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 実はすでにAngular 2化も進行中 • 様々な検証を進めている 40

Slide 41

Slide 41 text

λΠτϧ © ChatWork All rights reserved. 二槽式アーキテクチャ 2016/03/05 41

Slide 42

Slide 42 text

二槽式アーキテクチャ 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • 二槽が独立して成立することを目指したアーキテクチャ • @kyo_agoが提唱 • フロントエンド・フロントエンド • テンプレート記述、表示要素のトグル、CSSクラスの動的な変更 • windowやdocumentの絡む箇所、DOM, Elementの操作 • フロントエンド・バックエンド • Coreドメイン、Applicationドメイン • サーバへリクエストを発行、レスポンスを加工 • ゆくゆくはScala.jsで…? 42

Slide 43

Slide 43 text

二槽式アーキテクチャ 図解 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. 43 View Action Controller API Store Application Domain Core Domain Component Frontend-Frontend Frontend-Backend

Slide 44

Slide 44 text

まとめ 大型フロントエンド開発におけるTypeScriptとDDD 2016/03/05 © ChatWork All rights reserved. • チームが大きくなると • デザイン、ドキュメント、テスト、ビルド…いたるところで問題が見つかる • アプリ開発だけでなくチーム全体が上手く回る仕組みづくりも必要 • アプリケーションが大きくなると • 人間の管理が追いつかなくなる • 機械の支援を受ける • コンパイラのエラー • IDEの補完・ジャンプ • いくつもの共通認識を育てながら大型フロントエンド開発を進める 44

Slide 45

Slide 45 text

λΠτϧ © ChatWork All rights reserved. ChatWorkでは Angular 2を書きたいエンジニア を募集しています! 2016/03/05 45 おしまい