できるだけ楽ちんにCoffeeScriptだけでサーバとVue.jsを試す


できるだけ楽ちんにCoffeeScriptだけでサーバとVue.jsを試す

久々にフロントエンドでUIをいろいろ試したくなり、Vue.jsを、JadeとCoffeeScriptで触ってみました。

Vue.jsは、AngularJSから双方向データバインディングだけ切り出したようなライブラリで、学習コストが低い割に使い勝手がよく、AngularJSの学習の入り口としてもいいらしいです。(AngularJSは2.0でごっそり変わるみたいだし、賛否両論だし、まだいいかな…)

方針

  • できるだけ楽したいので、JavaScriptもHTMLも書きません。 代わりにCoffeeScriptとJadeで書きます。かっこ閉じとか面倒ですよね。 (ただし、ブラウザのDeveloper Toolでデバッグするので、 JavaScriptもHTMLも、ある程度読める必要はあります)
  • CSSも書きません。が、Bootstrapで楽して見た目はそれなりに…
  • さくっと試したいので、gulpでコンパイルとかもしません。 Vue.js, Bootstrap, jQueryは、CDNから直接ロードします。

ハマるところが少ないよう、できるだけシンプルな構成にしているので、
いろいろ書き換えながら勉強するのに向いてると思います。

この例では、サーバでAWSのインスタンス一覧を取得してキャッシュしておき、
フロントエンドでそれを取得して、インタラクティブにフィルタリングしています。

フロントエンド側

Jadeは、Node.jsでよく使われるHTMLのテンプレートエンジンで、
CoffeScriptやYAML等と同様、インデントの深さでHTMLタグの階層構造を記述します。
classは.、idは#と、CSS的に書ける上に、
divだとタグ名も省略できたり、かなり読みやすくなります。

title= titleとかは、Jadeのテンプレートの機能で、サーバ側でレンダリングされます。
v-textとか{{}}は、Vueによる拡張で、クライアント側でバインドされ、レンダリングされたりします。

views/index.jade
doctype html
html
  head
    meta(charset='utf-8')
    title= title
    link(rel='stylesheet',href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css')
    script(src='https://cdnjs.cloudflare.com/ajax/libs/vue/0.11.5/vue.min.js')
    script(src='http://code.jquery.com/jquery-2.1.3.min.js')
  body
    .container
      .masthead
        h1.text-muted= title
    #demo.container
      form.form-inline(role='form')
        input.form-control(v-model='searchText')
      div.text-muted(v-text='message')
      .table-responsive
        table.table.table-striped
          thead
            tr
              th Name
              th InstanceType
              th State
              th InstanceId
              th PrivateIpAddress
              th PublicIpAddress
          tbody
            tr(v-repeat='instances | filterBy searchText | orderBy field')
              td {{name}}
              td {{InstanceType}}
              td {{State.Name}}
              td {{InstanceId}}
              td {{PrivateIpAddress}}
              td {{PublicIpAddress}}
    .container
      .footer
        p © Copyright kaz080, 2015

    script
      :coffee
        vm = new Vue
          el: '#demo'
          data:
            instances: []
            field: 'name'
            message: ''
        $.getJSON '/instances', (res) ->
          console.log JSON.stringify res, 0, 2
          for i in res
            continue unless i.Tags
            i.name = tag.Value for tag in i.Tags when tag.Key == 'Name'
          vm.$data.instances = res
          vm.$data.message = "Total #{res.length} instances"

    script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js')

サーバ側

CoffeeScriptも、インデントで階層構造を表現することで{}を省略できたり、
引数の()を省略できたりと、JavaScriptの冗長な記述を不要にしてくれます。
(-> だけでfunctionが書けたり、arrayやloop処理などもめちゃくちゃ楽です)

app.coffee
express = require 'express'
http = require 'http'
aws = require 'aws-sdk'

app = express()
server = http.createServer app

app.set 'port', process.env.PORT || 3000
app.use express.static __dirname + '/public'
app.set 'views', __dirname + '/views'
app.set 'view engine', 'jade'

debug = (message) ->
  console.log message

# Configure libraries
process.env.AWS_PROFILE = process.env.AWS_DEFAULT_PROFILE
aws.config.update region: 'us-west-2'
ec2 = new aws.EC2()

# Start server
server.listen app.get 'port'
debug 'Start listening.'

# get HTML
app.get '/', (req, res) ->
  res.render 'index', { title: 'Express, Jade, Bootstrap, Vue, jQuery' }

# get JSON
instances = null
app.get '/instances', (req, res) ->
  if instances
    res.json instances
    return
  ec2.describeInstances {}, (err, data) ->
    debug JSON.stringify err if err
    instances = (r.Instances[0] for r in data.Reservations)
    res.json instances

サーバを起動し、http://localhost:3000/ にアクセス。

npm install express coffee-script jade aws-sdk
coffee app.coffee

感想

  • やっぱりCoffeeScriptの方がRubyより楽ちんで速い
  • 簡潔で読みやすく見通しよく書けるのって大事