scalasbtasset-pipelinescala.jsfinch

Serving Scala.js assets


I've started new project with Finch and Scala.js, where backend and frontend need to share some code.

And I'm concerned about a good way to serve JS produced by fastOptJS by Finch. Currently, I'm using custom SBT task which copies files from js/target/scala-2.11/*.js to jvm/src/main/resources. But I wondering if there's a better way to do it.

I saw awesome SPA tutorial, which uses sbt-play-scalajs plugin, but It seems applicable only for Play.


Solution

  • One approach which I've used successfully involves 3 sbt projects and an additional folder at the root for static content:

    .
    ├── build.sbt
    ├── client
    ├── server
    ├── shared
    └── static
    

    In the build.sbt, you would then use something like the following:

    lazy val sharedSettings = Seq(
      // File changes in `/static` should never trigger new compilation
      watchSources := watchSources.value.filterNot(_.getPath.contains("static")))
    
    lazy val server = project
      .settings(sharedSettings: _*)
      // Adds `/static` to the server resources
      .settings(unmanagedResourceDirectories in Compile += baseDirectory.value / ".." / "static")
    
    lazy val client = project
      .enablePlugins(ScalaJSPlugin)
      .settings(sharedSettings: _*)
      // Changes Scala.js target folder to "/static/content/target"
      .settings(Seq(fullOptJS, fastOptJS, packageJSDependencies, packageScalaJSLauncher, packageMinifiedJSDependencies)
        .map(task => crossTarget in (Compile, task) := file("static/content/target")))
    

    All you assets can be accessed as standard resources, then will also get packaged into your fat jar if you use something like sbt-assembly.