I have a project with a KMP module for shared data...
# javascript
j
I have a project with a KMP module for shared data models and another KMP module for a client library. The client module depends on the data models; however, when I generate the JavaScript library the data models aren't exported. How can I ensure the data models are exported in the client JS distribution? Let me know if any additional info/clarity is needed. Thanks! 🙏
A little more info: In the
data-models
module, I am exporting the classes with
@JsExport
. In the
client-library
module I am including the
data-models
as a transitive dependency via
api(project("data-models"))
. I don't want to re-export the models in the
client-library
.
e
That's strange. When marking a declaration with
@JsExport
, the export is transitive. Are you using ES modules or CommonJS? And which granularity? Per file, or per module?
> How can I ensure the data models are exported in the client JS distribution and > I don't want to re-export the models in the
client-library
. I think I'm missing which one of the two you want. For case 2 (no exports of transitive deps), there is no solution currently.
j
Hey @Edoardo Luppi, thanks for the reply. By "re-exporting" I was referring to something ChatGPT suggested by including some sort of export on the data models in the client module to ensure they were included in the JS library distribution; however, I don't think it was reliable advice/info. I created a GitHub repo that reproduces the issue and describes it in the README. If you get a chance, I'd really appreciate you or someone else on here checking it out. Many thanks! Here is the repo: https://github.com/jaredrummler/MultiModuleJsExportTest
e
Hey! I'll clone it, I'm curious to see where's the issue, and if the fix is pretty straightforward
This is https://youtrack.jetbrains.com/issue/KT-65695 The comment emphasizes how this bug makes it impossible to output working multi-module projects using ESM by default. Workarounds are: 1. using
useCommonJs()
instead of
useEsModules()
, but working with CJS might not be compatible with what you're trying to do. 2.
kotlin.js.ir.output.granularity = whole-program
in
gradle.properties
But thanks for the reproducer, I've also discovered in 2.1.20-Beta2 we've lost a lazy initialization optimization, as you can see on the screenshot (left 2.1.0, right 2.1.20-Beta2).
Sorry, done some editing to properly format the previous comment.
p
e
Not saying it's not true, but when you have a boolean check for a lazy instance in a loop, it takes quite the toll on performance. The first case that comes to mind is namespaced functions to manipulate bytes while looping over a byte array. Kotlin libs like kotlinx-io use https://github.com/search?q=repo%3AKotlin%2Fkotlinx-io%20UnsafeBufferOperations&type=code, for example. Another example is namespaced tokens in generated parser's or lexer's code. So that's something to be aware of. Since
@EagerInitialization
is not applicable to classes or objects, the optimization was a nice improvement to both perf and bundle size. Although, all in all, I'd always prefer to see optimizations in the stdlib instead of focusing on this.