shimada-kの日記

ソフトウェア・エンジニアのブログです

Synthを試してみる

先日東京Node学園14時限目に参加してきました。そこで@pchwさんから紹介があったSynthを試してみました。試してみた分かったことを書いておきます。

SynthはSPA作成を念頭において設計されたWebフレームワークです。

Angular.jsでサイトを作成した場合、HTMLの基本構造だけロードして中のデータは後からレンダリングされます。それだと検索エンジンフレンドリーではないというのと、APIロード完了までに空のdivやtableが表示されてしまってしまうという課題があったので、その課題に対するアプローチの1つということです。

Synthを使用しない(Angular.jsだけで実装した)場合と使用した場合のソースをさらしておきます。ちょくちょく出てくるRGBというプリフィックスやgridといったワードはプライベートプロジェクト由来のものなので特に他意はありません。

Synthを使用しない場合

テンプレート

<html ng-app>
    <head>
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
        <script src="angular.min.js"></script>
        <script src="05.js"></script>
    </head>
    <body ng-controller="RgbController">
        <table class="table">
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Platform</th>
                <th>Comment</th>
                <th>IsCold</th>
            </tr>
            <tr ng-repeat="rgb in rgbjson">
                <td>{{rgb.id}}</td>
                <td>{{rgb.name}}</td>
                <td>{{rgb.platform}}</td>
                <td>{{rgb.comment}}</td>
                <td>{{rgb.is_cold}}</td>
            </tr>
        </table>
    </body>
</html>

コントローラー側です。

function RgbController($scope, $http, $timeout) {
    var uri = 'http://192.168.3.2/rgb/rgb.json';
    var param = {num: 200};

    $http.get(uri, param)
         .success(function(data, status, headers, config) {
             log('success', data, status, headers, config);
         })
         .error(function(data, status, headers, config) {
             log('error', data, status, headers, config);
         });

    // jsonを表示する
    function log(type, data, status, headers, config) {
        // delay
        $timeout(function(){
                    $scope.rgbjson = data;
                    }, 5000);
        //$scope.rgbjson = data;
    }
}

Synthを使用した場合

サーバ側。チュートリアルのコードをベースにしています。Promiseオブジェクトを返す必要があるのでmysql-promiseをnpm installしました。

back/resources/rgb/getRgb.js

exports.getIndex = function (req, res) {

    req.db.configure({
        "host": "localhost",
        "user": "xxxx",
        "password": "xxxxxxxx",
        "database": "rgb"
    }); 

    return req.db.query('SELECT * FROM grid_image').then(function (rows) {
        console.log(rows[0]);
        return { data:rows };
    }); 
};

クライアント側。コントローラーから

front/controller/rgb.js

angular.module('my_app')
.controller('rgbController', function ($scope, $http, data) {
    //console.log(data.data[0]);
    $scope.rgb_entries = data.data[0];
});

続いてビュー

front/html/rgb/getIndex.jade

ul.rgb-timeline
    li.grid(ng-repeat="entry in rgb_entries").content {{entry.id}} {{entry.name}} {{entry.comment}}

総括

私はVirtualBox仮想マシン上に環境を作りましたが、ファイルサイズがデフォルトの8GBだとチュートリアルで使用するmongodbにデータを作るgenerateTeweet.jsがディスク容量不足で失敗しました。VMで試す場合はディスクサイズを余裕を持った値にしておくと詰まずに済みます。ちなみにVMのファイルサイズの変更はこちらを参考に行いました。

preloadを試すときはAPIの返り値をPromiseオブジェクトにしないといけませんが、現時点(2014年8月24日)で公式サイトで提供しているNodeはv0.10なのでPromiseをサポートしていません。

ならばと思いgithubのmasterブランチにのっているものをビルドすると-preが付いているバージョンはnode-sassモジュールをインストールできないと怒られ、Synthサーバを起動できませんでした。Promiseが公式にサポートされる(であろう)Node v0.12のリリースを待ちましょう。

Synthサーバを立ち上げている時にサーバ側のコードを変更すると変更を検知して自動でサーバを再起動してくれるのはうれしいです。

普段Expressを使っていて、ライアントサイドとサーバサイドのコードがごっちゃになっているのはいかがなものかと思っていたのでfront/とback/でディレクトリが明確に別れている構成は好感が持てます。