あらすじ
こんにちは、深澤です。
最近javascriptを多用したのですが、なかなか動作が安定しない(安定させるのに苦労した)という事件がありました。
そんな中、なんとscalaで書いたコードがjsになっちゃうという夢のようなお話を聞きました。
それがscala.jsとの出会いです。
jsの最初の一歩ってなんやろ?って考えたときに、
「とりあえずアラート出したら最小構成っぽいし、第一歩じゃね?」という安直な考えから、scala.jsでアラートを表示する目標に向かって歩き始めました。
目指すは、staticなhtmlファイルでアラートを表示することです。
scala.jsのセットアップ
ここはもう完全にチュートリアルを参考にしちゃいました。
Scala.js Tutorial
チュートリアルのバージョンは少し古いようなので最新にしてみました(2015年10月11日現在)。
sbt 0.13.8
scala 2.11.6
scalajs 0.6.5
まずはおもむろにディレクトリ作って(アプリケーションのルートディレクトリ)、
project/plugins.sbt でscala.jaを持ってきます。
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.5")
次にbuild.sbtをこんな感じに定義します。
enablePlugins(ScalaJSPlugin)
name := "try scala.js"
scalaVersion := "2.11.6"
そして、sbtのバージョンをproject/build.propertiesで指定します。
sbt.version=0.13.8
これで下準備は完了です!
初めてのjsコード
そしたら、適当にscalaのコードを書きます。
どこに書いても動作上問題ないですが、僕はsrc/main/scala配下に用意しました。
import scala.scalajs.js.JSApp
object sampleApp extends JSApp {
def main(): Unit = {
println("Hello world!")
}
}
JSAppクラスを継承してますが、このクラスを継承することで、scalaコードを自動でjavascriptにexportしてくれます。
もし、このJSAppを付けなかった場合は、JSExportアノテーションを付与しなければなりません。
具体的には、次のように書きます。
import scala.scalajs.js.annotation.JSExport
@JSExport
object sampleApp {
@JSExport
def main(): Unit = {
println("Hello world!")
}
}
ここまできたら、一旦正常に動作するかを確かめてみましょう。
$ sbt run
[info] Set current project to try scala.js (in build file:/)
[info] Running sampleApp
Hello world!
[success] ...
一応、これでscala.js完成となるのですが、目指す場所はコンソールでの表示ではありません。
staticなhtml上です。
というわけで、今書いたコードをjsに変換します。
sbtのfastOptJSというコマンドを使います。
$ sbt fastOptJS
ログを見れは一目瞭然ですが、jsファイルは
アプリケーションのルートディレクトリ/target/scala-2.11/foo-bar-fastopt.js
に生成されます。
staticなhtmlを用意
こんな感じで用意しました。
ちなみにアプリケーションのルートディレクトリ配下です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>scala-js使ってみました</title>
</head>
<body>
<script type="text/javascript" src="./target/scala-2.11/try-scala-js-fastopt.js"></script>
<script type="text/javascript">
sampleApp().main();
</script>
</body>
</html>
何も表示されない・・・
こんな感じで呼び出せばいいのかな。
pythonで簡単なhttpサーバを立ち上げて確認してみます。
python -m SimpleHTTPServer
おやおや?何も表示されない・・・。
チュートリアルをしっかり見るとこんなことが書いてありました。
If you now open the newly created HTML page in your favorite browser, you will see ... nothing. The println in the main method goes right to the JavaScript console, which is not shown by default in a browser.
あ、そっか。コンソールに表示されるのね。
確かに、chromeのjavascriptコンソールには元気いっぱいの「Hello world!」が表示されました。
いやいやいやいや、表示したいのはコンソールじゃないよ!
javascriptの関数の呼び出し方
なんと驚くことにscala.jsではjavascriptの関数をあっさり呼び出せるようです。
scala.scalajs.js.Dynamic.global から呼び出せます。
牛B!!(中国語で「すげぇ」って意味らしいですよ。)
てなわけでさっそく先ほどのコードを改良します。
import scala.scalajs.js.{ JSApp, Dynamic }
object sampleApp extends JSApp {
def main(): Unit = {
println("Hello world!")
Dynamic.global.alert("アラート")
}
}
改良ってより付け足した感じですね。
では、さっそくコンパイルして、表示します!
$ sbt fastOptJS
$ python -m SimpleHTTPServer
これでブラウザでlocalhost:8000にアクセスすると無事にアラートが表示されることを確認しました!
終わりに
まだまだ経験が浅いのですごく苦戦してしまいました。。。
でもまだまだjavascriptの遺産を呼び出しただけなので、本当のscala.jsの良さを理解してないと思います。
今後はもっとscala.jsを可愛がって、scala.jsを深く理解していきたいです。
なお、今回のコードは僕のgithubにて公開してます。
https://github.com/pukka/try-scalajs
いつも通りお気軽にコメントお願いしますね^^
それでは、失礼します。