user2975535 user2975535 - 4 months ago 16
Scala Question

Can't import from CrossType.Pure sbt project in Scala

I'm trying to make Play framework project with Scala.js on frontend and one shared project. My sbt configuration is:

import sbt.Project.projectToRef

lazy val scalaV = "2.11.8"

lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared"))
.settings(
scalaVersion := scalaV,
libraryDependencies ++= Seq(
"com.mediamath" %%% "scala-json" % "1.0"
),
resolvers += "mmreleases" at "https://artifactory.mediamath.com/artifactory/libs-release-global",
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
)
// set up settings specific to the JS project
.jsConfigure(_ enablePlugins ScalaJSPlay)


lazy val sharedJVM = shared.jvm.settings(name := "sharedJVM")

lazy val sharedJS = shared.js.settings(name := "sharedJS")

lazy val root = (project in file(".")).settings(
scalaVersion := scalaV,
scalaJSProjects := jsProjects,
pipelineStages := Seq(scalaJSProd, gzip),
routesGenerator := InjectedRoutesGenerator,
scalikejdbcSettings,
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
evolutions,
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test,
"mysql" % "mysql-connector-java" % "5.1.39",
"com.vmunier" % "play-scalajs-scripts_2.11" % "0.5.0"
),
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
).
enablePlugins(PlayScala).
aggregate(jsProjects.map(projectToRef): _*)

lazy val jsProjects = Seq(js)


lazy val js = (project in file("client")).settings(
scalaVersion := scalaV,
persistLauncher := true,
persistLauncher in Test := false,
autoCompilerPlugins := true,
scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature"),
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "0.9.0",
"com.mediamath" %%% "scala-json" % "1.0"
),
resolvers += "mmreleases" at "https://artifactory.mediamath.com/artifactory/libs-release-global",
resolvers += Resolver.sonatypeRepo("releases"),
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
).enablePlugins(ScalaJSPlugin, ScalaJSPlay)


Everything is working fine but the problem is: I can't import anything from shared project in Scala.js and Play Framework project. Here is how my shared project structure looks:
enter image description here

And here is how I'm trying to import it:

import services.Encryptor


At compile time I got error:


not found: object services [error] import services.Encryptor


How this issue can be fixed?

Answer

First of all, never ever (!) do this:

lazy val sharedJVM = shared.jvm.settings(name := "sharedJVM")
lazy val sharedJS = shared.js.settings(name := "sharedJS")

This creates new projects that are picked up by sbt, so the cross project does not hold the right projects anymore. See docs for details.

Instead, use jsSettings and jvmSettings:

(crossProject.crossType(CrossType.Pure) in file("shared"))
  // snip
  .jsSettings(name := "sharedJS")
  .jvmSettings(name := "sharedJVM")

In your build, it seems that your js project does not depend on the shared project. So if course the shared project's contents are not available.

You need to

lazy val js = (project in file("client"))
  // snip
  .dependsOn(shared.js)