90

Click here to load reader

実践Backbone.Marionette 現場の悩みと解決まで

Embed Size (px)

DESCRIPTION

2014/1/22 gooラボopen tech talkで話したBackbone.jsとMarionette.jsの話です。

Citation preview

Page 1: 実践Backbone.Marionette 現場の悩みと解決まで

実践Backbone.Marionette現場の悩みと解決まで

ryuma tsukano (@lxyuma)塚野 龍馬

Page 2: 実践Backbone.Marionette 現場の悩みと解決まで

Presented By ...

Page 3: 実践Backbone.Marionette 現場の悩みと解決まで

● ServerSide寄りWeb Developer○ 元々SIer出身:java/rubyで法人サービス開発してた○ 今は、弊社でCGMを開発○ 技術Skill

■ 言語FW:Rails + Backbone■ storage:MySQL + MongoDB■ 他rails周辺技術

● 趣味○ 旅行/音楽/美味しい物食べる事○ 去年は台湾とFrance行った(今年は国内巡ろう)○ 2013年ハマったのは、あまちゃんと叛逆

自己紹介 : 塚野 龍馬 (@lxyuma)

Page 4: 実践Backbone.Marionette 現場の悩みと解決まで

jsCafe

jsCafeというjavascriptの勉強会をやってる

今日のMarionetteも元はこちらで発表した物

良ければ是非お気軽にご参加を(次は2/2予定)

Page 5: 実践Backbone.Marionette 現場の悩みと解決まで

目的/目標

● 対象○ ある程度、Backbone知ってる方

● 目的○ 現実的にBackboneを使う上での悩み事を解決する

● 目標○ 現場でBackbone適用して絶望する人を減らす

Page 6: 実践Backbone.Marionette 現場の悩みと解決まで

目次(& ダイジェスト)

● 導入編○ Angularとの比較、BackboneでのDataBindings等

● 設計編○ Marionetteでのコンポーネント構成等

● 実装編○ オレオレ実装を如何に回避するか?等

● テスト編○ javascriptのtestし辛い所と救済措置

⇒これらQA形式で書いて行く。

Page 7: 実践Backbone.Marionette 現場の悩みと解決まで

導入編

Page 8: 実践Backbone.Marionette 現場の悩みと解決まで

javascriptのframework界隈の動き

といえば、Angularの勢いが強いですね

● DailyJSの2013年12月Survveyの利用率○ Backbone:25%(辛うじて1位)○ Angular:25%(僅差で2位)

● GoogleTrendsでAngularが急上昇○ 日本でも2013年9月に逆転してAngular>Backboneに

[世界] [日本]

Page 9: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneやべぇ

結構古いし

そろそろ寿命?

^o^ /老害ですか?

Page 10: 実践Backbone.Marionette 現場の悩みと解決まで

「老害」について

Engineer皆が好きな言葉だから

ついでにGoogleTrendsで調べてみた

着実に上昇中! 色々検索されてる!

Page 11: 実践Backbone.Marionette 現場の悩みと解決まで

「老害 Backbone」

良かった〜(> <;)まだ、胸を張って生きていけそうです。

Page 12: 実践Backbone.Marionette 現場の悩みと解決まで

BackboneとAngularを比較する

● VictorSavkin氏の比較記事○ infoQ訳

■ 俺も前に訳してたんだけどね><

● この記事が良いのは、○ Plugin付けた現実的な構成のBackboneと○ Angularを比較してる所

Page 13: 実践Backbone.Marionette 現場の悩みと解決まで

BackboneとPlugin

● Backbone = ただの背骨○ 肉は自分で付けないといけない><○ 肉付けは大体皆一緒 = Plugin化されてる

see BackPlug.io ⇒

Page 14: 実践Backbone.Marionette 現場の悩みと解決まで

BackboneとDataBindings

Angularのウリの1つ = DataBindings⇒Backboneもplugin追加すれば動く

● NYTimesのBackbone.stickit

● 使い方は超簡単!

Page 15: 実践Backbone.Marionette 現場の悩みと解決まで

Backbone.stickit

Viewの中で

1. 紐づけたいセレクタとmodel属性名を定義2. $el描写後にstickit()

⇒すげー簡単!form使うなら盲目的に使うべき

⇒他、Backbone単体の問題はPluginで補える

Page 16: 実践Backbone.Marionette 現場の悩みと解決まで

Backbone単体の問題

● BoilerPlateばっかり○ 多くはMarionette.jsのViewクラスで解決

● 俺俺実装でカオス○ これもMarionette.jsのController/Region等で解決

Page 17: 実践Backbone.Marionette 現場の悩みと解決まで

Marionette.jsとは?

Marionette.jsはBackboneをwrapしたframework⇒以前slideにまとめた

細かい説明は、そちらを見て※次の章に行く迄に上の slideをチラ見しておくと良いかと。。

⇒特にView周りで

頻繁に書く所をカバーしてくれる

Page 18: 実践Backbone.Marionette 現場の悩みと解決まで

Marionette.jsは必要か?

● Yes!○ Backbone使うなら絶対オススメ

● 以前blogに書いたがBackbone書いてると同じ様なrenderやView構成に何度も出くわす○ それをMarionette.jsが共通化してくれる○ 小規模でも使うと楽になる

Page 19: 実践Backbone.Marionette 現場の悩みと解決まで

Backbone単体の問題の続き

● Testし辛い○ これはsinon.jsのテストダブルで解決

■ sinon.jsもblog記事書いたので良ければ。○ ⇒これらで、ある程度は、楽になるはず

■ ただ、この辺りはやっぱりAngularが強い

これらでBackboneの諸問題は回避可能

⇒Angularの問題は?

Page 20: 実践Backbone.Marionette 現場の悩みと解決まで

Angularの問題

● 学習コストかかる○ GoogleTrendsでAngular高い=調べ物多い(のが要因の1つ)

○ Backboneはsource grepで解決(simple素晴らしい!)

● ベンダーロックインに近い状態になる○ client側の動きや各componentが非常に独特

■ これ勉強してもAngularだけでしか活かせない■ なんか某Mの.n●tみたいだ...

● 空気のようなAngularWay○ まだまだBestPracticeが定まってない感○ 今後、WebComponent化すると更にまた変わる?

Page 21: 実践Backbone.Marionette 現場の悩みと解決まで

AngularとBackboneの大人のつきあい方

● 個人Lv : Angularは監視/学習し続けるとして● 現場Lv : まだBackboneで良いのでは?

○ ※で、AngularはWebComponent繋がって、情報整理さ

れた頃使えばいいんじゃねーの

● 大分枯れてきてる● 情報も豊富(無料で一通り手に入る)⇒現実解としてBackbone!

Page 22: 実践Backbone.Marionette 現場の悩みと解決まで

ここ1年位のBackbone関係の話題

思いつく限り

● 海外○ 2013年もカンファあった。Maionetteも出てくる○ Airbnbがサーバサイドで動くrendr作った○ addyさんの素晴らしい書籍も出た

● 国内○ 春に、多分単独で初めて?書籍も出た○ C社さんがBackbone baseの独自FW作った

等、まだまだ現役。まだ終わってはいない。

⇒「老害 Backbone」でつぶやかないように。

Page 23: 実践Backbone.Marionette 現場の悩みと解決まで

という事で...

今年も皆Backboneやろうぜ!

⇒今から現場でBackbone入れた話をする

Page 24: 実践Backbone.Marionette 現場の悩みと解決まで

今日の話の前提条件

「普通の」rails3アプリに適用した話

● SinglePageAppliでない● ちなみに、turbolinksも使ってない

⇒前提違うと、

構成や注意点等大分違うと思うのでご注意を

※なお、rails固有の話もしません。

Page 25: 実践Backbone.Marionette 現場の悩みと解決まで

設計編

Page 26: 実践Backbone.Marionette 現場の悩みと解決まで

どう設計?

Backbone使う前提

⇒気軽にajax/Event追加

⇒設計の可能性が広がる。

同時に、色々悩みが出て来る

Page 27: 実践Backbone.Marionette 現場の悩みと解決まで

Q:htmlは全部Backbone.Viewにする?

⇒No

SPAでも無いので、

いつも通りServerSideのViewを9割使ってる

DHHが昔disったダブルMVC!

● ServerSideのViewにメリットある○ 値の連携○ FWのhelper等

Page 28: 実践Backbone.Marionette 現場の悩みと解決まで

Q:では、どこにBackbone.View?

A:jsが必要になる以下の時に書いてる

普通のWebアプリでよくあるパターン

● ①Eventキャッチ用View● ②ajax通信が必要なView

○ A:単一リソース○ B:複数リソース

■ 1:単純な親子■ 2:単純な親子+親戚

⇒大体、このどれかに落ち着く※要するに普段 js書いてるのを整理してるだけ

Page 29: 実践Backbone.Marionette 現場の悩みと解決まで

Q:①Eventキャッチ用Viewとは

殆どのjs処理がコレ。

例)#menuをclickしたらdiv.menu表示みたいな

● なぜ、これもBackboneで書くのか?○ Backbone無いと、bindしてるDOMと処理内容がバラバ

ラで読み辛い。テストもし辛い(=習慣化しない)■ 昔blogに書いたが、jQueryダラダラ書いて長くteam

開発して量も増えるとゴミコード溜まるし、管理できな

くなってくる

Page 30: 実践Backbone.Marionette 現場の悩みと解決まで

Q:Eventキャッチ用Viewはどれ使う?

⇒Marionette.Viewがオススメ

理由:uiがあるから

● ui○ selectorを一カ所にまとめて、bindしてjQueryObjに

■ (後述するがこれがテストで重要)○ 使う時、bindUIElements()忘れずに

■ ※ちなみに、ItemView継承してるclassは不要

● なお、htmlについて○ render()書かず、ServerSideのViewを元にしてる

○ もし、render()必要ならItemView使おう(自力でrender書かない事)

Page 31: 実践Backbone.Marionette 現場の悩みと解決まで

Q:②ajax通信が必要なViewとは?

MarionetteのViewを使い分ける

● A:単一リソース○ Marionette.ItemViewを使うと良いよ

● B:複数リソース○ 1:単純な親子

■ Marionette.CollectionView使うと良いよ○ 2:単純な親子+親戚

■ Marionette.CompositeView使うと良いよ

Page 32: 実践Backbone.Marionette 現場の悩みと解決まで

Q:複数リソースのViewとは

Backboneで複数data取得/表示する

situationが非常に多い!

例)検索して結果一覧表示

⇒ここで親子にView分割する

● なぜ親子分割が必要か?○ Blogにも書いた通り○ 分割しないと

■ MとVの紐付けが毎回必要■ 冗長なクラス/htmlになる

子View

子View

子View

子View

親View

※ただのイメージ図です

Page 33: 実践Backbone.Marionette 現場の悩みと解決まで

親子ViewとMarionette.js

Marionetteで親子View用のclassが準備されてる

● 親View○ CollectionViewか○ CompositeViewのいずれか。

● 子View○ ItemView

Page 34: 実践Backbone.Marionette 現場の悩みと解決まで

Q:2種類の親Viewをどう使い分ける?

⇒親戚要素(仮)がいるかどうか

● 親戚要素(仮)とは○ 親子に働きかける別の要素○ 俺以外誰も使わないので(仮)を付けてる

要素のActionを起点として

親子呼び出すSituation多い

● 例)検索box/tab等⇒この時、CompositeView使う

これで親子と親戚の連携がスッキリ!

子View

子View

子View

子View

親要素

※ただのイメージ図です

親戚要素(仮)

CompositeView

Page 35: 実践Backbone.Marionette 現場の悩みと解決まで

2種類の親Viewを整理する

● CollectionView○ 単純に親子階層だけ必要な時に使う

● CompositeView:親にTemplate使える○ 親子要素と、

○ その親子要素に働きかける別の要素(親戚要素(仮))が必要な時に使う

Page 36: 実践Backbone.Marionette 現場の悩みと解決まで

Q:component構成は?

⇒Backbone MV* in MVC model2っぽい構成

AppRouter

Controller

Region

html

View

Template

Model/Collection

生成

event描写

連携event表示

event

監視

元々のBackboneの基本的なMV*構成

Page 37: 実践Backbone.Marionette 現場の悩みと解決まで

意図している所

Controller一カ所見ればhtml上でのレイアウト構成と処理概要が分かるようにしたい

● ①レイアウト構成○ Region使ってる

● ②処理概要:Controller○ Marionette.Controller使ってる

Page 38: 実践Backbone.Marionette 現場の悩みと解決まで

①レイアウト構成:Region

DOM要素とViewを紐付け表示管理するclass。● ItemView継承してる

○ show()でそのまま使う

● ItemView継承してない○ attachView()で強制的に紐づけてる

⇒どのViewも必ずRegionと紐づける事で、

後でsrc辿る時にどこに何があるか分かり易い

● Regionからel貰うのでView内部でel持たない○ これは、テストの為にもそうしてる(後述)

Page 39: 実践Backbone.Marionette 現場の悩みと解決まで

②処理概要:Controller

Marionette.Controller使ってる

● Controllerの関数に書く事○ 宣言的な所

■ A)Regionの定義

○ 命令的な所■ B)Viewの連携Event

Page 40: 実践Backbone.Marionette 現場の悩みと解決まで

A)Controller内のRegion管理

⇒基本ApplicationのRegionに追加

(Layoutを使ってない)

● いつかFatControllerになったら、○ Region管理してる所(宣言的な所)をLayoutに外出しし

ようと思ってる○ が、直近困ってない

Page 41: 実践Backbone.Marionette 現場の悩みと解決まで

B)Controller内のView連携Eventとは

あるViewのイベントをきっかけに、

別のViewの要素を変える時のイベント

● あえて、Controller挟んでる○ ⇒ControllerでどのViewがどう連携してるか分かる○ View内に書くと処理全貌が掴み辛いので避けてる

● ちなみに、主にMarionetteのcmd使ってる

View A View B

Controller

Page 42: 実践Backbone.Marionette 現場の悩みと解決まで

Q:なぜControllerに寄せてる?

⇒Controllerの単位で処理切替るから

● ちなみにこれがSPAなら...○ App.jsみたいなのがglobalな連携event持って

○ Controllerはview小片call程度のThinなcontrollerにな

るんだろうなぁ

● 比較的fat気味なControllerにしてるのは○ 普通のwebアプリの延長で作った場合

■ 連携eventはControllerの単位で変わるから■ 連携eventがControllerまたぐ事ないから

⇒この辺りは、状況に応じてCaseByCase

Page 43: 実践Backbone.Marionette 現場の悩みと解決まで

実装編

Page 44: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneの実装といえば

オレオレ実装でしょ!

Page 45: 実践Backbone.Marionette 現場の悩みと解決まで

オレオレ実装とは

特にBackbone.View周辺で見られる

● オレオレ自由系render() !○ view毎バラバラでカオスなrender()記述

● オレオレ深層SubView構成!○ 深くまで辿らないと全貌が分からない

● オレオレスパゲティdata bindings!○ 1Viewが複数のModelに複雑にbindしてる

等々・・・

Page 46: 実践Backbone.Marionette 現場の悩みと解決まで

オレオレ実装との戦い

Backboneで書いたのにsource追えない

何の為にコレ入れたんだっけ?

はい、しゅーりょー

^o^/これは、どうにかしないと...

Page 47: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneに素直に従う

与えられた物をその範囲内で素直に使う事で

絡まる事無くsimpleでtestableな状態に!

● Backbone.Viewが用意してくれる事● Marionetteが用意してくれる事● stickitが用意してくれる事

Page 48: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneが用意してくれる事

● $el○ Viewは$el内のDOM要素だけを扱う○ globalな$使って外の要素を勝手に変えない

■ やりたければさっきの連携eventをtrigger● Model/Collection

○ 1Viewは1Modelか1Collectionだけと紐づく○ オレオレModel/Collection作らない

■ 連携が必要なら、同じく連携event使う

● render()○ 画面描写はrenderで行うのであって、initialize等別の関

数で画面描写するべきでない■ initializeに書くと画面描写とそれ以外が混合><

Page 49: 実践Backbone.Marionette 現場の悩みと解決まで

Marionetteが用意してくれる事

● render()○ 自分でrender書かないで、カオスを回避○ Template準備して、誰かと作業し易く

● ui○ ui経由でjQuery objとって冗長さを避ける

● Event系○ 与えられたEventに処理を追加していく

● 親子View○ Collection/CompositeView + Region管理でカバー

○ 可能な限り自力でsubview書かない(Backboneに準備

されてないし)

Page 50: 実践Backbone.Marionette 現場の悩みと解決まで

大原則

当たり前の事だけど、

これらに沿うだけで大分違う。

※勿論、例外はあるが。

基本的に、

与えられた物を素直に使う事に徹する

のがオススメ

Page 51: 実践Backbone.Marionette 現場の悩みと解決まで

Q:ぱっと見でViewの動きが掴めない

⇒関数名にevent入れる規約にする

● event関数名 = on + イベント名 + 対象○ 例)onClickSaveButton / onSyncModel

● これでevents一々見なくても流れが掴める○ Backbone.View関数名で動作を説明する必要は無い

■ (特にMarionette入れた)Backboneはviewの関数の

行数が少なくsrc見れば動きがすぐ分かるし○ そもそも他のevent駆動programも同じ発想

■ iOS/VB等々..○ 勿論event関数から呼ぶ別の関数は普通に名前付け(こ

れでevent駆動の関数とそれ以外で分かれる)

Page 52: 実践Backbone.Marionette 現場の悩みと解決まで

Q:view内の関数同士の関係がカオス

⇒関数同士の継ぎ目になるstatusを区別する

status?● 関数横断して相互利用する要素があった時

○ 例えば、tab/modal/load anime等○ testでbuggyなのは、この辺り!

○ そのままjQuery操作すると(特にsrcが長くなった時)独立

した表示要素の操作と区別がつかなくなって、埋もれて

しまう○ これはtestする上で致命的(追加改修時も大変)

⇒statusは変数として外出して変更箇所を統一

Page 53: 実践Backbone.Marionette 現場の悩みと解決まで

Q: statusどう管理する?

⇒methodにstatus/画面操作を統一で妥協

結局、どこまでやり過ぎるかのせめぎ合い

● デザパタState pattern○ ⇒Backbone.ViewのSubview構成に行き着く

● Backbone.Events継承● pluginもやっぱりある(がっつり系 / 簡易系)

⇒いずれにせよ、冗長になるが○ Viewがstatus持ってる事を明示出来る○ testや追加時に、status確認する起点が出来る

Page 54: 実践Backbone.Marionette 現場の悩みと解決まで

Q:変な動きするんだけど

⇒ソースgrepが早くて一番正確。

● BackboneもMarionetteもstickitも全部● どれもそんなに長くなくてsimple

○ 例えば、Backbone.Viewはたった百行前後しかない

ソース辿れるとどうにかなる。

simpleって素晴らしいですね!

ここがBackboneの良い所!

Page 55: 実践Backbone.Marionette 現場の悩みと解決まで

Q:書いてて不安になるんだけど

⇒分かる。だから、TDD必須

● 実装からBrowser表示まで時間かかる事ある○ こまめにTestFirstでjs levelの動作確認が必要

● しかし、生でtestは限界がある。● 結局、幾つかの慣例表現を知らないと

backboneのtest書けないので次に扱う○ ※今日はTestとTDDまとめて話すが、blogに書いた通り

厳密には違う。これも知らないと、どう書くか悩む事にな

るので、良ければ読んで頂ければ。今日はこの違いの

話はしない。

Page 56: 実践Backbone.Marionette 現場の悩みと解決まで

テスト編

Page 57: 実践Backbone.Marionette 現場の悩みと解決まで

jsのTest Frameworkざっくり流れ

● 数年前

● 2年前

● 去年

⇒コロコロ主流が

変わってきましたね

Page 58: 実践Backbone.Marionette 現場の悩みと解決まで

Q:Test Frameworkどれがいい?

● ちょっと前迄、mochaでいいと思ってた○ mocha使う=chai使う=language chainが気持ち悪い

○ chai以外にどのassertionLibに落ち着けばいいか謎。

(それぞれメリデメと、流行/廃りがある)

⇒最近、個人的にjasmineでいい気がしてきた

Page 59: 実践Backbone.Marionette 現場の悩みと解決まで

jasmine

● jasmine2が出てdone(非同期test機能)付いた● 呼出し口が固定されてる(当たり前だけど)

○ ※jasmineのspy周りは、機能詰め過ぎ/関数名長過ぎで

気持ち悪いので、sinon(後述)使ってる

● 調べるときも公式pageだけで完結● 2013DailyJSアンケートでも、まだ1位

⇒simple素晴らしい

jasmine + sinonでいいんじゃない?

Page 60: 実践Backbone.Marionette 現場の悩みと解決まで

BackboneとTest

BackboneのTestはFrontEnd特有の問題がある

● ①jsがDOM/htmlに依存してる問題● ②素直に検証書けない問題

これらの解決策を知らないとかなり悩む事に!

Page 61: 実践Backbone.Marionette 現場の悩みと解決まで

①jsがDOM/html依存してる問題

● 頻発するデザイン変更の度にtest修正が必要○ test修正自体正しい事だが量が多い点が問題><

● DOM調整作業やってるとTDDし辛い○ DOM調整でhtml注力すると開発flowにTest入らない

● target/testの2つだけで完結しない(htmlがある)のでTDDに集中できない○ ServerSideではtargetとtestの2つだけで恵まれてた

Page 62: 実践Backbone.Marionette 現場の悩みと解決まで

TDD進める為に

● ゴール○ ServerSideのTDDの様にTest/Targetだけの行き来に

する

● 方向性○ DOM/htmlの分離

■ 勿論、完全分離は不可能だが、距離をあける○ jsを書く事と、DOM調整作業を分ける

※ちなみに、テストから完全にDOM排除せよという話ではない。違う形で確認は必要。

Page 63: 実践Backbone.Marionette 現場の悩みと解決まで

BackboneでのDOM/html分離

● DOMselector書かずMarionette. View.ui使う○ TestCodeから要素掴むのもview.ui使う○ targetもtestも中身が絡まるのをおさえる○ 変更時の修正の起点を作る

● test用templateを基本的に作らない○ 変更時の修正costを下げるため○ htmlは本物のfileだけ。

● Viewは$elの範囲内だけ扱う相対View作る○ test用template書かずに済む

○ htmlに無いので表示検証が難しいが、逆にそれでDOM分離(logic検証spyでも可。jQuery関数自体を検証して

も意味ない)

Page 64: 実践Backbone.Marionette 現場の悩みと解決まで

②素直に検証書けない問題

● instance変数の変更等は普通に検証書けるが● event/server通信はそのまま書けない

⇒後者の対応の為に結局TestDoubleが必要

Page 65: 実践Backbone.Marionette 現場の悩みと解決まで

テストダブルとは

テスト対象が別コンポーネントに依存しており

この別コンポーネントの為テストが困難な時に

別コンポーネントを置換/監視する仕組み。

spy/stub/mock等がある。

テスト対象Backbone等

テストコードmocha等

別のコンポーネント

置換/監視

Page 66: 実践Backbone.Marionette 現場の悩みと解決まで

spy/stub/mockざっくり解説

● spy○ ある関数の入出力を監視

● stub○ ある関数の戻り値を改ざん

● mock○ 検証作業自体をobject化

Page 67: 実践Backbone.Marionette 現場の悩みと解決まで

Q:jsでどうやってTestDouble?

⇒sinon.jsがある

● spy/stub/mockに加え、fakeTimerやfakeServer等非常に便利

● ※jasmineにもあるが、前述の通り、機能詰め過ぎと関数名長過ぎでオススメしない

Page 68: 実践Backbone.Marionette 現場の悩みと解決まで

Q:いつTestDouble?

⇒主に、以下

● イベントトリガー● サーバー通信● アニメ● localなinstance

Page 69: 実践Backbone.Marionette 現場の悩みと解決まで

イベントトリガー例

Event掴む為にTestDouble● spyを作ってイベントにbindしておく● spyが呼ばれたか確認

※view.model等も一緒

※ちなみに、bindは_event確認すると良い

Page 70: 実践Backbone.Marionette 現場の悩みと解決まで

サーバー通信

● TestDouble無しでそのまま書くと○ テスト検証非同期callback深くなる○ Serverside経由する分、testの時間もかかる○ POST/PUTの検証にtest用GET自作する必要あり○ 問題有ったときの原因の切り分け面倒

⇒これら回避するためサーバ通信もTestDouble

Page 71: 実践Backbone.Marionette 現場の悩みと解決まで

Q:サーバー通信どこでTestDouble?

どこにTestDouble張るかは色々やり方がある

● 1.元の口にTestDouble○ $.ajaxやsyncメソッド等

● 2.xhr自体をTestDouble○ sinon.createFakeServer()でxhr自体wrapする○ stubとしては最も正しい姿だが設定面倒くさい

● 3.個別のメソッドにTestDouble○ model.save等

現実的に3が多い気がする

Page 72: 実践Backbone.Marionette 現場の悩みと解決まで

個別メソッドにTestDouble例

● 普通にspyしてlogicの検証してもいいし● fetch等はstubで仮のデータを返すのも有り

○ yieldsTo使うと、success/error等も叩ける

Page 73: 実践Backbone.Marionette 現場の悩みと解決まで

アニメ

普通に書くとテストで数秒待ちする必要

⇒sinon.fakeTimer使うと、すぐ終わる

Page 74: 実践Backbone.Marionette 現場の悩みと解決まで

localなinstanceのcheck

ある関数の中でModelのinstance作って、save等する時、普通にやると掴めない

⇒TestDouble(Mock)

● Model.prototypeにmockかける● sinonのstub

○ sinonはstubも検証できるobjなので、stubでも書けてし

まうが、Testのcontextでは無い所での検証なのでmockの方が正しい。(主体となる視点の違い)

Page 75: 実践Backbone.Marionette 現場の悩みと解決まで

localなinstanceの例

こんな感じ

Page 76: 実践Backbone.Marionette 現場の悩みと解決まで

テストダブルの注意

stub/mock等使うと実際の動きと異なる

⇒stub等経由しないテストが必要

● ※必ずしも全自動化の必要は無いと思うが

Page 77: 実践Backbone.Marionette 現場の悩みと解決まで

Q:sinonつらい

⇒分かる。

ServerSide他言語のtest書いてて、こんなにTestDouble頻繁に書かないし。ありえない。

● cursor戻して逐一before書くのが苦痛○ stubは必要なのは分かる。処理異なるし。○ 問題はspy周り。普通にそのままevent等確認したい

⇒Viewの全部にまとめてspyできねーか?と今plugin作ってみてる。良ければ。

Page 78: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneのbug

BackboneのViewの関数は

(特にMarionetteと一緒に使うと)行も少ないsimpleな物になる。

⇒1関数LVの挙動でbug入り込む余地が少ない

それより、event駆動に起因するbugが多い

Page 79: 実践Backbone.Marionette 現場の悩みと解決まで

event駆動

● FrontEnd ≒ event駆動○ 関数はeventに応じて実行(順番通りの部分もあるが)○ 例

■ 開発:関数A ⇒ 関数B ⇒ 関数Cを意図■ 実際:関数A ⇒ click ⇒ 関数C ⇒ click ⇒ 関数B

⇒意図しない関数の組み合わせがあり得る

● 独立している関数は意識しなくていいが● 独立していない関数は注意が必要

Page 80: 実践Backbone.Marionette 現場の悩みと解決まで

独立していない関数とは、例えば。

● statusに依存している/影響与える関数○ これは、先程の話○ 思わぬ前提条件statusの違いや思わぬstatus影響等

● 非同期処理を伴う関数 ○ 処理中に別の関数あると影響与える?与えない?等○ これも結局、上と同じstatusの話に行き着く

⇒これらの関数を中心に、

別の関数との相互作用を重点的にTestする

Page 81: 実践Backbone.Marionette 現場の悩みと解決まで

まとめ

● 設計編○ 親子ViewはCollection/CompositeViewを使う○ Controllerに処理寄せる(not SPAならね)

● 実装編○ Backbone/Marionetteに素直に作る○ status外出し

● テスト編○ jsのテストとDOMを分ける○ テストダブルを使う○ 独立してない関数に注意

Page 82: 実践Backbone.Marionette 現場の悩みと解決まで

Backboneの悩みを解決できた?

オレオレ実装/設計から逃れられそう?

Page 83: 実践Backbone.Marionette 現場の悩みと解決まで

これでBackboneに絶望する人を

少しでも救えたら幸い

(皆で渡れば怖くない。

まだ老害になりたくない。

今年もBackboneでしょ!)

Page 84: 実践Backbone.Marionette 現場の悩みと解決まで

Q:今日の内容もお前のオレオレだろ?

そうですね。

書いてて思った。

Page 85: 実践Backbone.Marionette 現場の悩みと解決まで

俺のオレオレと、

お前のオレオレと...新しい宇宙と......

Page 86: 実践Backbone.Marionette 現場の悩みと解決まで

なに言ってんの?(゚д゚ )

Page 87: 実践Backbone.Marionette 現場の悩みと解決まで

オレオレとの付き合い方

Marionetteやstickitみたいなpluginにして

● オレオレをルールにしなければ。● 人に同意されなければ。

という事で、Backbone周辺libraryを皆で色々作っていこう!

おわり

Page 89: 実践Backbone.Marionette 現場の悩みと解決まで

Blogもやってる

● 今日の内容も殆どここから○ いつも酒飲みながらダラダラ書いてる○ 今日言葉足りなかった所は是非読んで頂けると幸い○ 「はてぶくれ!」

http://lxyuma.hatenablog.com/

Page 90: 実践Backbone.Marionette 現場の悩みと解決まで

Presented By ...