51
Angular.jsで構築した noteに関して Shoei Takamaru (@takamario)

20140823 LL diver Angular.js で構築した note に関して

Embed Size (px)

DESCRIPTION

20140823 LL diver angular.js で構築したnoteに関して/高丸 翔英 angular の魅力や苦労した点などを解説。

Citation preview

Page 1: 20140823 LL diver Angular.js で構築した note に関して

Angular.jsで構築した!noteに関してShoei Takamaru (@takamario)

Page 2: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Agenda

• 自己紹介・サービス紹介

• Angular.jsの紹介

• Angular.jsを使って良かった点・苦労した点

• まとめ

2

Page 3: 20140823 LL diver Angular.js で構築した note に関して

自己紹介

Page 4: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Who are you?

• 高丸 翔英 (たかまる しょうえい, @takamario)!

• エンジニア (フロントエンド寄り?)!

• 2014年1月 ピースオブケイク入社

4

Page 5: 20140823 LL diver Angular.js で構築した note に関して

サービス紹介

Page 6: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Our Services

• デジタルコンテンツ配信プラットフォームCakes (ケイクス) 2012年9月リリースhttps://cakes.mu/!

!

• クリエイターと読者をつなげるサイト!

!

• 週額150円 / 月額500円で全記事読み放題

6

Page 7: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Our Services

• note (ノート) 2014年4月リリース https://note.mu/!

• 個人でコンテンツが100円から販売可能

7

Page 8: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Got a lot of feedback• いろいろなメディアで取り上げていただきました

• リリース1ヶ月で2,000万PV、100万UU 達成

• 売れる人の中には、月10万円ほど稼いでいる人も

8

Page 9: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Got a lot of feedback• リリース時に発生していたXSSが

twitterで話題に (即日対応)

• DM等で、ご連絡いただいた方、体を張って試していただいた方、ありがとうございました

• 「Angular 適切に使ってXSS発生するの?」→ しません、僕が適切に使ってませんでした。。

9

Page 10: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Got a lot of feedback• 2014年7月30日 ワールドビジネスサテライト

http://www.tv-tokyo.co.jp/mv/wbs/newsl/post_71737/

• 2014年8月5日 エンジニアtypehttp://engineer.typemag.jp/article/sadoshimavskato

10

Page 11: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Got a lot of feedback

• 芸能人アカウントも続々

11

伊集院光さん

ロンブー田村淳さんくるりさん

GLAY HISASHIさん

Page 12: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

News

• くるり公式ファンクラブ純情息子がnoteに移行

• 会報、オフショット、チケット先行予約案内などすべてがnote上で!

12

Page 13: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

News

• 山本さほさんのマンガ岡崎に捧ぐがヒット!https://note.mu/sahoobb/m/m6d7f0f032e74

• 80年代生まれの人に 多く共感される

• 今後は一般の方の作品が爆発的に売れる可能性も!

13

Page 14: 20140823 LL diver Angular.js で構築した note に関して

noteの開発体制と システム構成

Page 15: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Our Dev Team and System• CTO (SGP) x 1

• エンジニア (JPN) x 3 (高丸を含む)

• デザイナー (JPN) x 2

• iPhone App エンジニア (SGP) x 1

• and ディレクター、ユーザサポート(JPN)

• Ruby on Rails + Angular.js + MySQL + Redis + ElasticSearch

• AWS

• Github + HipChat + Jenkins 15

Page 16: 20140823 LL diver Angular.js で構築した note に関して

Angular.js

Page 17: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Why Angular?

•使ってみたかったから!(70%)

• SPAのUIに惹かれて (20%)

• API層を結局作るので (10%)

17

最初の想い

Page 18: 20140823 LL diver Angular.js で構築した note に関して

他にも フレームワークはある

Page 19: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

jQuery

19

$('button.like-button').click(function(){ // Call `Like` API $.ajax() .done(function(){ $(this).addClass('active'); });});

$('input.comment-form') .keypress(function(e){ // Press Enter then submit if (e.which === 13) $.ajax(); // Comment API});

jQueryって こんなに簡単だけど 結果、煩雑になる

Page 20: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

jQuery pros/cons

• 超簡単

20

良い所

悪い所

• フレームワークじゃない

• ルールがないから、煩雑になる

Page 21: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Backbone.js

21

var Like = Backbone.Model.extend({ url: '/like'});!var LikeButton = Backbone.View.extend({ el: $('button.like-button'),! events: { 'click button.like-button': 'addLike' },! addLike: function() { Like.save(); $(this.el).addClass('active'); }});

<script type=“text/template" id=“tmpl-like-button"> <button class=“like-button"> スキ </button></script>

よりオブジェクトっぽい使い方

Page 22: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Backbone pros/cons

• 正統派、JSっぽい

• 軽い、導入しやすい

• フレームワークを使うことで、開発ルールが決まる

22

良い所

悪い所• イベントのバインディングが面倒

• Getter / Setter は面倒

Page 23: 20140823 LL diver Angular.js で構築した note に関して

そこで

Page 24: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Angular.js

24

<div class="note" ng-controller="NoteCtrl"> <div class="datetime">{{ note.published_at | date:'yyyy/MM/dd'}}</div> <p class="talk">{{ note.body }}</p>! <button class="like-button" ng-click="likeNote()">! <div class="comment"> <input class="comment-form" ng-model="comment"> </div></div>

var noteApp = angular.module('noteApp',[]);!myApp.controller('NoteCtrl', [ '$scope', function($scope, $http) { $scope.likeNote = function() { $http.post('like'); }; }]);

Page 25: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Angular.js

25

注目すべき点• HTMLがそのままテンプレートに

• インラインでイベントバインディング(ng-click等)インラインでviewとmodelのバインディング(ng-model)

• Model 側であった変更が、View に伝わるView 側であった変更が、Model に伝わる(2-way Data binding)

Page 26: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

The 1st Month of Development

• あ、意外と書けるかも、HTMLにコード書くっていいね

• 2 way-binding マジ楽コード書いてないけど、勝手にここの値も変わってくれるし

26

Controller を作り、ModelとViewを対応させるのは簡単

デザイナーがHTMLを作成/修正

エンジニアがng-xxxxを付ける/移動する

スピーディな開発

Page 27: 20140823 LL diver Angular.js で構築した note に関して

でも

Page 28: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Fat controller

28

var noteApp = angular.module('noteApp',[]);myApp.controller('NoteCtrl', [‘$scope', function($scope) { $scope.method1 = function() { // do something }; $scope.method2 = function() { // do something }; $scope.method3 = function() { // do something }; $scope.method4 = function() { // do something }; $scope.method5 = function() { // do something }; ・・・ }]);

メソッドずらり。。 重複してるメソッドも散財。。

→ Services や Directives に移すべき

Page 29: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

The 2nd Month of Development

• そういえば、AngularってDirectivesってあるじゃん

• すげえ、属性つけるだけでちゃんと動いてくれるよ!

• これ、つまり controller に書かなくて良くない!?

• 使いまわせるね

29

Directives

Page 30: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Directives (restrict: ‘A’)

30

<div class="note" ng-controller="NoteCtrl"> <div class="datetime">{{note.published_at | date:'yyyy/MM/dd'}}</div> <p class="talk">{{note.body}}</p>! <button class="like-button" like-button likable=“note”>! <div class="comment"> <input class="comment-form" comment-form commentable=“note” enter-submit> </div></div>

noteApp.directive('likeButton', function() { return { restrict: 'A', scope: { likable: ‘=' }, link: function(scope, element, attrs) { element.click(function(){}); } };});

Directives

DirectivesDirectives Directives

Directives

Page 31: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Directives (restrict: ‘A’)

31

<div class="note" ng-controller="NoteCtrl"> <div class="datetime">{{note.published_at | date:'yyyy/MM/dd'}}</div> <p class="talk">{{note.body}}</p>! <button class="like-button" like-button likable=“note”>! <div class="comment"> <input class="comment-form" comment-form commentable=“note” enter-submit> </div></div>

関数名 引数 のイメージcontroller と directive の scope をうまく共有するためには

引数をうまく使うこと

Page 32: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Directives (restrict: ‘E’)

32

<note-card note="note"> <datetime format="yyyy/MM/dd"> <p class="talk">{{note.body}}</p> <like-button likable="note">! <comment-form commentable=“note”></note-card>

独自のタグが使える

noteApp.directive('likeButton', function() { return { restrict: 'E', template: ‘<button class=“like-button”></button>’ };});

Page 33: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

The 3rd Month of Development

• そういえば、他のブラウザは? (みんなChrome使用)

• Firefox:ちょいバグあるぐらい

• Safari:割と動いてる

• IE:え、IE?

33

テスト真っ最中、バグは多い。。

Page 34: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

What’s IE?

34

IEを斬る!!

Page 35: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

TextNote Editor

35

• MediumライクなWYSIWYGエディタ(contenteditable)

• 生JSMVCじゃなくて、DOMいじりばっかり

• クロスブラウザ対応難しい

Page 36: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

The 3rd Month of Development

• ボットのためにJS動かさないとね

• Google と Yahoo! と Bing と?

• Facebook?

• はてな?Pocket?

36

SEO対策は?

Page 37: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

OGP

• 初期には、Phantom JS で Angular をレンダリングする荒技を検討

• が、OGP bot ごとに対応が必要

• 2段階で来るbotも。。

• サーバサイドで返すように修正しました

37

Phantom JS (w/ cache)

Page 38: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Recently

• scope が watch しなければいけない対象が増えると Angular は極端に遅くなる(例:Infinite Pager でもっと見る)

• 高速化に関して (@konpyu)http://www.slideshare.net/KonYuichi/speeding-up-angularjs

38

パフォーマンスが落ちてきている

Page 39: 20140823 LL diver Angular.js で構築した note に関して

Angular まとめ

Page 40: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Angular Pros/Cons

• HTML + JS の開発は速い(気がする)、noteリリースはAngularのおかげ

• 2 Way Data Binding は幸せになれる

• 学習コストは突然高くなる マスターするならscopeとdirectiveの理解を集中的に

• Phantom JS で OGPは荒業よ

• ある程度に行くとパフォーマンスチューニングが必要

• IE は 名称が変わります

40

Page 41: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Future of JS• DHH は JS MVCフレームワーク嫌いらしい

http://signalvnoise.com/posts/3697-server-generated-javascript-responses

• HTML/JS分離の時代から、HTML + JSの部品の時代

• Google さんの時代

• Polymer → 部品化、再利用性の向上

• Dart → JSのパフォーマンス向上

• HTTP2.0 (SPDY) → セキュア、つなぎっぱ

• Wear → どこでも、どのデバイスでも41

Page 42: 20140823 LL diver Angular.js で構築した note に関して

最後に

Page 43: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

We’re hiring!

• ピースオブケイクではエンジニアを募集しています!

• cakesとnoteを支えるサーバーサイドエンジニアを募集!https://www.wantedly.com/projects/9689

• cakesとnoteを開発したいJavaScriptエンジニアさん大募集!https://www.wantedly.com/projects/7198

• noteのiOS/Androidアプリをつくりたいエンジニアさん大募集!https://www.wantedly.com/projects/7199

43

Page 44: 20140823 LL diver Angular.js で構築した note に関して

Thank you for listening!

Page 45: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Scope

• Scope を制するものは、Angular を制す (と思ってる)

• qiita: Angular JS で複数のコントローラ間でモデル(状態や値)を共有する方法 3 種類http://qiita.com/sunny4381/items/aeae1e154346b5cf6009

45

Scope

Page 46: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Scope

46

Upper Controller

Lower Controller

Main Controller Event

遠く離れたスコープでも共有可能、上書きの危険性もない !JSっぽい !双方向のコードを書く必要があるので、Angular ではあまり使わない方が良い http://plnkr.co/edit/7sD1JvA6TtKbkDBlZWLq?p=preview

Page 47: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Scope

47

Upper Controller

Lower Controller

Main Controller

Service

部品と部品をつなぐ !DI するだけで使用可能 !結局グローバル変数と変わらない (上書き注意) http://plnkr.co/edit/ajKnEz3jfMtpEG7aZ5kO?p=preview

Service

Page 48: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Scope

48

Upper Controller

Lower Controller

Main ControllerAngular の機構を そのまま利用 !Angular 推奨 !子は、親のスコープが見える !http://plnkr.co/edit/znYpEq4ibzUFIBSOwK2Y?p=preview !http://plnkr.co/edit/AxCPK6YrmTKsjhQtT8f1?p=preview

Parent / Child Scope

Page 49: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Reusability

• いかに、再利用性を高めるか Controller だけだとつらい

• コメント、Like、フォロー等々、いつどこに置くかもしれないものは Directive に

• ただ、基本的な設計は、function の設計と変わらない (インターフェースが汎用的かどうか)

49

Directive / Service

Page 50: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Libraries

• angular-ui/bootstraphttps://github.com/angular-ui/bootstrap

• angular-ui/ui-router https://github.com/angular-ui/ui-router

• danialfarid/angular-file-upload https://github.com/danialfarid/angular-file-upload

50

Page 51: 20140823 LL diver Angular.js で構築した note に関して

Copyright © Piece of Cake, Inc. All Rights Reserved.

Appendix - Books

• ng-book https://www.ng-book.com/

!

• AngularJSアプリケーション開発ガイドhttp://www.amazon.co.jp/dp/4873116678

51