Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using scala.js to compile only (and not override run) in SBT

Tags:

sbt

scala.js

I'm trying to use scalajs to just compile some scala sources to javascript and not modify anything else about the sbt environment, I don't want it to override the default behavior of the "run" sbt command.

Currently I've got a build.sbt that looks like:

import ScalaJSKeys._

scalaJSSettings

name := "foo"

organization := "com.example"

scalaVersion := "2.11.4"

compile <<= (compile in Compile) dependsOn (fastOptJS in Compile)

crossTarget in (fastOptJS in Compile) := ((classDirectory in Compile).value / "public" / "js")

libraryDependencies ++= {
val sprayVersion = "1.3.2"
val akkaVersion = "2.3.7"
Seq(
    "io.spray"            %%  "spray-can"     % sprayVersion,
    "io.spray"            %%  "spray-routing" % sprayVersion,
    "io.spray"            %%  "spray-servlet" % sprayVersion,
    "io.spray"            %%  "spray-testkit" % sprayVersion  % "test",
    "com.typesafe.akka"   %%  "akka-actor"    % akkaVersion,
    "com.typesafe.akka"   %%  "akka-testkit"  % akkaVersion   % "test",
    "org.specs2"          %%  "specs2-core"   % "2.3.11" % "test",
    "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
    "org.scala-lang.modules.scalajs" %%% "scalajs-jquery" % "0.6"
)}

Which compiles both the javascript and the scala just fine, but the problem is that this actually breaks an existing "run" command which I want to run plain old scala using the same discovery as the default sbt. My project is simple so I don't want to go down the multi-project route (as with the play-with-scalajs-example). I guess I probably need to remove the scalaJSSettings but then I don't know how to access the fastOptJS target so I can attach it as a dependency to compile after doing so.

like image 472
Kevin Avatar asked Sep 29 '22 05:09

Kevin


1 Answers

You must not do this. As soon as you put the scalaJSSettings in a project, all the sources will be compiled with the Scala.js compiler plugin.

This will indeed produce .class files, however, they contain things the basic Scala compiler does not emit and can therefore lead to binary incompatibility issues or unexpected behavior (see this post).

Instead, use a multi-project build:

import ScalaJSKeys._

organization := "com.example"
scalaVersion := "2.11.4"

val sprayVersion = "1.3.2"
val akkaVersion = "2.3.7"

lazy val foo = project.
  settings(
    name := "foo",
    compile <<= (compile in Compile) dependsOn (fastOptJS in Compile in bar),
    crossTarget in (fastOptJS in Compile in bar) :=
      ((classDirectory in Compile).value / "public" / "js"),
    libraryDependencies ++= Seq(
      "io.spray"            %%  "spray-can"     % sprayVersion,
      "io.spray"            %%  "spray-routing" % sprayVersion,
      "io.spray"            %%  "spray-servlet" % sprayVersion,
      "io.spray"            %%  "spray-testkit" % sprayVersion  % "test",
      "com.typesafe.akka"   %%  "akka-actor"    % akkaVersion,
      "com.typesafe.akka"   %%  "akka-testkit"  % akkaVersion   % "test",
      "org.specs2"          %%  "specs2-core"   % "2.3.11" % "test",
      "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
    )
  )


lazy val bar = project.
  settings(scalaJSSettings: _*).
  settings(
    name := "bar",
    libraryDependencies += "org.scala-lang.modules.scalajs" %%% "scalajs-jquery" % "0.6",
  )

This obviously also resolves the issue with the run command.

like image 125
gzm0 Avatar answered Oct 04 '22 04:10

gzm0