I have a multiplatform project supporting Android,...
# javascript
j
I have a multiplatform project supporting Android, Jvm and Apple (iOs, watchOs, tvOs). I’m now trying to add support for JS with this
Copy code
js(IR) {
    browser {
        webpackTask {
            mainOutputFileName = "kmp_lib.js"
            output.library = "kmpLib"
        }
    }
    binaries.executable()
    generateTypeScriptDefinitions()
}
When I run
./gradlew jsBrowserProductionWebpack
I see that
my_module.js
and
kmp_lib.js
are generated but the content seems weird
Copy code
!function(e,o){"object"==typeof exports&&"object"==typeof module?module.exports=o():"function"==typeof define&&define.amd?define([],o):"object"==typeof exports?exports.my_module=o():e.my_module=o()}(globalThis,(()=>(()=>{"use strict";var e={};return(e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})})(e),e})()));
I was expecting a js file containing all the public classes/variable exposed in my module, the same way it works for Apple. What am I missing?
a
The production build tries to minimize the code as much as possible to make your application lighter for clients to consume. The current export model (which is actually under discussion) doesn't export every public declaration to JavaScript to keep your application as light as possible. So, if you want your class/function/variables to be visible from JavaScript, you can mark such declarations with the
@JsExport
annotation, which will make them visible in your JavaScript application. The documentation is here: https://kotlinlang.org/docs/js-to-kotlin-interop.html
j
I’ll have a look, thanks!
kodee welcoming 1
e
I would question the use of
binaries.executable
at this point tho. If I'm building a self contained executable application, why would I want to 1. generate TS types 2. avoid minification
j
I'm not building a self contained executable application. I'm trying to build a library containing a bunch of shared logic between all my clients! Should I remove
binaries.exectuable
then? I added typescript generation since the web app client I'm considering adding the library to is written with TS
e
Yes, you should prefer
binaries.library
for this. You also don't need Webpack at that point, since bundling shouldn't be done at the library level, but at the final consumer level. A library doesn't configure Webpack at all, so you'd be good to go. You will have to mark your API surface with
@JsExport
anyway, as that's how you prevent name mangling. Note that the API can be a subset of the Kotlin declarations, you don't need to export everything.
j
Alright, thanks for the precious tips!
✔️ 1
e
This seems to be a recurrent issue when people are setting up the JS target in MP projects. Maybe the documentation should be reworked a bit to make this more obvious.
j
True, I didn't see
binaries.library
mentioned anywhere.