Alternative scalajs/scala-native distribution mechanisms

this looks amazing! One thing that was not clear from reading the docs is if there is support for jvm-specific scala folders (in the way that there are scala version specific folders). (apologies if this question is equivalent to asking about “shared”)

Also, great to see contributors being upfront about the extent of support! We need more of this.

1 Like

No, it is not supported but should be very easy to add.

Awesome work, like you said before the only way to achieve this right now is with the use of ClassLoaders so you can support multiple instances of the same sbt-plugin (in this instance scala-js)

I wonder if it would be useful to add more explicit type of support for this either in sbt-crossproject or sbt itself (also with using ClassLoader to support multiple instances of the scala backend)? Not sure I can directly use this plugin because I happen to be using the shared folder (also I have seperate code for scala-js compared to JVM for specific Scala versions and this may even be the case for scala-native for performance reasons).

However its definitely very useful for people who want to just recompile their current project to JS without any code changes. Great to see that this is possible within SBT, just need to muck around with ClassLoader's.

@sjrd Does it make sense to make an issue with the SBT guys to explore solutions in this space?

I think I very much agree, and have been thinking about this for a while… I’m not sure how to move that forward—beyond new projects, don’t people just look at existing issues to figure whether a project is supported?
EDIT: I suspect they don’t, but I can’t quite tell. I had started drafting a forum post calling for explicit FOSS support levels, but I could not quite answer this question.

It’s not multiple instances of the same sbt plugin. That would be utterly impossible. There is only one sbt plugin at play here: sbt-dynscalajs 0.1.0. What we load via ClassLoader are multiple instances of the Scala.js linker (not of the Scala.js sbt plugin). Note that sbt core itself does exactly the same kind of manipulations to load multiple instances of scalac with ++! There is no “right now” in this approach, it’s always going to be like that.

Also note that cbt must do the same thing if it wants to support multiple versions of Scala.js in the same build. Just as it needs ClassLoaders to load multiple versions of Scala (at least I strongly suspect it does; I don’t know how else it could work).

Hum maybe my readme wasn’t very clear about this. A shared folder if perfectly fine. Under this model the equivalent is simply the base directory of a project. So for some project foo, foo/src/ acts as shared folder instead of foo/shared/src/. For platform-specific sources, see the issue I mentioned in my previous post.

No, the only reason that really prevents you from using this plugin right now is that it doesn’t support Scala Native. Someone (not me) would have to write a similar plugin for Scala Native, say sbt-dynscalanative. Then you can use both plugins in a build, and you get triple dynamic platform support. Indeed, the way it is written, sbt-dynscalajs` can very well be composed with another similar plugin.

Since I was advocating earlier not to fiddle with multiple versions of Scala Native at the moment, the first iterations of that plugin wouldn’t even have to use any ClassLoader, as it could statically link against the most recent version of the Scala Native linker. So even a non expert could do it, by copying and adapting the relevant parts of sbt-dynscalajs and sbt-scalanative.

I don’t there is a solution space. As I said above, the way sbt-dynscalajs does it is the way to support multiple versions of a linker in the same build. Unless I misunderstood what you mean here?

TL;DR

  1. For both application developers and library maintainers, always upgrade your Scala/Scala.js/Scala Native to the latest minor version to resolve any compatibility issues, e.g. Scala 2.11.+, Scala.js 0.6.+, Scala Native 0.3.+
  2. For library maintainers, cross build on two major Scala versions, e.g. 2.11.+ and 2.12.+
  3. For library maintainers, don’t cross build on different Scala.js or Scala Native major version. Instead, only support the latest Scala.js or Scala Native.

Ah I see, thanks for the explanation, getting some good understanding of how its working

Okay thanks, will ask if its possible to do something similar with scala-native

I meant if SBT can add an abstraction (different from sbt-plugins) specifically for different backends for Scala which could simplify this? It would be something long term but I assume its better to start planning at some point

Ah I see. At this point I have no idea what kind of abstraction sbt could provide that would simplify this. Yes, we need to deal with ClassLoaders, but it’s not such a big deal. And I fear that if sbt tried to abstract that away, it would abstract too much or too little for it to be usable. For example, for optimal performance, the Scala.js linker needs to have the appropriate in-memory caches, in particular the instance of Linker itself (for incremental linking). We could first need to abstract away a platform-independent linking API, but I don’t think Scala Native is ready for this; it requires a pretty high degree of maturity to get that far. Even in Scala.js we are still refining the Linker API.

Basically, I think it’s too early for that, even to start planning.

1 Like

Okay good to know, at least this thread has been quite productive in regards to being informative about the decision

1 Like