alberto maria angelo paro - isomorphic programming in scala and webdevelopment in scala.js -...
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)
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
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
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
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