Alberto Paro - Hands on Scala.js

Preview:

Citation preview

MILAN - 08TH OF MAY - 2015

PARTNERS

Hands on ScalaJS

Alberto Paro

Engineer from Politecnico of MilanWorking at Big Data Technologies + ConsultingAuthor of two ElasticSearch books.Mainly working in Scala (Akka, Spray.io, Playframework, Apache Spark)Developed big application with Scala.JS

Alberto Paro 

Table Of Contents

Background information

Why Scala.JS

SBT

Libraries

Tricks and Tips

Questions

1. Why Scala.Js?

Why I don’t like Javascript

• A lot of language “defects”• It’s a script language, not designed to scale large applications (SPA or many modules)• IDEs are good, but no refactory available

• Hard to be used for large projects• Verbose if you want safe code.

• Coffescript and similar (Any => Js) try to simplify it.

• A lot of language compiles to javascript (Coffeescript, Microsoft typescript, …)https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS

What’s Scala.JS

"Scala.js is a compiler that converts Scala code into the equivalent, executable Javascript”Write Scala, not JavascriptThe compiler handles the restIt brings the advantages of Scala into client web development.Support of “all” Scala (also macros)Easy interoperability with JavascriptSBT integrationIDE support as “standard” Scala languageCompiled code is reasonable small (GCC => Google Closure Compiler)SourceMaps for easy debug in Web browserInteroperability with Javascript (JS => ScalaJS , ScalaJS => JS)

Scala.js code calls JavascriptScala.js can export classes and methods to Javascript

Scala.js Compiler Pipeline

On developing Web Apps

No code reuse between client and server

A least you must learn two languages (Scala + JS)Algorithms and models must be rewritten

RCP/Ajax calls with “no type”No compiler checksJavascript issues:

Forgot a “var”Js => [“10”, “10”, “10”, “10”].map(parseInt)

[10, NaN, 2, 3]['10','10','10','10','10'].map(function(x){return

parseInt(x);})

On developing Web Apps with Scala.js

Application in only one language

and the language is ScalaStrong typing in the application and RCP layer

Autowire libraryScala typesafe

document.getElementByld(“foo”)“Standard” behavior

scala.js> List("10", "10", "10", "10").map(parseInt)List(10, 10, 10, 10)

Some Semantic differences from JS

• Division by 0 doesn’t throw exception• Checking the type of number is based on its numeric value, not class instance.• Scala.Unit is represented as undefined in Javascript• JavaScript regular expressions are slightly different from Java regular expressions.• Different behavior of some exceptions

Javascript VM != Java VM

2. SBT

name := "Foo root project”lazy val root = project.in(file(".")). aggregate(fooJS, fooJVM). settings(publish := {}, publishLocal := {})

lazy val foo = crossProject.in(file(".")). settings( name := "foo", version := "0.1-SNAPSHOT", scalaVersion := "2.11.6”, libraryDependencies += "com.lihaoyi" %%% "scalatags" % "0.4.3" ). jvmSettings( // Add JVM-specific settings here ). jsSettings( // Add JS-specific settings here )

lazy val fooJVM = foo.jvmlazy val fooJS = foo.js

Simple multi target JS/JVM

SBT configuration for ScalaJS

<project root> +- jvm | +- src/main/scala+- js | +- src/main/scala+- shared +- src/main/scala

3. Libraries

Type safe RPC between client and serverAPI trait in shared codeServer code implement the backend codeClient calls in a type safe way

// shared interfacetrait Api{ def add(x: Int, y: Int, z: Int): Int }

Safe Server Client Communication

AutoWire

// server-side router and implementation object Server extends autowire.Server...object ApiImpl extends Api def add(x: Int, y: Int, z: Int) = x + y + z }

// client-side callsiteimport autowire._ // needed for correct macro application

object Client extends autowire.Client...Client[Api].add(1, 2, 3).call(): Future[Int]// | | |// | | The T is pickled and wrapped in a Future[T]// | The arguments to that method are pickled automatically// Call a method on the `Api` trait

https://github.com/lihaoyi/scalatagslibraryDependencies += "com.lihaoyi" %%% "scalatags" % "0.5.1”

ScalaTags is a small XML/HTML construction library for Scala.Since ScalaTags is pure Scala, any editor that understands Scala will understand scalatags. Not only do you get syntax highlighting, you also get code completion:• Autocomplete• Error Highlighting• In-editor documentation:And all the other good things (jump to definition, extract method, etc.) you're used to in a statically typed language. No more digging around in templates which mess up the highlighting of your HTML editor, or waiting months for the correct plugin to materialize.

Strong Typed HTML Syntax for JVM/JS

Scala Tags

Strong Typed HTML Syntax for JVM/JS

Scala Tags - Example

html( head( script(src:="..."), script( "alert('Hello World')" ) ), body( div( h1(id:="title", "This is a title"), p("This is a big paragraph of text") ) ))

<html> <head> <script src="..."></script> <script>alert('Hello World')</script> </head> <body> <div> <h1 id="title">This is a title</h1> <p>This is a big paragraph of text</p> </div> </body></html>

https://github.com/greencatsoft/scalajs-angularlibraryDependencies += "com.greencatsoft" %%% "scalajs-angular" % "0.4”

“scalajs-angular aims to help developers build AngularJS based applications in type safe manner with Scala language.”

Schermata 2015-04-26 alle 10.56.47.png

AngulaJS - scalajs-angular 1/2

It provides annotation helper for AngularJS Services, Controllers, Directives, and Filters.It wraps ngRoute for routing in your SPA.

Schermata 2015-04-26 alle 10.56.47.png

AngulaJS - scalajs-angular 2/2

https://github.com/jokade/scalajs-angulatelibraryDependencies += "biz.enef" %%% "scalajs-angulate" % "0.1”

“scalajs-angulate is a small library to simplify developing AngularJS applications in Scala (via Scala.js). To this end it provides:

• façade traits for the Angular core API• macros for defining controllers, services and directives in a more natural Scala style”

val module = angular.createModule("counter")module.controllerOf[CounterCtrl]

class CounterCtrl extends Controller { var count = 0 def inc() = count += 1 def dec() = count -= 1 // private properties and functions are not exported to the controller scope private def foo() : Unit = ...}

Schermata 2015-04-26 alle 10.56.47.png

AngulaJS - scalajs-angulate 1/2

It can be called in a similar HTML fragment:

<html ng-app="counter"> <body> <div ng-controller="App.CounterCtrl as ctrl"> Count: {{ctrl.count}} <button ng-click="ctrl.inc()">+</button> <button ng-click="ctrl.dec()">&ndash;</button> </div>

<!-- ... -->

</body></html>

Schermata 2015-04-26 alle 10.56.47.png

AngulaJS - scalajs-angulate 2/2

I love ReactJS because:• Your code is clear. It is arranged into components, each with its own defined

responsibility. (Web component, better dividi-et-impera approach)• Your app is predictable. It’s very clear where data flows, and what happens when a user

does something. • Your app is fast. React is really, really fast, creating a better experience for users, even

if you have a ton of data. (Virtual DOM, …)• Your app is standards-based. React adds layers only when it needs to. You feel like you

are actually writing JavaScript and HTML, not some magic template language.• Surprise, you’re an app developer. React breaks down barriers across platforms, by

applying its same model across the board. This means that once you learn the React way of structuring an web application, you have a huge head start on developing a native iOS or Android app, thanks to react-native. Surely this will happen to other platforms.

Schermata 2015-04-26 alle 10.56.47.png

Scala Js - React

http://aspiringwebdev.com/why-react-js-matters-for-developers/

I love ScalaJS ReactJS because:• It composed by simple concepts:

• Properties (Props) are immutable• State is mutable• a render method

• Everything is strong typed: VDOM, Components

• Easy to extend components• Schermata 2015-04-26 alle 10.56.47.png

Scala Js - React

Javascriptvar HelloMessage = React.createClass({displayName: 'HelloMessage', render: function() { return React.createElement("div", null, "Hello ", this.props.name); }});React.render(React.createElement(HelloMessage, {name: ”Alberto"}), mountNode);• Schermata 2015-04-26 alle 10.56.47.png

Scalaval HelloMessage = ReactComponentB[String]("HelloMessage") .render(name => <.div("Hello ", name)) .build

React.render(HelloMessage(”Alberto"), mountNode)Schermata 2015-04-26 alle

10.56.47.png

https://github.com/japgolly/scalajs-reacthttp://japgolly.github.io/scalajs-react/

Scala

Scala Js - React

https://github.com/japgolly/scalajs-reacthttp://japgolly.github.io/scalajs-react/

ScalaJS React provide also many extra:• Scalaz support ("com.github.japgolly.scalajs-react" %%% "ext-scalaz71" % "0.8.4")• Monocle support (Lens for case class) ("com.github.japgolly.scalajs-react" %%% "ext-

monocle" % "0.8.4")• Testing support ("com.github.japgolly.scalajs-react" %%% "test" % "0.8.4" % "test")

val s = Simulation.focus >> ChangeEventData("hi").simulation >> Simulation.blur• Module extra ("com.github.japgolly.scalajs-react" %%% "extra" % "0.8.4") with

Router Component Mixins:

Broadcaster and Listenable ExternalVar LogLifecycle OnUmount SetInterval

Scala

Scala CSS - CSS Type Safe!

https://github.com/japgolly/scalacsshttp://japgolly.github.io/scalacss/book/

ScalaCSS aims to bring type-safety and clarity to:• creating CSS• using CSS• maintaining CSS• correctness of CSSYou can create standalone CSS like SCSS/LESS, or you can create inline styles to be applied to directly without the need to manually manage class names.Being 100% Scala, you benefit from all the normal type-aware advantages like jump-to-definition of a style, type-safe keys and values, worry-free refactoring, etc.

Example: http://japgolly.github.io/scalacss/book/quickstart/standalone.html

Scala

Other Libraries Links

A lot of libraries are linked in Scala.js Homepage (http://www.scala-js.org/)For a complete projects, the best resources are:- SPA Tutorial (https://github.com/ochrons/scalajs-spa-tutorial) with doc (

http://ochrons.github.io/scalajs-spa-tutorial/css-in-scala.html):- Spray- Autowire- Scala.JS React- Scala CSS- Deploy

- Querki (https://github.com/jducoeur/Querki)- Scala.Js jquery- Facades

- Play Scala.Js Example (https://github.com/hussachai/play-scalajs-showcase)- Gitter Channels

4. Tips & Tricks

To manage the javascript library, Scala needs the code signature of the Javascript methods.First search on scala.js site or github scalajs trait JQuery extends js.Object { /** * Adds the specified class(es) to each of the set of matched elements. */ def addClass(classNames:String):JQuery = js.native def addClass(func:js.ThisFunction2[Element, Int, String, String]):JQuery = js.native @JSName("after") def afterInternal(content:js.Any):JQuery = js.native @JSName("append") def appendInternal(content:js.Any*):JQuery = js.native

@JSName("appendTo") def appendToInternal(target:js.Any):JQuery = js.native @JSName("attr") def attrInternal(attributeName:String):UndefOr[String] = js.native

Facading Javascript Libraries

$(“div#myId”).addClass("myclass")

“Automatically” bootstrap your façade from a typescript definition (https://github.com/borisyankov/DefinitelyTyped): ~900 library already “typed”.

The process is not 100 % accurate, so manual editing is often needed afterwards. This can be improved, but not to perfection, because the features offered by the type systems of TypeScript and Scala.js differ in some subtle ways.

Usage$ sbt 'run somelib.d.ts SomeLib.scala'

Facading Javascript Libraries

https://github.com/sjrd/scala-js-ts-importer

5. Questions

MILAN - 08TH OF MAY - 2015

PARTNERS

THANK YOU!Alberto Paro

alberto.paro@gmail.com@aparo77

PARTNERS

Recommended