Vadim Emelyanov
Vadim Emelyanov

Reputation: 35

Gradle multi-project build order using Kotlin script

I use Kotlin DSL script (.kts) for building. There the structure of my project is:

Root project 'demo'
+--- Project ':backend'
\--- Project ':frontend'

I need to build project frontend first, than backend. I tried

include(":frontend")
include(":backend)

and

include(":frontend", ":backend")

with and without : in settings.gradle.kts of root project, but still the order of build is alphabetical - backend, than frontend.

View source code on GitHub

Do you have any ideas what is wrong?

Upvotes: 0

Views: 749

Answers (1)

Bjørn Vester
Bjørn Vester

Reputation: 7600

There is nothing wrong. If you don't specify any inter-project dependencies, Gradle will execute them in alphabetical order. This should be fine if the two projects are unrelated, as they are now.

But let's say you like to build the frontend (using node) and then include those resources in the backend (using Spring Boot). Then you will need to make the backend depend on frontend project. Then Gradle will honor the dependency graph and build the frontend first.

There are many ways to do that. One is to use the java plugin in the frontend to build a jar file of your frontend resources. You can then make a normal project dependency to it. You could also make a dependency directly into the frontend project's "internal" build tasks, but that is a bit frowned upon. Or you could declare your own artifact, or do a it in a bunch of other different ways.

For the first approach, you can build a jar file of your frontend resources like this:

plugins {
    // ...
    id("java")
}

java {
    // Required to make the jar artifact compatible with your backend, which is configured for Java 1.8
    targetCompatibility = JavaVersion.VERSION_1_8
}

tasks.named("jar", Jar::class) {
    dependsOn("assembleFrontend")
    from("$buildDir/dist")
    into("static")
}

Then in the backend, depend on it like this:

dependencies {
    // ...
    runtimeOnly(project(":frontend"))
}

There are a few other things wrong with your build script as well.

  • The runtime configuration is deprecated; use runtimeOnly instead (for your spring-boot-devtools dependency).
  • A multi-project should only have a single settings.gradle file, but you have one in each project. Delete them except for the one in the root folder.
  • You have declared the org.siouan.frontend plugin twice: once using the recommended way and once using the "old" way. Remove the latter (everything in the buildscript block and the apply statement.

Also, while I am not familiar with the org.siouan.frontend plugin, it appears it does not declare inputs and outputs for you - probably because it is very generic. So to avoid running npm each time you build your backend (as you now have a dependency to the frontend), you should declare proper inputs and outputs for the frontend tasks like installFrontend and assembleFrontend.

Upvotes: 1

Related Questions