Synthってなんじゃらほい？


# Synthってなんじゃらほい
Synthとは、node.js製のフロントエンドとバックエンドをラップしたライブラリです。
それぞれ、フロントエンドはbower
バックエンドはnpmをラップしています。
そのため、従来からあるモジュールをそのまま使用することができます。

現代はHTMLの構築はほとんどAngularJS等を使用してフロントエンドで描画することが多いです。
サーバーサイドは主にAPIの提供のみとなる事が多くなると、必然的にbowerfileが増えてきます。GulpやGruntを駆使してファイルをワケても、やっぱりサーバーサイドとクライアントサイドのコードが混ざり合って、ワケワカメになりがちでした。

そこで、BackとFrontの二種類のディレクトリで完全にファイルを独立させることでファイルの見通しを非常に良くするツールが登場しました。それがSynthです。

また、AngularJSの欠点であった、初回レンダリング時のデータの読み込みの遅さ
例えば、TwitterのTLを描画するとき、AngularJSがDOMの構築を完全に終わってからTLのデータをサーバーに問い合わせ始めるため、表示に無駄がありました。
様々な打開策があったのですが、どれもいまいちだったのですが、
その点に関してもpreloadを使用したアプローチが入っています。


# ファイル構成

```
.
├── back
│   └── package.jsonとかバックエンドのファイルはここ
└── front
    └── bower.jsonとかフロントエンドのファイルはすべてここに
```

# Tutorial
Synthはコマンドラインツールとexpressをラップしたフレームワークの二種類から成り立っています。

## Install a Synth
`$ npm install -g synth`


## create a new app
```
$ synth new my_app
```
これで`./myapp`に新規プロジェクトが構築されます。

```
$ cd my_app
```
Yoに慣れたあなたなら、安直に

```
$ npm install && bower install
```
とでもしたくなるでしょう。
でも待ってください。Synthには便利なツールがまだまだ用意されています。
(勿論、front, backに移動して自分でやっても良いです。しかし、後述の便利な機能が享受できないので、出来ればこちらをマスターしましょう。)

## サードパーティモジュールのインストール

```
$ synth install -b
$ synth install -f
```

引数の`-b`はback, `-f`はフロントエンドを指しています。

バックエンドのライブラリは`./back/node_modules`に入り
フロントエンドのライブラリは`./front/bower_components`に入ります。
いつもとディレクトリ構造が違うだけで、動作は全く同じです。

## 早速、動かしてみる
`$ sails lift`的な機能が用意されています。

```
$ synth s
```
これで初期状態では3000番portにlistenしたかと思います。
できなかったらMongoDBが入っていない可能性があります。ググって頑張って入れましょう。
ちなみに`synth server`でも同じです。

Production modeで実行する場合は

```
$ synth prod
```
で実行することもできます。

また、`-p 3004`等と引数を送ればポートの指定もできます。

## サンプルの動作確認
ページは開けましたか？
開けたら、もう一つコンソールを開いて

```
$ node back/generateTweets.js
```
とやってみましょう。

Tweetが追加されましたか？
動作が確認できれば、後はいつものExpressとAngularJSです。

# 3rd party製のライブラリを導入する
必ず、synthコマンドを使用して導入しましょう。

## npmなバックエンドのライブラリを導入
### socket.ioを導入する場合

```
$ npm install socket.io --save
```
とやりたい場合、

```
$ synth install -b socket.io
```
これで結果は同じになります。
少し特殊なフォルダ構成になっているため、このコマンドを活用しましょう。

## bowerなフロントエンドのライブラリを導入する
### jQueryを導入する場合
```
$ bower install jquery
```
とやりたい所ですが、必ず

```
$ synth install -f jquery
```
このコマンドを使用しましょう。
ある便利な機能が使用できなくなってしまいます。

# そんで、さっきから言っている"便利な機能"って何よ！
簡単に言うとrequire.js的なのが入ってます。
まだ詳細まで見ていないのでどうなっているのかわからないのですが、内部的にGulpが動いているようです。

具体的には`front/js/jsFiles`ですね。
こいつが実行時にスクリプトタグに変換されてHTMLに埋め込まれます。
require.jsと違ってHTMLに直接埋め込まれて鯖から送られてくるため、ちょっと早いです(たぶん)

また、cssも`front/css/cssFiles`があり、こちらも自動的に埋め込まれます。

# 他に利点は無いの？
## AltJSやSASSのオートビルド
特に前準備なしにCoffeeScriptやSASSを使用することができます。
バックエンドの場合はそのまま`.coffee`ファイルを配置して構いませんが、
フロントエンドはJSの場合、`jsFiles`に`.coffee`のままファイル名を記述してください。

同じくCSSも`cssFiles`に`.sass`なり`.scss`のまま記述すると、自動的に実行時にコンパイルしてくれます。

## 表示するデータのpreloadが簡単に書ける
AngularJS等のフロントエンドフレームワークの欠点であった、データの読み込みまでの遅さ。

従来はページにコンテンツが全て埋め込まれた状態のファイルをDOMに展開していたのですが、AngularJSは
テンプレートのHTMLを読み込み→DOMに描画→コンテンツを鯖から読み込み→DOMに描画
と、とても効率が悪くなりがちでありました。
その点に関してアプローチはいくつかあるのですが、Synthではpreloadといった変数を最初からHTML内に埋め込む手法をとっています。

### どんな感じになってるの？
`synth new my_app`した状態ですと、	`./back/resources/tweets/getTweets.js`
が該当するファイルです。

```CoffeeScript:getTweets.coffee
exports.getIndex = (req, res) ->
  req.db.collection("tweets")
        .find()
        .sort created_at: -1
        .limit 20
        .toArray()
        .then (tweets) ->
                  tweets: tweets

```
返り値にはobjectで
`{tweets: teets}`
が入っています。
次に、`./front/index.jade`を見てみましょう。

```Jade:index.jade
// Preloaded Data
script.
    var preloadedData = !{data};
```

となっている。これでユーザーには1コネクション分の時間だけ短くデータを提供することが出来る。

# 気になったバグ？仕様？
`$ synth server`を実行中にファイルが変更されると自動的に再起動して適応してくれるのだが、
`.coffee`なファイルはwatchされてない。かなしみ。

## 追記
やっぱり動かないのは不便なのでpull request送りました。
[Add to watch the CoffeeScript #58](https://github.com/JonAbrams/synth/pull/58)