LINE株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。 LINEヤフー Tech Blog

Blog


Backbone.js gives structure to web app

こんにちは、開発1室UITチーム 清水@tori3_jpです。

さて、今回はLINEのスマートタブレット向けブラウザ版でも採用したJavaScriptのMVC FrameworkであるBackbone.jsについて紹介したいと思います。

この数年でブラウザの高速化やHTML5の機能の実装が進むにつれHTML/CSS/JavaScriptでよりネイティブアプリケーションに近い表現がブラウザ上で可能になりつつあり、それにともない開発はより複雑になってきています。

jQuery pluginなど使えば短いコードで様々な機能を手軽に実装できますが、規模が大きくなるにつれcallbackが増え、徐々に見通しの悪いコードになりがちです。また、DOMとデータの分離が難しくなることも問題となってきます。

そこで、Javaなどで広く使われているデザインパターンの1つであるMVCパターンで構造化された設計をとりいれることで問題をある程度解決できます。

構造化されることで以下のようなメリットが考えられます。

  1. モジュール同士の独立性が高まる = 保守性が高まる
  2. ユニットテストの実装が容易になる =  品質が高まる

Backbone.jsとは

DocumetCloud IncJeremy Ashkenas氏によって開発されMIT Licenseのもと公開されています。Jeremy氏はcoffeescript, underscore.jsの開発者としても有名です。

Backbone.jsを構成する主な要素とMVCとの関連は下のようになります。

Model = Backbone.Model,Backbone.Collection
View + Controller = Backbone.View, Backbone.Router

?と思われるかもしれませんが、Javaなどで使われているMVCとは異なります。
How does Backbone relate to "traditional" MVC?

Backbone.View, Backbone.RouterがControllerとViewの両方の役割を兼ねています。

通常のMVCではControllerによってView,Modelが連携しますがBackbone.Viewでは直接Modelのイベントに反応してViewをControlします。
Backbone.RouterはURLパターンとメソッドをマッピングする役割とControllerの機能を兼ねます。

/**
* BackBone.View sample
*/
App.view.itemList = Backbone.View.extend({
    el: '#list',
    initialize: function() {
        // viewは自身が持つmodel(collection)のeventにbind
        this.model.on("add", this.add, this);
    },

    /**
    * modelのeventをtriggerにしてviewを更新する
    */
    add: function(model) {
        var item = new App.view.item({
            model: model
        });
        this.$el.append(item.render().el);
    }
});

以下のような特徴があります。

RESTful JSON

Backbone.jsではModel(Collection)のメソッド(save, destroy, fetch)から透過的にCRUDを実装したBackbone.syncが実行され、REST API(with JSON)がcallされる仕組みが用意されています。そのためREST形式のサーバー通信の実装を簡単に行うことができます。

また、Backbone.syncをoverrideすることで、websocketやLocal Storageを使った実装に変更することも可能です。

LightWeight

Backbone.js自身にはDOM操作、XHRなどの機能は提供しないため、それらの機能は他のライブラリに依存していますが、最小構成で18KBと軽量です。 (Zepto.jsのサポートブラウザの範囲という構成でjson2.jsを除外した場合です)

  • jQuery or Zepto.js
  • underscore.js
  • json2.js

Backbone.js(5.6KB) + underscore.js(4KB) + Zepto.js (8.4KB)   = 18KB(minify and gziped)

Routing & HistoryManagement

Backbone.Routerはlocation.hashをもとにしたナビゲーションを実装しています。

また、Backbone.HistoryでHTML5 History APIを使ったHistory管理が可能です。History APIをサポートしていないブラウザに対しては自動でhashchangeやiframeを使った方法にフェイルオーバーされます。

var router = Backbone.Router.extend({
    routes: {
        "/back/:color": "back", // ex) #/back/black
        "/font/:color": "font"  // ex) #/font/red   
    },
    /**
    * http://hoge/#/back/blackのようなURLにマッチした場合に実行される
    */
    back: function(color) {
        $("body").css("background-color", color);
    },

    /**
    * http://hoge/#/font/blackのようなURLにマッチした場合に実行される
    */
    font: function(color) {
        $("h1").css("color", color);
    }
});

new router();
// back/foward時のHistory制御
Backbone.History.start({pushState: true});​​

今回紹介したBackbone.jsの他にも様々なMVC Frameworkは存在します。

また他にDojoやYUI, Sencha TouchなどフルスタックフレームワークでもMVCパターンを利用できるものもあます。それぞれ長所、短所がありますが、今回紹介したBackbone.jsは軽量でドキュメントも整理されている点などから、比較的導入しやすいフレームワークだと思うので、興味を持ちましたらぜひ使ってみてはいかがでしょうか。