In our final evaluation of Kotlin MP/JS, these are...
# javascript
e
In our final evaluation of Kotlin MP/JS, these are the main issues we considered problematic, or impacting DevEx. Might be interesting for others too. I'll report another one but it was considered minor in our case. - https://youtrack.jetbrains.com/issue/KT-59523/ We use CommonJS modules at the moment, luckily. - https://youtrack.jetbrains.com/issue/KTIJ-22593 Workaround is to use Force Step Over. Painful for Java devs. - https://youtrack.jetbrains.com/issue/KT-51389 Workaround is to use unsigned types internally and convert to signed externally. Or use `expect class`/`actual typealias` to support unsigned types in the JS API (more work tho...). - https://youtrack.jetbrains.com/issue/KT-57192 Workaround is to return the
Any?
type, but the API is not explicit anymore. - https://youtrack.jetbrains.com/issue/KT-60140 Fix the naming ourselves, just be more careful at the moment. - https://youtrack.jetbrains.com/issue/KT-60141 Can't do anything about it, but it's only inside IntelliJ IDEA, so we should be safe. - No equivalent of
@JvmStatic
, to avoid dealing with
MyObject.getInstance().MY_CONST
in TypeScript. We'd like
<http://MyObject.MY|MyObject.MY>_CONST
or
MyObject.myMethod()
. - https://youtrack.jetbrains.com/issue/KT-53993 We want to be able to customize the outputted JS code if necessary (especially if the Kotlin team cannot release a fix in a timeframe that works for us). Should never happen, but better safe than sorry.
👍 2
FYI @Artem Kobzar
f
• How do you deal with collections not being exportable (e.g. list)? https://youtrack.jetbrains.com/issue/KT-34995 • How do you deal with the need of annotating a lot of the common code with the
@JsExport
https://youtrack.jetbrains.com/issue/KT-47200/KJS-IR-Define-exports-without-JsExport • How do you deal with the need of wrapping common suspending API is Js Promises? https://youtrack.jetbrains.com/issue/KT-56281 For me these are impacting DevEx a lot
e
How do you deal with collections not being exportable
Array
everywhere. Fortunately for us, it's enough as we deal with a protocol layer, so very simple types on the API surface.
annotating a lot of the common code with the
@JsExport
No big deal here. I've got a lot of common code
JsExport
-ed, and annotated with Jvm stuff. Everything is centralized and explicit in
commonMain
, so for me it is a win.
How do you deal with the need of wrapping common suspending API is Js Promises
I've build an API type that wraps both promises and futures, so in common code we deal with a single object. But yes, it's important to have automatic conversion, see KT-53993, last comment
f
The goal for us it to have nice interoperability and idiomatic APIs for all platforms. Arrays are not really idiomatic on JVM/Android world. Having worked in Android for long time, I don't remember using array ever in the codebase (only lists). JsExport is more bothering me personally (I find it to be a redundant visibility modifier). I see that is not a big deal though. The suspend part is big deal for us, because for idiomatic Android we don't use blocking code, only suspending. Wrapping it in a custom type is a workaround at the cost of the JVM and Swift API IIUC, which are less idiomatic. Having automatic conversion from suspend to async for swift and js would make us much more happy. Glad to hear that is working for you though 😄 Hopefully we will join the KMP world soon, too.
e
In the case of the suspending to platform specific idiomatic API, I've been lucky enough to target only the JVM and Node, as of now. In JS any thenable object can be used with async/await. On the JVM the wrapper exposes the usual
CompletableFuture
API. Maybe for other platform it's not that easy tho, perfectly understandable.
JsExport is more bothering
Yeah I get it. I'm a bit on the opposite side, I prefer being explicit on everything, so I know what I'm actually exporting on the code itself, and not in my build configuration, which might get overlooked.
Arrays are not really idiomatic
That's reasonable too. Well at least we have a decent list here. Hopefully some of these can be solved.
Sorry, just wondering, have you tested an
expect class
/
actual typealias
approach to expose a
List
on the JVM layer, and an
Array
on the JS layer? Could be done with other types too proably.
f
You would use this solution at the boundary level, like
Copy code
expect class MyListWrapper<T>

expect fun <T> List<T>.wrapped(): MyListWrapper<T>

public myApi(): MyListWrapper<Int> {
  internalStuff().wrapped()
}

internal internalStuff(): List<Int>
or do you also use it for internal stuff? That may work, it just doesn't make dev ex so nice. I'd love to see an official solution or compiler plugin or a library very well done. Something that doesn't feel a personal workaround (just like they did for coroutines interop for ios for example)
s
a
Thank you so much for your feedback 🙏 1. So, for sure, those tickets (https://youtrack.jetbrains.com/issue/KT-59523/, https://youtrack.jetbrains.com/issue/KT-57192, https://youtrack.jetbrains.com/issue/KT-60140, https://youtrack.jetbrains.com/issue/KT-60141) should and will be fixed in the next releases. 2. The issue (https://youtrack.jetbrains.com/issue/KTIJ-22593) is more related to IDEA team, so, we (Kotlin/JS team) can't help a lot with it, sorry. 3. For the ULong/Long classes (https://youtrack.jetbrains.com/issue/KT-51389) we are planning to use JS
bigint
instead of our wrappers, so, it should be better when we will implement it. 4. For the issue (https://youtrack.jetbrains.com/issue/KT-56281), we are also working on a new design for coroutines compilation, so, with the design, it would be possible to export them and use on the JS side.
Also, we are trying to find the best design right now, to fix the problem with collections JsExport
gratitude thank you 1
e
Thanks @Artem Kobzar! My eng manager was pretty impressed with Kotlin's capabilities. Doesn't happen often lol Looking forward to 1.9.20, I've seen the commits and there is a bunch of cool fixes already. In the meantime I'll keep going with the POC, which is tbh already in a usable state for JVM and Node. Regarding unsigned types, are there plans to map
UByteArray
to
Uint8array
?