4

I have an AndrodiStudio KMM project and I'd like to add a JS target.

Given that JS development is only available in IntelliJ, I'd expect that I have to open the project in IDEA add a "Module" -- but I don't even know which one to choose -- none of them seem to be a "right" fit:

  • In the Gradle section, there is "Kotlin/JS for browser and "Kotlin/JVM". Adding "Kotlin/JS" breaks* the Gradle build for the whole project. "Kotlin/Multiplatform" doesn't sound like what I want since I already have the "shared" module for that (although it doesn't include JS)

  • In the Kotlin section, there is "KS | IDEA". Obviously, I don't want to add something based on the "IDEA build system" to a gradle.kts based project.

So my question is:

  • Which module template is the best starting point for adding "jsApp" (or webApp) alongside "iosApp" and "androidApp" (in AndroidStudio or Idea?)?

  • What do I need to add to "shared/build.gradle.kts" to support "jsMain" and "jsTest" folders? Is there a different / better starting point (e.g. tutorial or minimal "helloWorld" sample on Github covering all platforms)?

The current structure of my code corresponds 1:1 to the KMM project template in Android Studio: https://github.com/stefanhaustein/komponents

*) The error message:

Error resolving plugin [id: 'org.jetbrains.kotlin.multiplatform', version: '1.4.31']
> Plugin request for plugin already on the classpath must not include a version
Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51
  • Would also be interested to know why this Q is being downvoted? Am I overlooking something simple? Is this the wrong substack? – Stefan Haustein Mar 21 '21 at 13:28
  • 1
    Hello! Basically, you need just to add `js()` target at your `shared/build.gradle.kts`. See [this](https://kotlinlang.org/docs/mpp-set-up-targets.html) doc page. After that, add your code to the `/src/jsMain/kotlin`. I agree that the documentation might be unclear on adding new targets, worth creating an issue at the Kotlin's issue tracker: kotl.in/issue – Artyom Degtyarev Mar 22 '21 at 11:26
  • 1
    Thanks, I got it working by manually copying bits of the kotlin/js template... (your link doesn't describe what needs to go into `js()`. I have filed an issue as suggested here: https://youtrack.jetbrains.com/issue/KT-45612 and here: https://github.com/Kotlin/kmm-sample/issues/55 -- will add an answer with what I needed to do later here. – Stefan Haustein Mar 23 '21 at 10:55

1 Answers1

5

Got it working by creating a new Kotlin/JS project and copying it over to jsApp in the KMM project (parallel to iosApp etc.) The minimum jsApp/build.gradle.kts seems to be:

plugins {
    kotlin("js")
}

dependencies {
    implementation(project(":shared"))
}

kotlin {
    js() {
        browser {
        }
    }
}

In shared/build.gradle.kts, I needed to add the following snippet to the kotlin section (parallel to android() and ios{...}

    js {
        browser {     
        }
    }

Pitfalls why this took me longer than one would expect:

  • Bad time with forgetting .kts in build.gradle.kts and fantastic error messages
  • Because the jsApp build.gradle.kts is now nested, the kotlin plugin can't have a version there apparently (guess it makes sense for consistency).
  • The js source file name in index.html needs to match the module name (jsApp in my case).
  • Don't forget include(":jsApp")in settings.gradle.kts

Recommended steps:

  • Try to first get the "web" module working
  • Use a gradle based run configuration
  • Only when the web sample project works in the new structure, wire up the shared code
Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51