1

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:

  • First run Gradle task browserDevelopentRun (I don't understand magick behind it) and after browser opens and renders React SPA (single page application) you can
  • stop that task and then
  • start the Vert.x backend with task run.

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.

2 Answers 2

1

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"))
Sign up to request clarification or add additional context in comments.

1 Comment

Almost there! But instead of referring StaticHandler to other build location, I believe it's better to copy distribution into webroot.
0

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.

1 Comment

That's exactly what I am trying to avoid. Instead of starting 2 backends (the actual and other to host web UI) with CORS complications, use JS target to build SPA distribution and serve it with JVM backend The idea to develop backend on JVM target and UI on the JS target but be able to start backend with or without UI using Gradle

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.