How to set up a dependency between two Scala.js cross-projects in a multi-module build?
Asked Answered
H

1

0

Say I have two sub-projects, lib1 and lib2 with build.sbts that look like this:

lazy val libX = crossProject.in(file(".")).settings(
  ... // a bunch of settings
).jvmSettings(
  ... // a bunch of settings  
).jsSettings(
  ... // a bunch of settings
)

lazy val libXJVM = apiClient.jvm
lazy val libXJS = apiClient.js

I need to use them in another large multi-module project so that lib2 depends on lib1.

If I try this in the main build.sbt:

lazy val lib1 = crossProject.in(file("lib1"))

lazy val lib2 = crossProject.in(file("lib2")).dependsOn(lib1)

lazy val lib1JVM = lib1.jvm
...

then the project dependency seems to work but the settings from the libraries internal build.sbt files (e.g. libraryDependencies) are completely ignored and the build fails.

If I try this instead:

lazy val lib1JS = project.in(file("lib1"))
lazy val lib2JS = project.in(file("lib2")).dependsOn(lib1JS)

dependsOn is seemingly ignored and lib2 won't compile because it can't import types from lib1.

Is there any way to make this work without duplicating the crossProject settings in the main build file?

Hafnium answered 5/12, 2017 at 16:44 Comment(0)
E
4

If I understand correctly, you are trying to dependsOn (cross) projects that are defined in a completely separate build?

If that is the case, what you need are ProjectRef. There is no direct of CrossProjectRef, so you need to manually use ProjectRefs for the JVM and JS parts. It would look something like:

lazy val lib1JVM = ProjectRef(file("path/to/other/build", "lib1JVM")
lazy val lib1JS = ProjectRef(file("path/to/other/build", "lib1JS")

which you can then depend on with

lazy val myProject = crossProject
  .jvmConfigure(_.dependsOn(lib1JVM))
  .jsConfigure(_.dependsOn(lib1JS))

Note that I do not quite understand what you are trying to do with the lazy val lib2 = crossProject.in(file("lib2")).dependsOn(lib1) part of your question. If lib2 should depend on lib1, that dependency should already have been declared in the build of lib2. In your larger multi-module build that reuses lib1 and lib2, it is too late to add dependencies to lib2 which comes from another build.

Extricate answered 5/12, 2017 at 21:14 Comment(3)
I am basically trying to avoid having to go through the local ivy repository when iterating on the libraries. lib2 depends on lib1, both are intended to be used in other projects. Some subprojects in the current big project build depend on lib2, some depend on lib1. I tried adding both libs as git submodules to the main project and setting up their internal dependencies manually in the main build to avoid ivy resolution.Hafnium
Then what you need are indeed ProjectRefs. And in that case you do not need to declare the dependency from lib2 on lib1 in your build, since the ProjectRef for lib2 will correctly resolve all the settings and setup of lib2 from its own build, including its dependency on lib1.Extricate
But I can't avoid putting lib1 into lib2's libraryDependencies unless I hard-code relative paths to it in lib2's build file, can I? Something like this was quite straightforward in Maven, because it would first try to resolve all dependencies within the modules of a multi-project build and then if some were still missing it would try to find them externally. This allowed re-using the same build file for both publishing libraries to repos and using them in larger projects avoiding the repo altogether. So far it looks like this is not possible at all with sbt.Hafnium

© 2022 - 2024 — McMap. All rights reserved.