kuza
kuza

Reputation: 3031

How to glue together Vert.x web and Kotlin react using Gradle in Kotlin MPP

Problem

It is not clear to me how to configure the Kotlin MPP (multiplatform platform project) using Gradle (Kotlin DSL) to use Vert.x web for Kotlin/JVM target with Kotlin React on the Kotlin/JS target.

Update

You can check out updated minimal example for a working solution inspired by an approach of Alexey Soshin.

What I've tried

Have a look at my minimal example on GitHub of a Kotlin MPP with the Vert.x web server on the JVM target and Kotlin React on the JS target.

You can make it work if you:

After that, without refreshing the remaining SPA in the browser, you can confirm that it can communicate with the backend by pressing the button and it will alert received data.

Question

What are the possible ways/approaches to glue these two targets so when I run my application: JS target is assembled and served via JVM backend conveniently?

I am thinking that perhaps Gradle should trigger some of the Kotlin browser tasks and then make them available in some way for the Vert.x backend.

Upvotes: 1

Views: 235

Answers (2)

Alexey Soshin
Alexey Soshin

Reputation: 17721

If you'd like to run a single task, though, you need that your server task would depend on your JS compile. In your build.gradle add the following:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    dependsOn(tasks.getByName<org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack>("jsBrowserProductionWebpack"))
}

Now invoking run will also invoke WebPack.

Next you want to serve your files. There are different ways of doing it. One is to copy them to Vert.x resources directory using Gradle. Another is to point Vert.x to where WebPack puts them by default:

route().handler(StaticHandler.create("../../../distributions"))

Upvotes: 1

Alexey Soshin
Alexey Soshin

Reputation: 17721

There is a bunch of different things going on there.

First, both your Vert.x and Webpack run on the same port. Easiest way to fix that is to start Vert.x on some other port, like 18080:

.listen(18080, "localhost") { result ->

And then change your index.kt file to use that port:

 val result: SomeData = get("http://localhost:18080/data")

Because we run on different ports now, we also need to specify CORS handler:

       router.apply {
                    route().handler(CorsHandler.create("*"))

Last is the fact, that you cannot run two neverending Gradle tasks from the same process (ok, you can, but that's complicated). So what I suggest is that you open two Terminals, and run:

./gradlew run

In one, and

./gradlew jsBrowserDevelopmentRun

In another.

Having done all that, you should see this: enter image description here

Now, this is for development mode. For production mode, you probably don't want to run jsBrowserDevelopmentRun, but tie jsBrowserProductionWebpack to your run and server spa.js from your Vert.x app using StaticHandler. But this answer is already too long.

Upvotes: 0

Related Questions