https://kotlinlang.org logo
#javascript
Title
# javascript
r

Reuben Firmin

11/28/2023, 5:05 PM
what in the gradle config tells it which js files to compile? i have src/jsMain/kotlin/ah/view/DarkMode.kt as an initial file that i want to build and have included in my backend project. i can see that kotlin is building and producing main.bundle.js (configuration in thread) but that file doesn't include the source from my DarkMode.kt
Copy code
kotlin {
    jvm {
        jvmToolchain(17)
        withJava()
        testRuns.named("test") {
            executionTask.configure {
                useJUnitPlatform()
            }
        }
    }
    js {
        binaries.executable()
        browser {
            commonWebpackConfig {
                cssSupport {
                    enabled.set(true)
                }
            }
            runTask {
                outputFileName = "main.bundle.js"
                sourceMaps = true
                devServer = KotlinWebpackConfig.DevServer(
                    open = false,
                    port = 3000,
                    proxy = null,
                    static = mutableListOf("$buildDir/processedResources/js/main")
                )
            }
            webpackTask {
                outputFileName = "main.bundle.js"
                output.libraryTarget = "commonjs2"
            }
        }
    }

    sourceSets {
        val commonMain by getting
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val jvmMain by getting {
            dependencies {
                implementation(platform("org.http4k:http4k-bom:${http4kVersion}"))
                implementation("org.http4k:http4k-client-okhttp:${http4kVersion}")
                implementation("org.http4k:http4k-core:${http4kVersion}")
                implementation("org.http4k:http4k-format-jackson:${http4kVersion}")
                implementation("org.http4k:http4k-server-jetty:${http4kVersion}")
                implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
                implementation("org.jetbrains.kotlinx:kotlinx-html:0.9.1")
                implementation("org.hotswapagent:hotswap-agent-core:1.4.0")
            }
        }
        val jvmTest by getting

        val jsMain by getting {
            dependencies {
                implementation(npm("tailwindcss", "3.3.5"))
                implementation(npm("flowbite", "2.0.0"))
                implementation(npm("<http://htmx.org|htmx.org>", "1.9.6"))
            }
        }
        val jsTest by getting
    }
}
a

Artem Kobzar

11/28/2023, 5:23 PM
How did you understand that the sources were not included? I'm asking just to understand the problem
r

Reuben Firmin

11/28/2023, 5:26 PM
fair enough, might be a false assumption. however, I'm looking in the bundled main.bundle.js and not seeing string literals that are in my kt class. i also looked in sourcemap and don't see the class referred to
a

Artem Kobzar

11/28/2023, 5:54 PM
Do you use this class in your code? In production it could be eliminated if it's not in use and is not annotated with JsExport.
r

Reuben Firmin

11/28/2023, 5:56 PM
that could be what's going on. i'm intending to import main.bundle.js from the backend. this is a kotlinx.html / htmlx project, i.e. backend driven, so i need a js library rather than a spa-driven ui
a

Artem Kobzar

11/28/2023, 6:08 PM
You can try to annotate the class with @JsExport and check if it presents inside the bundle
r

Reuben Firmin

11/28/2023, 6:10 PM
nice! looks like that did it. i see that's experimental - should i worry about it being removed in some future, or is it fairly safe?
a

Artem Kobzar

11/28/2023, 6:14 PM
No, I believe 100% it will not be removed. The only thing is that the way of exporting in some cases could be changed until we stabilize it and describe it in docs.
r

Reuben Firmin

11/28/2023, 6:20 PM
hmmm, one more (small?) hurdle - is this a commonjs vs esm thing?
ok, switching to :
Copy code
webpackTask(Action {
                mainOutputFileName = "main.bundle.js"
                output.libraryTarget = "global"
            })
(rather than commonjs2) works, and then i just have to explicitly instantiate any of my classes, which seems ok. e.g. (kotlinx.html)
Copy code
fun FlowContent.bundleInit() {
        // set up htmx
        script {
            src="/static/bundle/main.bundle.js"
        }

        script {
            unsafe {
                // brittle but not terrible
                raw("new backend5.ah.view.DarkMode()")
            }
        }
    }
if there's a better way please let me know, and if the commonjs module not being defined seems like a bug, i can file it
a

Artem Kobzar

11/28/2023, 6:58 PM
I would say it's commonjs
r

Reuben Firmin

11/28/2023, 6:59 PM
is it a bug that it gets "module is not defined"?
a

Artem Kobzar

11/28/2023, 7:00 PM
If you run it in browser - no.
r

Reuben Firmin

11/28/2023, 7:01 PM
ok, what target is best for the browser? / is there a target which will automatically export it & work, or is "global" as I landed on the only option for browser?
a

Artem Kobzar

11/29/2023, 6:27 AM
It depends on your needs. And it's more related to webpack configuration rather then to Kotlin compiler. Also, seems like in current configuration you have made everything work, haven't you?
r

Reuben Firmin

11/29/2023, 11:01 AM
right, it is working - but if i wanted to, how could i get an automatic export working?
a

Artem Kobzar

11/29/2023, 12:36 PM
I feel that the way you use is pretty "legit" for those needs.