Angularで
大規模開発に
取り組み始めた話
2017/10/26
Meguro.es #12
自己紹介
- 西田雅博
- 株式会社Bizreach
- HRMOS採用管理
- Angular 4, Play Framework (Scala)
- React/Redux
Angularで大規模開発に
取り組み始めた話
- AngularJS 1.xで構築されたフロントエンドをAngular 4に置き換えてる最中
- そこでいろんな施策をやってみた
- 良かれと思って
- フィードバック欲しいです!🙏
Contents
-
背景
-
Angular
-
UIコンポーネントの分離+デモアプリ
- オレオレFluxライクアーキテクチャ
背景
- 2014年くらい?からのコード
- HTML/CSS/JS合わせて10万行〜
- サーバーサイドのScalaは20万行〜
- Angular4は今6万行くらい
- Angular JS 1.4 (一部 1.5)
背景
- Flux風アーキテクチャ
- なかなかおつらいコード(aka 技術的負債)
- ngUpgradeの使用を断念
- Angular4で作り直す
- この機会に色々やったろ😏
- 長期間メンテンナンス性を保つ
- Angular 5,6,7 ... と上げていきたい
Angular
Angular
- Angularを使うという決断はどうだったのか
- Angularを使うのが決まったあと参加
Cons
- 高い学習コスト
- Module, DI, RxJSあたりは難しい
- エンジニア・マークアップの住み分けが必要?
- とはいえ一般的なMVCフレームワークの範疇だと思う
- 大規模SPAを構築する道具の学習コストなので、結局は必要なコストなのでは
- 社内勉強会で3ヶ月かけてangular.io/docsを読みきった
- Reactに比べるとまだまだ枯れてない
- 周辺ライブラリなど
- ググるのにいちいち -angularjs するのめんどい
Pros
- 全部入り
- Router, HTTP, Form, Test
- インターフェースにRxJS
- ドキュメント充実
- angular.io (英語)
- Angular-CLI
- Webpackの知識ほぼ不要
- @angular/cdk
- async pipe
- などなど
async pipe
<!-- user$ は Observable<User> もしくは Promise<User> -->
<ng-container *ngIf="user$ | async as user; else loading">
<span>{{ user.name }}</span>
<span>{{ user.mail }}</span>
</ng-container>
<ng-template #loading>
<my-spinner></my-spinner>
</ng-template>
- isLoadingみたいなのを管理しなくていい
- Observableのsubscribe/unsubscribeをよしなにやっておいてくれる
- 非同期・イベントドリブンなコンポーネントを組みやすい
- ng-container: 不要なdivとかを生成しない
Angular
- 個人的には好きです
- サーバーサイドのMVC FWっぽい
- 今は日本語の書籍もあるので学習コストの面はある程度楽になっている?
アプリケーションとUIコンポーネントの分離
+デモアプリ
アプリケーションと
UIコンポーネントの分離
- Button, Toast, Modal などのコンポーネントを別プロジェクトに
- npmのdependencies経由でアプリから使用
- Atomic Designに従う
- デモアプリを作成
- UIコンポーネント、アプリの両方
Demo
Pros
- デザイナー・エンジニアの分業
-
- html/css/animation ...
- ロジック/状態管理/http/RxJS ...
- as a Living Document
- コンポーネント実装時のサンドボックス
Consなど
- メンテナンスコスト
- コードの肥大
- アプリのデモアプリを書くのは結構大変
- たくさんの依存をMockしたり
その他
- 最初はAtomic Componentsを採用していた
- UI/アプリでの分割基準を見直した結果Atomic Designに落ち着いた
- 詳しくは以前の発表資料
- Storybook使ってもいいし自前でアプリ組んでもいいと思う
- 大規模ならコストに見合うメリットありそう
- OSSとして公開したらかっこいい…?
- angular-elementsでWeb Componentsのライブラリとして公開できたらもっとかっこいい…?
- Angular-CLIのmultiple app機能が便利
Flux-like Savkin inspired Architecture
Flux-like Savkin inspired Architecture
Flux-like Savkin inspired Architecture
- 記事ではフロントエンドの状態は6種類に分けられるとある
- それぞれの状態をRxJSのSubjectにして、AngularのDIの仕組みと組み合わせればRedux的なアーキテクチャになると考えた
- Subject: EventEmitterみたいなやつ
- Subject#next(data): イベントを送信
- Subject#subscribe(listener): 受信
だいたいこんな感じ
export interface Todo {
id: number;
text: string;
done: boolean;
}
@Injectable()
export class TodoService {
_todos = new BehaviorSubject<Todo[]>([
{ id: 1, text: 'learn angular', done: false },
{ id: 2, text: 'learn react', done: true },
]);
todos = this._todos.asObservable();
constructor() { }
fetch(): Observable<Todo[]> {
return this.todos;
}
addTodo(text: string) {
const todos = this._todos.getValue();
const nextId = todos.length + 1;
this._todos.next([ ...todos, { id: nextId, text, done: false }]);
}
}
雑な比較
Redux | Angular + RxJS | |
---|---|---|
Store | JSON | 複数のSubject |
Storeの結合 | combineReducers | (combineLatest とか) |
selector | あり | (ServiceのDIとか) |
Action | ActionCreatorの実行 | Serviceメソッドの実行 |
状態の変化 | reducer | Subject#next |
こんなイメージ
{ ... }
Redux
RxJS
Componentのasync pipeにObservable突っ込むだけ、相性抜群
map/filter/reduce/flatMap/combineLatestなどでObservableを加工する
1枚のJSONがAction/Reducerで更新されていく
やってみて
- これでいいじゃん感ある
- まだ複雑な場合で試せてない
- NgRxのデファクトっぷりが加速?
- いまから選定するならNgRxにするかも…
- Savkin先生もNgRx推し
まとめ
- Angularで大規模開発の足場を固めている
- Angular自体大規模に向いている
- UIとアプリを分離してみた
- デモアプリを作ってみた
- NgRxを使わないで状態管理してみた
おわり
Angularで大規模開発に取り組み始めた話
By adwd
Angularで大規模開発に取り組み始めた話
- 4,623