@import BookData._ @def lazyload(id: String) = script(raw(s""" window.addEventListener("load", function(){ document.getElementById("$id").src = 'https://hands-on-scala-js.herokuapp.com/' }) """)) @p Historically, sharing code across client & server has been a holy-grail for web development. There are many things which have made it hard in the past: @ul @li Javascript on the client v.s. PHP/Perl/Python/Ruby/Java on the client @li Most back-ends make heavy use of C extensions, and front-end code was tightly coupled to the DOM. Even if you manage to port the main language @p There have been some attempts in recent years with more traction: Node.js, for example, has been very successful at running Javascript on the server, the Clojure/Clojurescript community has their own version of cross-built code, and there are a number of smaller, more esoteric platforms. @p Scala.js lets you share code between client and server relatively straightforwardly. As we saw in the previous chapter, where we made a shared module. Let's work to turn that shared module into a working client-server application! @val server = wd/'examples/'crossBuilds/'clientserver/'server/'src/'main/'scala/'simple @val client = wd/'examples/'crossBuilds/'clientserver/'client/'src/'main/'scala/'simple @sect{A Client-Server Setup} @p Getting started with client-server integration, let's go with the simplest configuration possible: a Spray server and a Scala.js client. Most of the other web-frameworks (@lnk.misc.Play, @lnk.misc.Scalatra, etc.) will have more complex configurations, but the basic mechanism of wiring up Scala.js to your web framework will be the same. Our project will look like this: @hl.bash $ tree . ├── build.sbt ├── client │   ├── shared/main/scala/simple/FileData.scala │   └── src/main/scala/simple/Client.scala ├── project │   └── build.sbt └── server ├── shared -> ../client/shared └── src/main/scala/simple ├── Page.scala └── Server.scala @p First, let's do the wiring in @code{build.sbt}: @hl.ref(wd/'examples/'crossBuilds/'clientserver/"build.sbt") @p We have two projects: @code{client} and @code{server}, one of which is a Scala.js project (indicated by the presence of @hl.scala{scalaJSSettings}). Both projects share a number of settings: the presence of the @code{shared/} folder, which shared code can live in (similar to what we saw in @sect.ref{Cross Publishing Libraries}) and the settings to add @lnk.github.Scalatags and @lnk.github.uPickle to the build. Note that those two dependencies use the triple @code{%%%} instead of the double @code{%%} to declare: this means that for each dependency, we will pull in the Scala-JVM or Scala.js version depending on whether it's being used in a Scala.js project. Note also the @hl.scala{packageArchetype.java_application} setting, which isn't strictly necessary depending on what you want to do with the application, but this example needs it as part of the deployment to Heroku. @p The @code{client} subproject is uneventful, with a dependency on the by-now-familiar @code{scalajs-dom} library. The @code{server} project, on the other hand, is interesting: it contains the dependencies required for us to set up out Spray server, and one additional thing: we add the output of @code{fastOptJS} from the client to the @code{resources} on the server. This will allow the @code{server} to serve the compiled-javascript from our @code{client} project from its resources. @p Next, let's kick off the Spray server in our Scala-JVM main method: @hl.ref(server/"Server.scala") @p This is a not-very-interesting @lnk("spray-routing", "http://spray.io/documentation/1.2.2/spray-routing/") application: we set up a server on @code{localhost:8080}, have the root URL serve the main page on GET, and have other GET URLs serve resources. This includes the @code{js-fastopt.js} file that is now in our resources because of our @code{build.sbt} config earlier! We also add a POST route to allow the client ask the server to list files various directories. @p The HTML template @hl.scala{Page.skeleton} is not shown above; I put it in a separate file for neatness: @hl.ref(server/"Page.scala") @p This is a typical @lnk.github.Scalatags HTML snippet. Note that since we're serving it directly from the server in Scala code, we do not need to leave a @code{.html} file somewhere on the filesystem! We can declare all HTML, including the skeleton of the page, in Scalatags. Otherwise it's the same as what we saw in earlier chapters: A simple HTML page which includes a script tag to run our Scala.js application. @p Lastly, we'll set up the Scala.js main method, which we are calling in the @hl.html{