My goal is to write a Kotlin library, compile it to WebAssembly and call its functions from JS. Since a few hours I try to get a simple hello world to work. The documentation on this topic is either non existent or well hidden.
This is my kotlin file:
@Used
public fun hello() {
println("Hello world!")
}
fun main(args: Array<String>) {
println("main() function executed!")
}
When I compile it to WebAssembly, I get a hello.wasm and hello.wasm.js file.
First I tried to use something like this to execute the function:
WebAssembly.instantiateStreaming(fetch('hello.wasm'), importObject)
.then(obj => obj.instance.exports.hello());
Then I understood that I need to pass the imports from my hello.wasm.js file in the importObject parameter. So I guess that I need to use the hello.wasm.js file to correctly initialize my wasm program.
When I load my wasm like the following, I don't get any errors and the main() function is executed.
<script wasm="hello.wasm" src="hello.wasm.js"></script>
But how can I execute the hello() function from JavaScript? The only kotlin wasm examples I found are not calling specific functions but rendering something from the main() function.
Also any links to relevant documentation are very much appreciated.
UPDATE: I managed to execute the function, but I don't believe this is the correct way:
<script wasm="hello.wasm" src="hello.wasm.js"></script>
<script>
WebAssembly.instantiateStreaming(fetch('hello.wasm'), konan_dependencies)
.then(obj => obj.instance.exports['kfun:hello$$ValueType']());
</script>
The problem is, that my wasm file is fetched two times if I do it like that.
Loading only the hello.wasm.js file without the wasm attribute gets me the following error:
Uncaught Error: Could not find the wasm attribute pointing to the WebAssembly binary.
at Object.konan.moduleEntry (stats.wasm.js:433)
at stats.wasm.js:532
You can freely talk to JavaScript from Kotlin via dynamic types. If you want to use the full power of the Kotlin type system, you can create external declarations for JavaScript libraries which will be understood by the Kotlin compiler and the surrounding tooling.
Kotlin-Native can be compiled to WebAssembly, but this method is going away. The new compiler is not yet readily available.
Yes. In addition to using for backend web, you can also use Kotlin/JS for client-side web. Kotlin can use definitions from DefinitelyTyped to get static typing for common JavaScript libraries, and it is compatible with existing module systems such as AMD and CommonJS.
I recently did some research into this myself and from my understanding, your usecase is not really supported so far. What you are looking for is essentially a library, yet if you look into the documentation of Kotlin/Native it states:
The following binary kinds are supported (note that not all the kinds are available for all native platforms):
[...]
sharedLib - a shared native library - all native targets except wasm32
staticLib - a static native library - all native targets except wasm32
From my understanding, the difficulty lies withing data passing between Javascript and WebAssembly as it only supports ints or the rather roundabout way via linear memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With