LoginSignup
8
2

More than 5 years have passed since last update.

Scala.jsでクロスコンパイル - 1. 環境構築

Posted at

Scala.jsは、ScalaのコードをJavaScript(JS)に変換するコンパイラです。
公式の紹介ページでは、以下の4点がScala.jsの優れた点であると謳われています。

Scala.jsは、単なるJSの代替記法(altJS)に加え、JSとJava仮想マシン(JVM)とで動作するコードのクロスビルドツールとして利用することができます。
クロスビルドに関する資料として、以下のようなものが挙げられます。

しかし、これらの資料は、十分にクロスビルドを説明しているとは言えません。
クロスビルド初心者は、チュートリアルが存在しないので、試す前に諦めてしまうかもしれません。
私も全然わからず、ソースコードから動作を推測するなどして、やっと動かすことができました。
そこで、コードを書く部分を含めた、Scala.jsクロスコンパイルの簡単なチュートリアルを作成します。

本ページでは、Scala.jsでクロスコンパイルできる環境を構築し、JSとJVM向けにそれぞれ実行可能なものが生成されることを確認します。

環境のセットアップ

事前にSBTをインストールしておいてください。

以下に示すようにsbt newコマンドを実行すると、自動的にScalajsクロスビルド対応のSBTプロジェクトが生成されます。

$ sbt new umireon/scalajs-cross-seed.g8
Minimum Cross-building Scala.js build.

name [My Something Project]: Scalajs Cross Example⏎

Template applied in ./scalajs-cross-example

自動生成されたプロジェクトの内容は以下の通りです。

scalajs-cross-example/
├── build.sbt
├── js/src/main/scala/example/Hello.scala
├── jvm/src/main/scala/example/Hello.scala
├── project/
│   ├── build.properties
│   └── scalajs.sbt
└── shared/src
    ├── main/scala/example/Hello.scala
    └── test/scala/example/HelloSpec.scala

これで、Scala.jsクロスビルドの準備は完了です。
ここでは、build.sbtの内容に触れませんが、気になる方は公式ドキュメントを確認してください。

ビルドの確認

先ほど生成したプロジェクトにはテストが含まれています。
Scala.jsが正しく動作しているか確認するために、JSとJVM上でビルド及びテストを実行してみます。
プロジェクトディレクトリへ移動し、以下のコマンドを実行してみてください。

$ sbt test
[info] HelloSpec:
[info] The Hello object
[info] - should say hello
[info] Run completed in 660 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.

[info] Fast optimizing /path/to/scalajs-cross-example/hello-test-fastopt.js
[info] HelloSpec:
[info] The Hello object
[info] - should say hello
[info] Run completed in 606 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 24 s, completed 2017/04/18 14:23:36

出力結果を見ると、All tests passed.が2回現れていることがわかります。
これは、1番目がJVMにおけるテストの結果、2番目がJSにおけるテストの結果を示すものです。

ビルド後、ディレクトリ構成は以下のように変化します。

scalajs-cross-example/
├── build.sbt
├── js
│   ├── src/main/scala/example/Hello.scala
│   └── target/
├── jvm
│   ├── src/main/scala/example/Hello.scala
│   └── target/
├── project/
│   ├── build.properties
│   └── scalajs.sbt
├── shared/src
│   ├── main/scala/example/Hello.scala
│   └── test/scala/example/HelloSpec.scala
└── target/

ディレクトリ構成

本節では、上記のディレクトリ構成のうち、Scala.jsクロスビルド特有のものについて説明します。

sharedは、JSとJVMで共有するコードを格納するディレクトリです。
ここに格納されたScalaコードは、JVMビルド時とJSビルド時に別々にコンパイルされます。
したがって、クロスビルド実現のためには、JVMとJSの両環境で実行可能なScala.jsコードを書く必要があります。

js及びjvmは、各環境にて実行可能なオブジェクトが生成されるディレクトリです。
JS用の生成物はjs/target/、JVM用の生成物はjvm/targetにそれぞれ出力されます。
また、Hello.scalaのように、片方の環境のみで実行したいコードもここに格納します。
参考のため、各Hello.scalaの内容を以下に示します。

js/src/main/scala/example/Hello.scala
package example

import scala.scalajs.js

object Hello extends Greeting with js.JSApp {
  def main(): Unit = {
    println(greeting)
  }
}
jvm/src/main/scala/example/Hello.scala
package example

object Hello extends Greeting with App {
  println(greeting)
}

生成物の確認

JVMでは、JARファイルを生成し、それが実行可能であることを確認します。
JARファイルはsbt packageコマンドを実行することにより生成され、jvm/target/scala-2.12以下に得られます。

$ ls scalajs-cross-example/jvm/target/scala-2.12
classes             test-classes
hello_2.12-0.1.0-SNAPSHOT.jar

実行結果は、以下のコマンドにより確認できます。

$ sbt helloJVM/run
...
[info] Running example.Hello
hello
[success] Total time: 1 s, completed 2017/04/18 15:11:04

JSでは、JSファイルを生成し、それが実行可能であることを確認します。
JSファイルはsbt fullOptJSコマンドを実行することにより生成され、js/target/scala-2.12以下に得られます。

$ ls scalajs-cross-example/jvm/target/scala-2.12
classes                   hello-test-fastopt.js
hello-jsdeps.js           hello-test-fastopt.js.map
hello-jsdeps.min.js       hello-test-jsdeps.js
hello-opt.js              hello_sjs0.6_2.12-0.1.0-SNAPSHOT.jar
hello-opt.js.map          test-classes

実行結果は、以下のコマンドにより確認できます。

$ node scalajs-cross-example/js/target/scala-2.12/hello-opt.js
hello

続き

Scala.jsでクロスコンパイル - 2. 型とコレクション
そのうち書く

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2