It doesn’t work the same because
scalajs-library.jar is cross-compiled on the binary version, whereas the compiler is cross-compiled on the full version.
scalajs-library_2.12-0.6.20.jar is the standard library for the 2.12 eco-system, version 0.6.20, and it is based on the Scala std lib sources of 2.12.3 because that was the most recent version as of the release of Scala.js 0.6.20.
scalajs-compiler_2.12.3-0.6.20.jar is the compiler plugin for 2.12.3 specifically, version 0.6.20.
This means that when 2.12.4 comes along, we just go back to the tag
v0.6.20, and can publish
scalajs-compiler_2.12.4-0.6.20.jar after the fact. This works because it is a new artifact on Maven. We cannot do the same for
scalajs-library_2.12-0.6.20.jar, because that artifact already exists, and we cannot change it.
So then the natural question is: why don’t we also cross-version
scalajs-library on the full version? Well then, we have an even bigger problem. If a library
A was compiled with
scalaVersion := "2.12.3", it will depend on
scalajs-library_2.12.3. And then if another project
B which depends on
scalaVersion := "2.12.4", it will depend on
scalajs-library_2.12.4. Now you end up with two versions of
scalajs-library on the classpath, instead of one being evicted by ivy resolution. And that’s really bad.
If we want ivy to evict the older
scalajs-library, we need to use the Scala version number as the artifact version. But then where do we put the Scala.js version number? Do we combine the two version numbers to publish
0.6.20.2.12.3? That’s no good because
0.6.21.2.12.1 would evict it? If we switch them, we have the reversed problem, obviously.
This double-version problem means that one Scala.js version can only ever be built for one version of the Scala std lib. And hence once 0.6.20 has been released based on 2.12.3, the only way you can possibly get the 2.12.4 std lib is to wait for Scala.js 0.6.21.