会社のインターンでVue.jsを利用するんですが、去年も触ったけど、やっぱりちゃんとサンプルを動かしてみないといけないなと思って写経してみました。
サンプルはこちらのページを利用しました。
日本語ページ去年はなかった気がしますが、今は日本語で読めてとても楽です。
ところで、最近altJSというのが流行ってますね。
TypeScriptやCoffeeScript色々ありますね。
せっかくなので今回はScala.jsを使いました。
Scala.jsとは -> http://www.scala-js.org/
やっぱScalaは型があっていいですよね。
コンパイル時にコーヒー飲めるしすばらしい。
概要
この後の流れ
1. Vue.jsをScala.jsで使うための準備
2. マークダウンエディタサンプル写経
3. マークダウンエディタサンプルを動かしてみる
利用したライブラリたち
- Scala 2.11.5
- Vue.js 0.12.9
- Scalajs 0.6.4
1. Vue.jsをScala.jsで使うための準備
Scala.jsにjQueryのクラスなどは用意されていますが、それ以外は自前でインターフェイスを定義してあげる必要があります。
どうやればいいんだろうと思ってググっていたらこちらにたどり着きました。takezoe.hatenablog.com
Aceライブラリのインターフェイスの定義
scalajs-ace/Ace.scala at master · scalawarrior/scalajs-ace · GitHub
自前とかむりぽ
そこでscala-js-ts-importerです。
これはTypeScriptの型定義を元にScalaのコードに変換してくれるライブラリです。
Vue.jsの型定義ファイルはこちらにまとまっていたものを利用させていただきました。
$cd /path/to/scala-js-ts-importer $cp /path/to/DefinitelyTyped/path/to/vue.d.ts ./ $sbt 'run vue.d.ts Vue.scala'
これでVue.scalaができ・・・ない!
$sbt 'run vue.d.ts Vue.scala' [info] Loading project definition from /Users/a-tanaka/.ghq/github.com/sjrd/scala-js-ts-importer/project [info] Set current project to TypeScript importer for Scala.js (in build file:/Users/a-tanaka/.ghq/github.com/sjrd/scala-js-ts-importer/) [info] Running org.scalajs.tools.tsimporter.Main vue.d.ts Vue.scala Parse error at 166.1 ``interface'' expected but 'import' found import Vue = vuejs.Vue; ^ java.lang.RuntimeException: Nonzero exit code: 2 at scala.sys.package$.error(package.scala:27) [trace] Stack trace suppressed: run last compile:run for the full output. [error] (compile:run) Nonzero exit code: 2 [error] Total time: 3 s, completed 2015/08/07 20:50:31 # importがダメなようです # とりあえず消して動かすことにしました # これによってビルドされるVue.scalaのJSNameアノテーションも少し修正しないといけなくなります。 $vim vue.d.ts # importが2つあったので削除 $sbt 'run vue.d.ts Vue.scala' [info] Loading project definition from /Users/a-tanaka/.ghq/github.com/sjrd/scala-js-ts-importer/project [info] Set current project to TypeScript importer for Scala.js (in build file:/Users/a-tanaka/.ghq/github.com/sjrd/scala-js-ts-importer/) [info] Running org.scalajs.tools.tsimporter.Main vue.d.ts Vue.scala [success] Total time: 1 s, completed 2015/08/07 20:51:06
2. マークダウンエディタのサンプル写経
写経してみた結果が下記の通りです。
tips
- jsのobjectを定義するには scala.scalajs.js.Dynamic.literalを利用すると良いみたいです。
- また、ここの markedは他ライブラリのmarked.jsのグローバル変数になるのですが、marked.jsのインターフェイス定義をまたscala-js-ts-importerで行うのはめんどうなのでここではそのままグローバル変数を入れるようにしています。
- jsのグローバル変数を利用するためにはscala.scalajs.Dynamic.globalを利用すると良いみたいです。
package vu import scala.scalajs.js.Dynamic.{global => g} import scala.scalajs.js import scala.scalajs.js.JSApp import scala.scalajs.js.annotation.JSExport import scala.scalajs.js.Any._ import scala.scalajs.vuejs.Vue object VueSample extends JSApp { @JSExport def main():Unit = { val option = js.Dynamic.literal( "el" -> "#editor", "data" -> js.Dynamic.literal( "input" -> "# hello" ), "filters" -> js.Dynamic.literal( "marked" -> g.marked ) ) val app = new Vue(option) } }
htmlはサンプルと全く同じです
<html> <head> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.9/vue.js"></script> <script type="text/javascript" src="../target/scala-2.11/scala-js-tutorial-fastopt.js"></script> <script type="text/javascript" src="./app.js" async></script> <style> html, body, #editor { margin: 0; height: 100%; font-family: 'Helvetica Neue', Arial, sans-serif; color: #333; } textarea, #editor div { display: inline-block; width: 49%; height: 100%; vertical-align: top; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 0 20px; } textarea { border: none; border-right: 1px solid #ccc; resize: none; outline: none; background-color: #f6f6f6; font-size: 14px; font-family: 'Monaco', courier, monospace; padding: 20px; } code { color: #f66; } </style> </head> <body> <div id="editor"> <textarea v-model="input" debounce="300"></textarea> <div v-html="input | marked"></div> </div> </body> </html>
app.js
(function() { vu.VueSample().main() })();
ここまで書いたコードを置いたレポジトリがこちらです。
動かしたい場合は
$git clone git@github.com:ara-ta3/scalajs-vuejs-getting-started.git $cd scalajs-vuejs-getting-started $sbt fastOptJS # ↓はMacのみです。単にresources/index.htmlをブラウザで開けば問題無いです。 $open resources/index.html
また、Vue.scalaはJSNameアノテーションの部分を少し変えています。
// @JSName("vuejs.Vue") @JSName("Vue") class Vue protected () extends js.Object { ...
こうしないとブラウザ(chrome)で怒られてしまったので、変更しました。
さて、動かして見た結果がこちらです。(jsで書いた時と何も変わらないですw)
これでVue.jsもScalaでかけます!
JavascriptもサーバサイドもScalaで・・・!
あとはCSSだけですね!