Query on Tree Shaking in Kotlin-JS Compilation wit...
# javascript
a
Query on Tree Shaking in Kotlin-JS Compilation with ES6 in Kotlin 1.9.0: I'm working on a Kotlin-JS project where I have two Kotlin files (
hello.kt
and
request.kt
) and a specified Gradle configuration. After compiling to JavaScript and using the
dev.petuska.npm.publish
for publishing, I'm observing an unexpected behavior in the bundle size when importing different functions. hello.kt
Copy code
@JsExport
fun SayHi() {
    console.log("hi")
}
request.kt
Copy code
@JsExport
fun sendRequest() {
    // Code using HttpClient and GlobalScope.launch
    GlobalScope.launch {
        HttpClient(Js).request {
            url {
                this.protocol = URLProtocol.HTTPS
                this.host = "www.test.com"
            }
        }

    }
}
Gradle Configuration:
Copy code
plugins {
    kotlin("js") version "1.9.0"
    id("dev.petuska.npm.publish") version "3.4.1"
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0")
    implementation("io.ktor:ktor-client-core:3.0.0-beta-1")
    implementation("io.ktor:ktor-client-js:3.0.0-beta-1")
}


kotlin {
    js {
        binaries.library()
        useEsModules()
        moduleName = "js-kotlin"
        browser {
            webpackTask {
                outputFileName = "js-kotlin.js"
                output.library = "jsKotlin"
            }
          
        }
        generateTypeScriptDefinitions()
    }
}

tasks.withType<KotlinJsCompile>().configureEach {
    kotlinOptions {
        moduleKind = "es"
        useEsClasses = true
    }
}
import in JS project :
Copy code
import {SayHi} from 'js-kotlin/js-kotlin.mjs'
import {sendRequest} from 'js-kotlin/js-kotlin.mjs'
When I import
{SayHi}
and
{sendRequest}
from my compiled module, I'm noticing that the import cost for both imports is similar. I was expecting tree shaking to reduce the size for the
{SayHi}
import, considering it doesn't use the heavier
ktor
dependency. Am I missing something in my configuration that's preventing tree shaking from effectively reducing import cost ?
a
You can also try to add
Copy code
"sideEffects": false
into the package.json for
js-kotlin
package
a
tried, still no impact on size.
m
I could not make it any smaller either. I was using webpack to bundle a js file. I imported a lodash function for comparison. Lodash was tree-shaken successfully while my kotlinjs package was not.
a
anyone else is facing this ?
a
@Ilya Goncharov [JB] is it possible because of our side-effects during the module initialization?
a
@Ilya Goncharov [JB]: Any ideas of this.
i
Sorry, I will check this case, and tell you about results of investigation
🙌 1
@Artem Kobzar Yes, it looks like because of side-effects during the module initialization. I get following ending of file
Copy code
//region block: post-declaration
initMetadataForLambda(sendRequest$slambda, VOID, VOID, [1]);
//endregion
//region block: exports
export {
  SayHi as SayHi,
  sendRequest as sendRequest,
};
//endregion
And if I comment
initMetadataForLambda
, webpack output will be more expected
a
I think we can discuss it, because I know the way to improve it for the per-module
a
Any ways to overcome this locally ?
a
Let me think: what version of the compiler do you use?
👍 1
a
1.9.22
a
Hmm, in this case, I can't find any solution. You could try per-file mode in 2.0.0-Beta3 just to check if the tree-shaking works better (or worse).
a
Let me check. Do I need anything separately to use per-file mode?
a
The only restriction is to use ES-modules, but seems like you already use it
a
still no luck with 2.0.0-Beta3 😞 same results.
a
And with the per-file granularity? (you should declare it by yourself inside the
gradle.properties
like this:
Copy code
kotlin.js.ir.output.granularity=per-file
a
Oh, i missed adding that earlier. Now tree-shaking seems to be working with per-file granularity. Thanks for help. But now somehow library .d.ts file is missing,
🔥 1
a
It should contain only one file per-module (we are working on per-file .d.ts right now)
Btw, great to hear it. Could you please share how changed the bundle size with the tree-shaking with per-module and per-file?
a
My Js npm library just have Kotlin classes and no other external libraries (other than kotlin-js-std). per-module config size : 32.kb per-file config size : 13 kb. These are gzip size.
🫡 1
a
Nice, thank you for sharing.
👍 1
Could you also please share (just to understand some points for improvements), what size of the project itself? How many classes do you have in the library (or how many lines of code)
a
Sure, we are in process of pushing this change to production. Let me get back with final results.
🙏 1