35
SCALA JAVA SCRIPT Katrin Shechtman BoldRadius, Toronto, Canada Dave Sugden BoldRadius, Gatineau, Quebec © BoldRadius, 2015 1

How You Convince Your Manager To Adopt Scala.js in Production

Embed Size (px)

Citation preview

Page 1: How You Convince Your Manager To Adopt Scala.js in Production

SCALA JAVASCRIPTKatrin ShechtmanBoldRadius, Toronto, Canada

Dave SugdenBoldRadius, Gatineau, Quebec

© BoldRadius, 2015 1

Page 2: How You Convince Your Manager To Adopt Scala.js in Production

How to convince your Manager* to adopt scalajs

*Manager: boss | client | CTO | colleague | that clojurescript guy • Effective front-end development with the scalajs ecosystem

is viable (and preferable!).

• Here are some tools to enable you to persuade whoever you need to.

© BoldRadius, 2015 2

Page 3: How You Convince Your Manager To Adopt Scala.js in Production

Who are you?1. You know and love scala

2. You have to deal with some non-trivial web front-end

3. You don't scalajs? Lets get you going.

4. You do scalajs? Here are some of our opinions

© BoldRadius, 2015 3

Page 4: How You Convince Your Manager To Adopt Scala.js in Production

Who are we?• Server Side scala/akka developers

• Relatively new to scalajs

• Have experience writing javascript for the front-end

© BoldRadius, 2015 4

Page 5: How You Convince Your Manager To Adopt Scala.js in Production

Path to scalajs: shoulders of giantsPart 1

Like many others, our path to scalajs began with @lihaoyi

• scalatagsform( div(cls := "form-group")( label(color := GlobalStyles.textColor)("Cluster Name"), input(tpe := "text", cls := "form-control", value := S.cluster.name, onChange ==> B.updateClusterName) ))

© BoldRadius, 2015 5

Page 6: How You Convince Your Manager To Adopt Scala.js in Production

Path to scalajs: shoulders of giantsPart 2

• scalarximport rx._val a = Var(1)val b = Var(2)val c = Rx{ a() + b() }println(c()) // 3a() = 4println(c()) // 6

© BoldRadius, 2015 6

Page 7: How You Convince Your Manager To Adopt Scala.js in Production

© BoldRadius, 2015 7

Page 8: How You Convince Your Manager To Adopt Scala.js in Production

Javascript, living the dream• JS devs live and die by their setups*

• No different for scalajs... you need a setup

*setup: tooling, framework, module + dependency mgmt etc.

© BoldRadius, 2015 8

Page 9: How You Convince Your Manager To Adopt Scala.js in Production

Javascript the language(from lihaoyi.github.io/hands-on-scala-js) • Its an OK language with some warts

• Not an easy language to work in at scale (refactoring)

© BoldRadius, 2015 9

Page 10: How You Convince Your Manager To Adopt Scala.js in Production

Javascript as Platform(from lihaoyi.github.io/hands-on-scala-js)

• No install

• Everywhere

• Sandboxed security

© BoldRadius, 2015 10

Page 11: How You Convince Your Manager To Adopt Scala.js in Production

A Javascript "setup"• Newcomers are often coming from communities in which

full-stack solutions exist.

• JavaScript tooling often consists of small tools, utilities and libraries that combined builds your code to be used in a browser.

• Variety is huge

© BoldRadius, 2015 11

Page 12: How You Convince Your Manager To Adopt Scala.js in Production

A Javascript "setup" - Part 11. Babel / CoffeeScript / Typescript / PureScript: transpilers

2. Webpack / Browserify : module bundlers

3. Gulp / Grunt : build systems, task runners, orchestrate processes to work on some files

© BoldRadius, 2015 12

Page 13: How You Convince Your Manager To Adopt Scala.js in Production

A Javascript "setup" - Part 21. npm: package manager, downloading packages, resolving

dependencies

2. Mocha / Jasmine / Chai / sinon: Test framework

3. AngularJS / Ember / Backbone / React etc.

© BoldRadius, 2015 13

Page 14: How You Convince Your Manager To Adopt Scala.js in Production

A Scala "setup"You are already a scala expert and familiar with SBT:

You already have 2/3 of your "setup"

© BoldRadius, 2015 14

Page 15: How You Convince Your Manager To Adopt Scala.js in Production

Scala, SBT, ScalaJsPlugin, Webjars: the first 2/3...

© BoldRadius, 2015 15

Page 16: How You Convince Your Manager To Adopt Scala.js in Production

The Final Third of your Setup• scalajs-dom, scalatags

• scalarx

• scalajs-react

• autowire

• upickle

• sbt tasks and plugins

© BoldRadius, 2015 16

Page 17: How You Convince Your Manager To Adopt Scala.js in Production

Scalajs really practical guidehttps://github.com/katrinsharp/scalajs-rpg

• Anatomy of typical Scalajs app

• Each step contains minimal code and dependencies

• Client assets are independent from server

• Proposed architecture

© BoldRadius, 2015 17

Page 18: How You Convince Your Manager To Adopt Scala.js in Production

1. MAKE SURE YOU SHARE!Server/client code sharing - done right

addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.4")

//build.sbtimport org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._name := "scalajs-rpg"lazy val root = project.in(file(".")) .aggregate(jsProject, jvmProject)lazy val cross = crossProject.in(file(".")) .settings( name := "scalajs-rpg", version := "0.1-SNAPSHOT", scalaVersion := "2.11.7") .jvmSettings()// JVM-specific settings here .jsSettings()// JS-specific settings here

© BoldRadius, 2015 18

Page 19: How You Convince Your Manager To Adopt Scala.js in Production

2. MANIPULATE THIS HTML DOM.And use your first Scalajs facade

"org.scala-js" %%% "scalajs-dom" % "0.8.0"

val mainEl = dom.document.getElementById("main-el")//option AmainEl.innerHTML = s""" |<div>some stuff</div> ... """.stripMargin//option Bval parNode = doc.createElement("p")...mainEl.appendChild(parNode)

© BoldRadius, 2015 19

Page 20: How You Convince Your Manager To Adopt Scala.js in Production

3. GOT DEPENDENCIES? SBT IT!Use WebJars with sbt-web

addSbtPlugin("com.typesafe.sbt" % "sbt-web" % "1.1.1")

"org.webjars" % "jquery" % "1.11.1" / "jquery.js","org.webjars" % "bootstrap" % "3.3.2" / "bootstrap.js" dependsOn "jquery.js"

<!-- dep in index-fastopt.html --><link rel="stylesheet" type="text/css" href="./js/target/web/web-modules/main/webjars/lib/bootstrap/css/bootstrap.min.css">

© BoldRadius, 2015 20

Page 21: How You Convince Your Manager To Adopt Scala.js in Production

4. SAFE HTML EDUCATION.With scalatags (scalacss? out-of-scope this time)

"com.lihaoyi" %%% "scalatags" % "0.5.2"

divInMainEl.appendChild( div(`class` := "col-md-8", p(`class` := "red", s"From shared and type safe: $res") ).render)

© BoldRadius, 2015 21

Page 22: How You Convince Your Manager To Adopt Scala.js in Production

5. DON'T RE-INVENT THE WHEEL!jQuery, Angular, React, (Ionic, Electron) ...

"com.github.japgolly.scalajs-react" %%% "core" % "0.9.0"

val component = ReactComponentB[Unit]("TodoListComponent") .initialState(State(List.empty[Todo], "")) .backend(new Backend(_)) .render((_, S, B) => div( h3("TODO"), TodoList(S.items), form(onSubmit ==> B.handleSubmit, input(onChange ==> B.onChange, value := S.text), button("Add") ) ) ).buildU

© BoldRadius, 2015 22

Page 23: How You Convince Your Manager To Adopt Scala.js in Production

6. KEEP YOUR DATA IN SYNC!"com.lihaoyi" %%% "scalarx" % "0.2.8"

© BoldRadius, 2015 23

Page 24: How You Convince Your Manager To Adopt Scala.js in Production

7. TREAT YOUR AJAX CALLS WITH SOME SAFETY!"com.lihaoyi" %%% "autowire" % "0.2.5"

//SHAREDtrait Api { def suggestions(s: String): Seq[Suggestion]}//SERVER: segments: val req = autowire.Core.Request(segments, params)AutowireServer.route[Api](ApiImpl)(req)/* CLIENT:** 1. Call statically typed API** 2. Implement callback that will be called when your Future completes** 3. Use Rx to automatically update the client state*/AjaxClient[Api].suggestions(text).call().foreach(r => currentSuggestions() = r)

© BoldRadius, 2015 24

Page 25: How You Convince Your Manager To Adopt Scala.js in Production

8. RELEASE YOUR CLIENT TO THE WILD. RAWWRR....

• IF your assets are hosted somewhere else:lazy val ReleaseJsCmd = Command.command("releaseJs") { state => "crossJS/fullOptJS" :: "crossJS/webStage" :: state}...jsSettings( pipelineStages := Seq(cssCompress), commands += ReleaseJsCmd )

• IF you host assets on your app server - package it © BoldRadius, 2015 25

Page 26: How You Convince Your Manager To Adopt Scala.js in Production

Now you have a setup, whats next?

The real (fun) work begins...

You need to show your prospect that this works.

© BoldRadius, 2015 26

Page 27: How You Convince Your Manager To Adopt Scala.js in Production

You could...• Find an internal project that requires a UI

• Something your people care about.

• Interactive visual representation of your best stuff.

• Remove all the friction associated with scalajs

• Own the problems

© BoldRadius, 2015 27

Page 28: How You Convince Your Manager To Adopt Scala.js in Production

Tips• Console / dashboard all the things.

• Use websockets and make that server push

• Use a dark background

© BoldRadius, 2015 28

Page 29: How You Convince Your Manager To Adopt Scala.js in Production

Our experiment with akka clusterA distributed application with akka cluster presents an opportunity:

• What are the states of my clustered actors?

• What are the dependencies between them?

• What hardware are they on?

© BoldRadius, 2015 29

Page 30: How You Convince Your Manager To Adopt Scala.js in Production

cluster-console• Subscribe to any cluster's events

• Push events to UI with websockets + akka-http streams

• Safe client-server API with autowire + akka-http

• scalajs-react for ui components

• data binding with scalarx

© BoldRadius, 2015 30

Page 31: How You Convince Your Manager To Adopt Scala.js in Production

Acknowledgements@lihaoyi

• scalajs-react: David Barri @japgolly

• scalajs-spa-tutorial Otto Chrons @ochrons

© BoldRadius, 2015 31

Page 32: How You Convince Your Manager To Adopt Scala.js in Production

Highlightsd3 facade

package Layout { trait Layout extends js.Object { def force(): ForceLayout = js.native } trait ForceLayout extends js.Function { def size(mysize: js.Array[Double]): ForceLayout = js.native def charge(number: Double): ForceLayout = js.native def linkDistance(number: Double): ForceLayout = js.native def friction(number: Double): ForceLayout = js.native }}val force = d3.layout.force().size(List[Double](P.width, P.height).toJsArray).charge(-1500).linkDistance(1000).friction(0.9)

© BoldRadius, 2015 32

Page 33: How You Convince Your Manager To Adopt Scala.js in Production

Highlightsd3 inside scalajs-react

val component = ReactComponentB[Props]("Graph").initialStateP { P => val force = ... val (nodes, links) = // calculate Seq[GraphNode], Seq[GraphLink] State(nodes, links, force) }.backend(new Backend(_)) .render{(P, S, B) => svgtag(SvgAttrs.width := P.width, SvgAttrs.height := P.height)( drawLinks(S.links, P.mode), drawNodes(S.nodes, S.force, P.mode) ) }.componentWillMount { scope => scope.backend.startfixed()}.build

© BoldRadius, 2015 33

Page 34: How You Convince Your Manager To Adopt Scala.js in Production

HighlightsBack to arguing about more important things:

indexes.flatMap(index => indexes.filter(_ > index).map((index, _)))

vs for { index <- indexes eachOther <- indexes.filter(_ > index) tuple <- Some(index, eachOther) } yield tuple

© BoldRadius, 2015 34

Page 35: How You Convince Your Manager To Adopt Scala.js in Production

Demohttps://github.com/dsugden/cluster-console

© BoldRadius, 2015 35