SlideShare uma empresa Scribd logo
1 de 35
Baixar para ler offline
SCALA JAVASCRIPT
Katrin Shechtman
BoldRadius, Toronto, Canada
Dave Sugden
BoldRadius, Gatineau, Quebec
© BoldRadius, 2015 1
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
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
Who are we?
• Server Side scala/akka developers
• Relatively new to scalajs
• Have experience writing javascript for the front-end
© BoldRadius, 2015 4
Path to scalajs: shoulders of giants
Part 1
Like many others, our path to scalajs began with @lihaoyi
• scalatags
form(
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
Path to scalajs: shoulders of giants
Part 2
• scalarx
import rx._
val a = Var(1)
val b = Var(2)
val c = Rx{ a() + b() }
println(c()) // 3
a() = 4
println(c()) // 6
© BoldRadius, 2015 6
© BoldRadius, 2015 7
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
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
Javascript as Platform
(from lihaoyi.github.io/hands-on-scala-js)
• No install
• Everywhere
• Sandboxed security
© BoldRadius, 2015 10
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
A Javascript "setup" - Part 1
1. 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
A Javascript "setup" - Part 2
1. npm: package manager, downloading packages, resolving
dependencies
2. Mocha / Jasmine / Chai / sinon: Test framework
3. AngularJS / Ember / Backbone / React etc.
© BoldRadius, 2015 13
A Scala "setup"
You are already a scala expert and familiar with SBT:
You already have 2/3 of your "setup"
© BoldRadius, 2015 14
Scala, SBT, ScalaJsPlugin,
Webjars: the first 2/3...
© BoldRadius, 2015 15
The Final Third of your Setup
• scalajs-dom, scalatags
• scalarx
• scalajs-react
• autowire
• upickle
• sbt tasks and plugins
© BoldRadius, 2015 16
Scalajs really practical guide
https://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
1. MAKE SURE YOU SHARE!
Server/client code sharing - done right
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.4")
//build.sbt
import 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
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 A
mainEl.innerHTML = s"""
|<div>some stuff</div>
...
""".stripMargin
//option B
val parNode = doc.createElement("p")
...
mainEl.appendChild(parNode)
© BoldRadius, 2015 19
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
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
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
6. KEEP YOUR DATA IN SYNC!
"com.lihaoyi" %%% "scalarx" % "0.2.8"
© BoldRadius, 2015 23
7. TREAT YOUR AJAX CALLS WITH SOME SAFETY!
"com.lihaoyi" %%% "autowire" % "0.2.5"
//SHARED
trait 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
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
Now you have a setup, whats next?
The real (fun) work begins...
You need to show your prospect that this works.
© BoldRadius, 2015 26
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
Tips
• Console / dashboard all the things.
• Use websockets and make that server push
• Use a dark background
© BoldRadius, 2015 28
Our experiment with akka cluster
A 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
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
Acknowledgements
@lihaoyi
• scalajs-react: David Barri @japgolly
• scalajs-spa-tutorial Otto Chrons @ochrons
© BoldRadius, 2015 31
Highlights
d3 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
Highlights
d3 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
Highlights
Back 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
Demo
https://github.com/dsugden/cluster-console
© BoldRadius, 2015 35

Mais conteúdo relacionado

Mais procurados

Type-safe front-end development with Scala
Type-safe front-end development with ScalaType-safe front-end development with Scala
Type-safe front-end development with Scala
takezoe
 
Wakanda - apps.berlin.js - 2012-11-29
Wakanda - apps.berlin.js - 2012-11-29Wakanda - apps.berlin.js - 2012-11-29
Wakanda - apps.berlin.js - 2012-11-29
Alexandre Morgaut
 
End to-end W3C - JS.everywhere(2012) Europe
End to-end W3C - JS.everywhere(2012) EuropeEnd to-end W3C - JS.everywhere(2012) Europe
End to-end W3C - JS.everywhere(2012) Europe
Alexandre Morgaut
 

Mais procurados (20)

Scal`a`ngular - Scala and Angular
Scal`a`ngular - Scala and AngularScal`a`ngular - Scala and Angular
Scal`a`ngular - Scala and Angular
 
Type-safe front-end development with Scala
Type-safe front-end development with ScalaType-safe front-end development with Scala
Type-safe front-end development with Scala
 
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
 
An Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemAn Intense Overview of the React Ecosystem
An Intense Overview of the React Ecosystem
 
Wakanda - apps.berlin.js - 2012-11-29
Wakanda - apps.berlin.js - 2012-11-29Wakanda - apps.berlin.js - 2012-11-29
Wakanda - apps.berlin.js - 2012-11-29
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
2015 Java update and roadmap, JUG sevilla
2015  Java update and roadmap, JUG sevilla2015  Java update and roadmap, JUG sevilla
2015 Java update and roadmap, JUG sevilla
 
End to-end W3C - JS.everywhere(2012) Europe
End to-end W3C - JS.everywhere(2012) EuropeEnd to-end W3C - JS.everywhere(2012) Europe
End to-end W3C - JS.everywhere(2012) Europe
 
React Vs AnagularJS
React Vs AnagularJSReact Vs AnagularJS
React Vs AnagularJS
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015
 
angular-wakanda ngParis meetup 15 at 42
angular-wakanda ngParis meetup 15 at 42angular-wakanda ngParis meetup 15 at 42
angular-wakanda ngParis meetup 15 at 42
 
Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0 Single Page Applications with AngularJS 2.0
Single Page Applications with AngularJS 2.0
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
 
Migrating to Java 9 Modules
Migrating to Java 9 ModulesMigrating to Java 9 Modules
Migrating to Java 9 Modules
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Moving To The Client - JavaFX and HTML5
Moving To The Client - JavaFX and HTML5Moving To The Client - JavaFX and HTML5
Moving To The Client - JavaFX and HTML5
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshop
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5
 
The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)
 

Destaque

Curriculum
CurriculumCurriculum
Curriculum
thipik
 
Pow séminaire "Divine Protection"
Pow séminaire "Divine Protection"Pow séminaire "Divine Protection"
Pow séminaire "Divine Protection"
Alkauthar
 

Destaque (20)

Quick typescript vs scala slide
Quick typescript vs scala slideQuick typescript vs scala slide
Quick typescript vs scala slide
 
Full Stack Scala
Full Stack ScalaFull Stack Scala
Full Stack Scala
 
Getting started with typescript and angular 2
Getting started with typescript  and angular 2Getting started with typescript  and angular 2
Getting started with typescript and angular 2
 
Roslyn: another introduction
Roslyn: another introductionRoslyn: another introduction
Roslyn: another introduction
 
NuGet vs Maven
NuGet vs MavenNuGet vs Maven
NuGet vs Maven
 
Empirics of standard deviation
Empirics of standard deviationEmpirics of standard deviation
Empirics of standard deviation
 
Scala: Collections API
Scala: Collections APIScala: Collections API
Scala: Collections API
 
Code Brevity in Scala
Code Brevity in ScalaCode Brevity in Scala
Code Brevity in Scala
 
Value Classes in Scala | BoldRadius
Value Classes in Scala | BoldRadiusValue Classes in Scala | BoldRadius
Value Classes in Scala | BoldRadius
 
Curriculum
CurriculumCurriculum
Curriculum
 
Partial Functions in Scala
Partial Functions in ScalaPartial Functions in Scala
Partial Functions in Scala
 
Test
TestTest
Test
 
Paul Partlow Highlighted Portfolio
Paul Partlow Highlighted PortfolioPaul Partlow Highlighted Portfolio
Paul Partlow Highlighted Portfolio
 
Pattern Matching in Scala
Pattern Matching in ScalaPattern Matching in Scala
Pattern Matching in Scala
 
Pow séminaire "Divine Protection"
Pow séminaire "Divine Protection"Pow séminaire "Divine Protection"
Pow séminaire "Divine Protection"
 
Taste of korea
Taste of koreaTaste of korea
Taste of korea
 
Cold drawn guide rail, Elevator guide Rail India
Cold drawn guide rail, Elevator guide Rail IndiaCold drawn guide rail, Elevator guide Rail India
Cold drawn guide rail, Elevator guide Rail India
 
What Are For Expressions in Scala?
What Are For Expressions in Scala?What Are For Expressions in Scala?
What Are For Expressions in Scala?
 
Functional Programming - Worth the Effort
Functional Programming - Worth the EffortFunctional Programming - Worth the Effort
Functional Programming - Worth the Effort
 
Presentation1
Presentation1Presentation1
Presentation1
 

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

Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
jaxconf
 
Introduction to Microsoft Flow and Azure Functions
Introduction to Microsoft Flow and Azure FunctionsIntroduction to Microsoft Flow and Azure Functions
Introduction to Microsoft Flow and Azure Functions
BIWUG
 

Semelhante a How You Convince Your Manager To Adopt Scala.js in Production (20)

Custom Runtimes for the Cloud
Custom Runtimes for the CloudCustom Runtimes for the Cloud
Custom Runtimes for the Cloud
 
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
Amazon Web Services and PaaS - Enterprise Java for the Cloud Era? - Mark Pric...
 
Part 3: Models in Production: A Look From Beginning to End
Part 3: Models in Production: A Look From Beginning to EndPart 3: Models in Production: A Look From Beginning to End
Part 3: Models in Production: A Look From Beginning to End
 
Multi-tenancy with Rails
Multi-tenancy with RailsMulti-tenancy with Rails
Multi-tenancy with Rails
 
DevOps and Decoys How to Build a Successful Microsoft DevOps Including the Data
DevOps and Decoys  How to Build a Successful Microsoft DevOps Including the DataDevOps and Decoys  How to Build a Successful Microsoft DevOps Including the Data
DevOps and Decoys How to Build a Successful Microsoft DevOps Including the Data
 
#SPSBrussels 2017 vincent biret #azure #functions microsoft #flow
#SPSBrussels 2017 vincent biret #azure #functions microsoft #flow#SPSBrussels 2017 vincent biret #azure #functions microsoft #flow
#SPSBrussels 2017 vincent biret #azure #functions microsoft #flow
 
Introduction to Microsoft Flow and Azure Functions
Introduction to Microsoft Flow and Azure FunctionsIntroduction to Microsoft Flow and Azure Functions
Introduction to Microsoft Flow and Azure Functions
 
SUG Bangalore - Kick Off Session
SUG Bangalore - Kick Off SessionSUG Bangalore - Kick Off Session
SUG Bangalore - Kick Off Session
 
Azure DevOps Tasks.pptx
 Azure DevOps Tasks.pptx Azure DevOps Tasks.pptx
Azure DevOps Tasks.pptx
 
MongoDB.local Seattle 2019: MongoDB Stitch Tutorial
MongoDB.local Seattle 2019: MongoDB Stitch TutorialMongoDB.local Seattle 2019: MongoDB Stitch Tutorial
MongoDB.local Seattle 2019: MongoDB Stitch Tutorial
 
Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)
 
Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)
 
Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)Staying Sane with Drupal (A Develper's Survival Guide)
Staying Sane with Drupal (A Develper's Survival Guide)
 
Utilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done Faster
 
Azure + DataStax Enterprise Powers Office 365 Per User Store
Azure + DataStax Enterprise Powers Office 365 Per User StoreAzure + DataStax Enterprise Powers Office 365 Per User Store
Azure + DataStax Enterprise Powers Office 365 Per User Store
 
Why and How SmartNews uses SaaS?
Why and How SmartNews uses SaaS?Why and How SmartNews uses SaaS?
Why and How SmartNews uses SaaS?
 
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
 
Creating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJSCreating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJS
 
The Future of Cloud Innovation, featuring Adrian Cockcroft
The Future of Cloud Innovation, featuring Adrian CockcroftThe Future of Cloud Innovation, featuring Adrian Cockcroft
The Future of Cloud Innovation, featuring Adrian Cockcroft
 
MongoDB.local Atlanta: MongoDB Stitch Tutorial
MongoDB.local Atlanta: MongoDB Stitch TutorialMongoDB.local Atlanta: MongoDB Stitch Tutorial
MongoDB.local Atlanta: MongoDB Stitch Tutorial
 

Mais de BoldRadius Solutions

Mais de BoldRadius Solutions (12)

Introduction to the Typesafe Reactive Platform
Introduction to the Typesafe Reactive PlatformIntroduction to the Typesafe Reactive Platform
Introduction to the Typesafe Reactive Platform
 
Towards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The BayTowards Reliable Lookups - Scala By The Bay
Towards Reliable Lookups - Scala By The Bay
 
Introduction to the Actor Model
Introduction to the Actor ModelIntroduction to the Actor Model
Introduction to the Actor Model
 
Why Not Make the Transition from Java to Scala?
Why Not Make the Transition from Java to Scala?Why Not Make the Transition from Java to Scala?
Why Not Make the Transition from Java to Scala?
 
String Interpolation in Scala | BoldRadius
String Interpolation in Scala | BoldRadiusString Interpolation in Scala | BoldRadius
String Interpolation in Scala | BoldRadius
 
Scala Days Highlights | BoldRadius
Scala Days Highlights | BoldRadiusScala Days Highlights | BoldRadius
Scala Days Highlights | BoldRadius
 
Domain Driven Design Through Onion Architecture
Domain Driven Design Through Onion ArchitectureDomain Driven Design Through Onion Architecture
Domain Driven Design Through Onion Architecture
 
What are Sealed Classes in Scala?
What are Sealed Classes in Scala?What are Sealed Classes in Scala?
What are Sealed Classes in Scala?
 
How To Use Higher Order Functions in Scala
How To Use Higher Order Functions in ScalaHow To Use Higher Order Functions in Scala
How To Use Higher Order Functions in Scala
 
Immutability in Scala
Immutability in ScalaImmutability in Scala
Immutability in Scala
 
Scala Days 2014: Pitching Typesafe
Scala Days 2014: Pitching TypesafeScala Days 2014: Pitching Typesafe
Scala Days 2014: Pitching Typesafe
 
Demonstrating Case Classes in Scala
Demonstrating Case Classes in ScalaDemonstrating Case Classes in Scala
Demonstrating Case Classes in Scala
 

Último

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 

Último (20)

%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 

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

  • 1. SCALA JAVASCRIPT Katrin Shechtman BoldRadius, Toronto, Canada Dave Sugden BoldRadius, Gatineau, Quebec © BoldRadius, 2015 1
  • 2. 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
  • 3. 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
  • 4. Who are we? • Server Side scala/akka developers • Relatively new to scalajs • Have experience writing javascript for the front-end © BoldRadius, 2015 4
  • 5. Path to scalajs: shoulders of giants Part 1 Like many others, our path to scalajs began with @lihaoyi • scalatags form( 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
  • 6. Path to scalajs: shoulders of giants Part 2 • scalarx import rx._ val a = Var(1) val b = Var(2) val c = Rx{ a() + b() } println(c()) // 3 a() = 4 println(c()) // 6 © BoldRadius, 2015 6
  • 8. 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
  • 9. 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
  • 10. Javascript as Platform (from lihaoyi.github.io/hands-on-scala-js) • No install • Everywhere • Sandboxed security © BoldRadius, 2015 10
  • 11. 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
  • 12. A Javascript "setup" - Part 1 1. 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
  • 13. A Javascript "setup" - Part 2 1. npm: package manager, downloading packages, resolving dependencies 2. Mocha / Jasmine / Chai / sinon: Test framework 3. AngularJS / Ember / Backbone / React etc. © BoldRadius, 2015 13
  • 14. A Scala "setup" You are already a scala expert and familiar with SBT: You already have 2/3 of your "setup" © BoldRadius, 2015 14
  • 15. Scala, SBT, ScalaJsPlugin, Webjars: the first 2/3... © BoldRadius, 2015 15
  • 16. The Final Third of your Setup • scalajs-dom, scalatags • scalarx • scalajs-react • autowire • upickle • sbt tasks and plugins © BoldRadius, 2015 16
  • 17. Scalajs really practical guide https://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
  • 18. 1. MAKE SURE YOU SHARE! Server/client code sharing - done right addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.4") //build.sbt import 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
  • 19. 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 A mainEl.innerHTML = s""" |<div>some stuff</div> ... """.stripMargin //option B val parNode = doc.createElement("p") ... mainEl.appendChild(parNode) © BoldRadius, 2015 19
  • 20. 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
  • 21. 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
  • 22. 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
  • 23. 6. KEEP YOUR DATA IN SYNC! "com.lihaoyi" %%% "scalarx" % "0.2.8" © BoldRadius, 2015 23
  • 24. 7. TREAT YOUR AJAX CALLS WITH SOME SAFETY! "com.lihaoyi" %%% "autowire" % "0.2.5" //SHARED trait 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
  • 25. 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
  • 26. Now you have a setup, whats next? The real (fun) work begins... You need to show your prospect that this works. © BoldRadius, 2015 26
  • 27. 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
  • 28. Tips • Console / dashboard all the things. • Use websockets and make that server push • Use a dark background © BoldRadius, 2015 28
  • 29. Our experiment with akka cluster A 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
  • 30. 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
  • 31. Acknowledgements @lihaoyi • scalajs-react: David Barri @japgolly • scalajs-spa-tutorial Otto Chrons @ochrons © BoldRadius, 2015 31
  • 32. Highlights d3 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
  • 33. Highlights d3 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
  • 34. Highlights Back 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