Search code examples
android-studiointellij-ideakotlin-multiplatformkotlin-js

How do I add a JS target to a KMM project?


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

Solution

  • 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