Basics of SBT dependencies management

Hi everyone!

I’m new to Scala and Scala.js and I’m struggling with some basic concepts, even before I actually start to think about application logic… And I must say I DO want to learn this, because I see so much potential in this language!

The main problems I run into are due to my lack of understanding of SBT dependencies and import statements. As an example, I cloned a starter project from scala-js-example-app, which includes the following build.sbt file:

// Turn this project into a Scala.js project by importing these settings
enablePlugins(ScalaJSPlugin, WorkbenchPlugin)

scalaVersion := "2.11.8"

name := "Example"

version := "0.1-SNAPSHOT"

libraryDependencies ++= Seq(
  "org.scala-js" %%% "scalajs-dom" % "0.9.1",
  "com.lihaoyi" %%% "scalatags" % "0.6.1",
  "com.lihaoyi" %%% "scalarx" % "0.3.2",
)

% sign

First, why do I sometimes see %, %% or even %%% in the dependencies definition? Why one, two or three signs? What do they mean?

Update dependencies

Second, is there a way to update all package dependencies, similar to npm update in Node.js? I included a package that somehow changed my Scala version:

[warn] Scala version was updated by one of library dependencies:

So I tried to change it manually in the build.sbt file, but that caused the application to crash.

Import from dependency

Finally, how am I supposed to know what the import statement is supposed to look like for a specific managed dependency? As an example, I included "com.mediamath" %%% "scala-json" % "1.0" as a dependency, but I must import json._ in my .scala file. If it weren’t for the documentation, how could’ve I guessed it?

Thanks helping a green Scala programmer! :crazy_face:

I struggle with sbt myself, but some quick answers

  • The single % is for java libraries, the %% appends the version of scala used, and should be use for scala libraries; the %%% is for scala-js (and scala native).
  • The import statement is based on package and object names, which in general may have nothing to do with the project name. So there is no way to know other than the specific package documentation.
  • Try to use a new enough version of scala (2.11.8 is old, try 2.12.4) as long as all the dependencies can handle it.

Did you update to Scala 2.11.12 or 2.12.4? Generally a patch-level update will be binary compatible (2.11.x → 2.11.y), while anything else will require all libraries to be recompiled. Also, since you’re using Scala.js, you’ll generally want to update that whenever you update Scala itself.

Thanks for the replies! Concerning my second question, I understand from your contributions that I need to ensure that all my imported dependencies are compatible with the Scala version I’m specifying.

However, the question remains: is there an easy way to update all packages at the same time with a simple command such as npm update, or do I have to go check each dependency myself, look at the latest compatible version and change it manually in the build.sbt file?

Perhaps I am barking to the wrong tree but sbt uses special regexes similar to maven.
Here is a quote from http://www.scala-sbt.org/release/docs/Library-Management.html:

Ivy can select the latest revision of a module according to constraints you specify. Instead of a fixed revision like “1.6.1”, you specify “latest.integration”, “2.9.+”, or “[1.0,)”. See the Ivy revisions documentation for details.

I wouldn’t really recommend automatically picking the latest version of every library anyway. If some library somewhere in your build makes an incompatible change suddenly your build starts failing.

https://github.com/rtimush/sbt-updates will tell you if you have out-of-date libraries

happy user: https://twitter.com/tpolecat/status/924003922791895040

1 Like

Note that this particular happy user is frequently unhappy with things.