Scala.js Tutorial
Setup
project/plugins.sbt
🔧
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.10")
build.sbt
🔧
enablePlugins(ScalaJSPlugin)
name := "Scala.js Tutorial"
scalaVersion := "2.11.7" // or any other Scala version >= 2.10.2
並確認 project/build.properties
中的版本>=0.13.7
建立JSApp流程:
使用JSApp
src/main/scala/tutorial/webapp/TutorialApp.scala
🔧
package tutorial.webapp
import scala.scalajs.js.JSApp
object TutorialApp extends JSApp {
def main(): Unit = {
println("Hello world!")
}
}
接著在 sbt 下 執行:
作者建議用 Node.js 解釋器,將 build.sbt
加入下列指令
scalaJSUseRhino in Global := false
建立html模板
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>The Scala.js Tutorial</title>
</head>
<body>
<!-- Include Scala.js compiled code -->
<script type="text/javascript" src="./target/scala-2.11/scala-js-tutorial-fastopt.js"></script>
<!-- Run tutorial.webapp.TutorialApp -->
<script type="text/javascript">
tutorial.webapp.TutorialApp().main();
</script>
</body>
</html>
生成 JS File
實作1: 使用DOM
project/plugins.sbt
🔧
logLevel := Level.Warn
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.10")
build sbt
🔧
enablePlugins(ScalaJSPlugin)
name := "basicScalajs"
version := "1.0"
scalaVersion := "2.11.8"
scalaJSUseRhino in Global := false//Rhino is terribly slow. This will enable Node.js by default when launching sbt.
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.0" //%%% means not a normal Scala library
src/main/scala/tutorial/webapp/TutorialApp.scala
🔧
package tutorial.webapp
import scala.scalajs.js.JSApp
import org.scalajs.dom
import dom.document
import scala.scalajs.js.annotation.JSExport
object TutorialApp extends JSApp {
def appendPar(targetNode: dom.Node, text: String): Unit = {
val parNode = document.createElement("p")
val textNode = document.createTextNode(text)
parNode.appendChild(textNode)
targetNode.appendChild(parNode)
}
@JSExport //making scala.js method callable from JS
def addClickedMessage(): Unit = {
appendPar(document.body, "You clicked the button!")
}
def main(): Unit = {
appendPar(document.body,"Hello World")
}
}
接著在sbt 依序執行:
$reload //重新執行sbt
$run
$fastOptJS //重新編譯js檔,但如果每次一有更動就要輸入嫌麻煩的話,執行 ~fastOptJS
根目錄下放置一個 html file(命名任意)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>The Scala.js Tutorial</title>
</head>
<body>
<button id="click-me-button" type="button"
onclick="tutorial.webapp.TutorialApp().addClickedMessage()">Click me!</button>
<!--Include Scala.js compiled code-->
<script type="text/javascript" src="./target/scala-2.11/basicscalajs-fastopt.js"></script>
<!-- Run tutorial.webapp.TutorialApp -->
<script type="text/javascript">tutorial.webapp.TutorialApp().main();</script>
</body>
</html>
實作2: 使用jQuery
project/plugins.sbt
🔧
enablePlugins(ScalaJSPlugin)
name := "basicScalajs"
version := "1.0"
scalaVersion := "2.11.8"
scalaJSUseRhino in Global := false//Rhino is terribly slow. This will enable Node.js by default when launching sbt.
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.0" //%%% means not a normal Scala library
//jqueryVersion
libraryDependencies += "be.doeraene" %%% "scalajs-jquery" % "0.9.0"
skip in packageJSDependencies := false
jsDependencies +=
"org.webjars" % "jquery" % "2.1.4" / "2.1.4/jquery.js"
jsDependencies += RuntimeDOM
src/main/scala/tutorial/webapp/TutorialApp.scala
🔧
import scala.scalajs.js.JSApp
import org.scalajs.jquery.jQuery
object TutorialApp extends JSApp {
def addClickedMessage(): Unit = {
jQuery("body").append("<p>You clicked the button!</p>")
}
def setupUI(): Unit = {
jQuery("body").append("<p>Hello World</p>")
jQuery("#click-me-button").click(addClickedMessage _)
}
def main(): Unit = {
jQuery(setupUI _)
}
html file
<button id="click-me-button" type="button">Click me!</button>
<!-- Include JavaScript dependencies -->
<script type="text/javascript" src="./target/scala-2.11/basicscalajs-jsdeps.js"></script>
<!-- Include Scala.js compiled code -->
<script type="text/javascript" src="./target/scala-2.11/basicscalajs-fastopt.js"></script>
<!-- Run tutorial.webapp.TutorialApp -->
<script type="text/javascript">tutorial.webapp.TutorialApp().main();</script>
接著 sbt 執行:
$reload
$run
$~fastOptJS
Full Optimization
Test and Automatically Creating Launcher
project/plugins.sbt
🔧
enablePlugins(ScalaJSPlugin)
name := "Scala.js Tutorial"
scalaVersion := "2.11.8"
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.0"
libraryDependencies += "be.doeraene" %%% "scalajs-jquery" % "0.9.0"
skip in packageJSDependencies := false
jsDependencies +=
"org.webjars" % "jquery" % "2.1.4" / "2.1.4/jquery.js"
jsDependencies += RuntimeDOM
// uTest settings
libraryDependencies += "com.lihaoyi" %%% "utest" % "0.3.0" % "test"
testFrameworks += new TestFramework("utest.runner.Framework")
//automatically creating a launcher
persistLauncher in Compile := true
persistLauncher in Test := false
src/test/scala/tutorial/webapp/TutorialApp.scala
🔧
package tutorial.webapp
import utest._
import org.scalajs.jquery.jQuery
/**
* Created by YD on 2016/7/21.
*/
object TutorialTest extends TestSuite {
// Initialize App
TutorialApp.setupUI()
def tests = TestSuite {
'HelloWorld {
assert(jQuery("p:contains('Hello World')").length == 1)
}
'ButtonClick {
def messageCount =
jQuery("p:contains('You clicked the button!')").length
val button = jQuery("button:contains('Click me!')")//not yet click
assert(button.length == 1)
assert(messageCount == 0)
for (c <- 1 to 5) {
button.click()
assert(messageCount == c)
}
}
}
}
src/main/scala/tutorial/webapp/TutorialApp.scala
🔧
package tutorial.webapp
import scala.scalajs.js.JSApp
import org.scalajs.jquery.jQuery
object TutorialApp extends JSApp {
def main(): Unit = {
jQuery(setupUI _)
}
def setupUI(): Unit = {
jQuery("body").append("<p>Hello World</p>")
jQuery("""<button type="button">Click me!</button>""")
.click(addClickedMessage _)
.appendTo(jQuery("body"))
}
def addClickedMessage(): Unit = {
jQuery("body").append("<p>You clicked the button!</p>")
}
}
html file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>The Scala.js Tutorial</title>
</head>
<body>
<!-- Include JavaScript dependencies -->
<script type="text/javascript" src="./target/scala-2.11/scala-js-tutorial-jsdeps.js"></script>
<!-- Include Scala.js compiled code -->
<script type="text/javascript" src="./target/scala-2.11/scala-js-tutorial-fastopt.js"></script>
<!--
<!– Run tutorial.webapp.TutorialApp –>
<script type="text/javascript">
tutorial.webapp.TutorialApp().main();
</script>-->
<!-- Run JSApp -->
<script type="text/javascript" src="./target/scala-2.11/scala-js-tutorial-launcher.js"></script>
</body>
</html>