alberto maria angelo paro - isomorphic programming in scala and webdevelopment in scala.js -...

29
Isomorphic programming in Scala and WebDevelopment in Scala.JS Alberto Maria Angelo Paro CODEMOTION MILAN - SPECIAL EDITION 10 – 11 NOVEMBER 2017

Upload: codemotion

Post on 21-Jan-2018

48 views

Category:

Technology


0 download

TRANSCRIPT

Isomorphic programming in Scala and WebDevelopment in Scala.JSAlberto Maria Angelo Paro

CODEMOTION MILAN - SPECIAL EDITION

10 – 11 NOVEMBER 2017

Alberto Paro

Master Degree in Computer Science Engineering at Politecnico di Milano

Author of 3 books about ElasticSearch from 1 to 5.x + 6 Techreviews

Big Data Trainer, Developer and Consulting on Big data Technologies (Akka, Playframework, Apache Spark, ReactiveProgramming) e NoSQL (Accumulo, Hbase, Cassandra, ElasticSearch, Kafka and MongoDB)

Evangelist for Scala e Scala.JS Language

CTO at Quinnteus PTE LD (Singapore)

Who it’s using Scala

Isomorphic Scalaone language => many target

Scala is a language that is:• Multi-paradigm• Strong-typed• Functional• Object Oriented

Scala compiler compile code in a special AST (Abstract Syntactic Tree)There are different byte-cote emitter: JVM Javascript Native (binary based on LLVM)

The same code can be compiled and run in different target based on your needs.

Javascript issues

A lot of language “defects”: Easy to forget var

It’s born a script language, not designed to scale large applications (SPA or many modules) And Web is moving toward very big and complex JS applications

Jquery => AngularJS => React.Js (an hype in complexity)

A lot of language compiles to javascript (Coffeescript, Typescript, …) due to these issues and more: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 Javascript - the compiler handles the rest.

It brings the advantages of Scala into client web development.

Support of “all” Scala (also macros)

SBT integration - IDE support as “standard” Scala language

Compiled code is reasonable small (GCC => Google Closure Compiler)

SourceMaps for easy debug in Web browser

Interoperability with Javascript (JS => ScalaJS , ScalaJS => JS)

• Scala.js code calls Javascript

• Scala.js can export classes and methods to Javascript

• http://www.scala-js.org/

Scala.js Compiler Pipeline

Main.classMain$.class

Main.Scala

Main.sjsirMain$.sjsir

script- fastopt.js

500k - 3000Kb

script- opt.js

100k - 1000kb

Scala

c

Scala.jsPlugin

Optimizer

Renderer

Google C C

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 checks

Javascript 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 dev. Web Apps with ScalaJS

Application in only one language and the language is Scala

Strong typing in the application and RCP layer Autowire library

Scala 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

Javascript VM != Java VM

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

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.12.3”,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

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

+- src/main/scala

SBT configuration JS/JVM

Libraries

When using REST in themes, my code can break due to: Model changes:• Who removed a field from …?• Who renamed the field …?• Who changed the type of the field …?

Endpoints changes:• A new parameter is required• You changed my endpoint name! o /item/executeNLP => /item/execute-nlp

• Changed return type: i.e. models This situation becomes more evident in large teams

or in very fast development cycles.

Safe Server-Client Communication

Issues

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

// server-side router and implementation object Server extends autowire.Server...object ApiImpl extends Apidef 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

Autowire

https://github.com/lihaoyi/scalatagslibraryDependencies += "com.lihaoyi" %%% "scalatags" % "0.6.7”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

ScalaTags

Strong Typed HTML Syntax for JVM/JS

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>

ScalaTags - Example

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

“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

AngularJS – 1/2

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

AngularJS – 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

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

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

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 = ScalaComponent.builder[String]("HelloMessage")

.render($ => <.div("Hello ", $.props))

.build

HelloMessage(”Alberto") .renderIntoDOM(mountNode)Schermata 2015-04-26 alle 10.56.47.

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

ScalaJs - React

Scala

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" % ”1.1.1")• Monocle support (Lens for case class) ("com.github.japgolly.scalajs-react" %%% "ext-

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

val s = Simulation.focus >> ChangeEventData("hi").simulation >> Simulation.blur• Module extra ("com.github.japgolly.scalajs-react" %%% "extra" % ”1.1.1") with Router Component Mixins: Broadcaster and Listenable ExternalVar LogLifecycle OnUmount SetInterval

ScalaJs - React

Scala

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

ScalaCSS – CSS typesafe

Links

Scala

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): Play Scala.Js Example (https://github.com/hussachai/play-scalajs-showcase)

https://scalafiddle.io/sf/4beVrVc/1 Rendering https://scalafiddle.io/sf/n6lR8Xh/2 Some samples https://github.com/circe/circe JSON as a Pro! https://twitter.github.io/scala_school/ Scala Course from twitter

Scala Native http://www.scala-native.org/en/latest/

Useful Links

Questions

Thank YouAlberto Paro

[email protected]@aparo77We are hiring (IT, GB, SG)!

Tip & 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.nativedef 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

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

Facading Javascript Libraries

“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'

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

Facading Javascript Libraries