alberto paro - hands on scala.js

30
MILAN - 08TH OF MAY - 2015 PARTNERS Hands on ScalaJS Alberto Paro

Upload: scala-italy

Post on 08-Aug-2015

205 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Alberto Paro - Hands on Scala.js

MILAN - 08TH OF MAY - 2015

PARTNERS

Hands on ScalaJS

Alberto Paro

Page 2: Alberto Paro - Hands on Scala.js

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 

Page 3: Alberto Paro - Hands on Scala.js

Table Of Contents

Background information

Why Scala.JS

SBT

Libraries

Tricks and Tips

Questions

Page 4: Alberto Paro - Hands on Scala.js

1. Why Scala.Js?

Page 5: Alberto Paro - Hands on 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

Page 6: Alberto Paro - Hands on Scala.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

Page 7: Alberto Paro - Hands on Scala.js

Scala.js Compiler Pipeline

Page 8: Alberto Paro - Hands on Scala.js

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);})

Page 9: Alberto Paro - Hands on Scala.js

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)

Page 10: Alberto Paro - Hands on Scala.js

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

Page 11: Alberto Paro - Hands on Scala.js

2. SBT

Page 12: Alberto Paro - Hands on Scala.js

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

Page 13: Alberto Paro - Hands on Scala.js

3. Libraries

Page 14: Alberto Paro - Hands on Scala.js

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

Page 15: Alberto Paro - Hands on Scala.js

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

Page 16: Alberto Paro - Hands on Scala.js

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>

Page 17: Alberto Paro - Hands on Scala.js

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

Page 18: Alberto Paro - Hands on Scala.js

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

Page 19: Alberto Paro - Hands on Scala.js

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

Page 20: Alberto Paro - Hands on Scala.js

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

Page 21: Alberto Paro - Hands on Scala.js

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/

Page 22: Alberto Paro - Hands on Scala.js

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/

Page 23: Alberto Paro - Hands on Scala.js

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

Page 24: Alberto Paro - Hands on Scala.js

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

Page 25: Alberto Paro - Hands on Scala.js

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

Page 26: Alberto Paro - Hands on Scala.js

4. Tips & Tricks

Page 27: Alberto Paro - Hands on Scala.js

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")

Page 28: Alberto Paro - Hands on Scala.js

“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

Page 29: Alberto Paro - Hands on Scala.js

5. Questions

Page 30: Alberto Paro - Hands on Scala.js

MILAN - 08TH OF MAY - 2015

PARTNERS

THANK YOU!Alberto Paro

[email protected]@aparo77

PARTNERS