SBT 0.13.6+ : SBT cross building : separate library dependency versions for each SBT/Scala version

As of SBT 0.13.6, the feature to target multiple SBT versions has been integrated into SBT itself, so we no longer have to import the sbt-cross-building plugin to do so.

I haven't seen a guide/example for declaring separate libraryDependencies for each SBT version with SBT 0.13.6+, which is why I've decided to create a guide for it.

Before we begin, I want to first clarify that only SBT plugins need to target multiple SBT versions. Other Scala libraries should only need to target multiple Scala versions.


To target multiple SBT versions in SBT 0.13.6+, simply configure crossSbtVersions:

crossSbtVersions := Seq("0.13.16", "1.0.3", "1.1.0")

To declare different libraryDependencies for each SBT version:

libraryDependencies ++= (
  (sbtBinaryVersion in pluginCrossBuild).value match {
    case "0.13" => Seq(
      "groupId" %% "artifactId" % "version",
      ...
    )
    case "1.0" | "1.1" => Seq(
      "groupId" %% "artifactId" % "version",
      ...
    )
  }
)

  • omit the default case so that SBT will throw a MatchError if none of the cases are matched.
  • sbtBinaryVersion is used instead of sbtVersion so that you only have to match the major + minor version, and not the patch version. Use sbtVersion instead if you need to declare different libraryDependencies for different patch versions.
  • sbtBinaryVersion must be scoped to pluginCrossBuild, else it will return the binary compatibility version substring of the sbt.version in project/build.properties.

Then run:

^ compile


Similarly to older SBT versions, to target multiple Scala versions, simply configure crossScalaVersions:

crossScalaVersions := Seq("2.10.6", "2.11.11", "2.12.4")

To declare different libraryDependencies for each SBT version:

libraryDependencies ++= (
  scalaBinaryVersion.value match {
    case "2.10" => Seq(
      "groupId" %% "artifactId" % "version",
      ...
    )
    case "2.12" => Seq(
      "groupId" %% "artifactId" % "version",
      ...
    )
    case "2.13" => Seq(
      "groupId" %% "artifactId" % "version",
      ...
    )
  }
)

  • omit the default case so that SBT will throw a MatchError if none of the cases are matched.
  • scalaBinaryVersion is used instead of scalaVersion so that you only have to match the major + minor version, and not the patch version. Use scalaVersion instead if you need to declare different libraryDependencies for different patch versions.
  • From my experience, Scala Release Candidate(RC)/Milestone(M) versions may not have their scalaBinaryVersion properly configured. If you obtain a MatchError, try matching against the full Scala version String instead of just the major + minor version.

Then run:

+ publish

If React.js is too hard, learn Vue.js first

For someone like me who comes from an OOP background, and hadn't touched any JavaScript since the advent of Node.js, learning React.js can be really hard. If you find yourself struggling to learn to learn React.js, I recommend learning Vue.js first.

Now, why can React.js be hard to learn? To use React.js, you first need to understand JavaScript, Node.js, NPM/Yarn, Webpack, Babel, JSX. That is a whole lot of things to learn at once before you can even write your first line of code. Sure, you can use React.js without any of that (with CDN), but almost every example/tutorial of React.js out there is written in JSX.

What is JSX? JSX is an XML-like template that compiles to JavaScript. Eg.

<h1>Hello World</h1>
compiles to:
React.createElement('h1', null, 'Hello World')

The JSX to JavaScript conversion is performed using a JSX to JavaScript transpiler, the most popular being Babel. Babel also allows you to use the latest JavaScript features even before they are supported by your targeted environment, by transpiling them down to ES5 code. This is usually automated using Webpack, a build tool for JavaScript. NPM/Yarn is a dependency manager for JavaScript, which is required to download loaders/plugins for Webpack. Node.js is a JavaScript engine that allows you to execute JavaScript code outside of a web browser.

So, how is Vue.js easier to learn? Vue.js comes with its own template, that can be used without any other external dependency. That means you can learn Vue.js without having to learn Node.js, NPM/Yarn, Webpack, Babel, JSX, etc. beforehand. After getting familiar with Vue's template syntax and its concepts, you can then slowly incorporate the aforementioned tools into your project to improve performance, development time, maintainability, etc. (I may elaborate more on this in a separate blog post).

Once you've mastered all of the concepts and required tools, it should be extremely easy to learn React.js, if you still wish to do so.

Edit: Apparently there are starter kits for React.js (eg. create-react-app) that comes pre-configured with all the aforementioned tools and more (eg. Flow, ESLint). These really should be included in React's User Guide.

GitHub – daniel-shuy

Daniel Shuy

Malaysia

Full-stack polyglot developer