I would like to do a dynamic import like so: ```i...
# javascript
e
I would like to do a dynamic import like so:
Copy code
import js.import.import

suspend fun MyFun(cloudUrl: String) {
    import<Unit>(
        /* webpackIgnore: true */
        "$cloudUrl/assets/js-client-8.5.0/cloud-client.js"
    )
}
Unfortunately the magic comment is removed when compiling Kotlin to JS. In the browser i get the error "Cannot find module 'https://anylogic.zenmo.com/assets/js-client-8.5.0/cloud-client.js'".
import("<https://anylogic.zenmo.com/assets/js-client-8.5.0/cloud-client.js>")
works in plain javascript. How do I get the compiler/webpack to leave this import untouched?
t
Is there sideeffect inside?
e
No just class definitions
t
Do you have declarations for them?
e
That is not the issue, it's not even fetching it
For pill I need details
cloudUrl is really dynamic?
e
externals sounds like it should work but it seems it has some caveats. This works:
Copy code
val promise: Promise<Unit> = eval("import('<https://anylogic.zenmo.com/assets/js-client-8.5.0/cloud-client.js>')")
promise.then {
    console.log(CloudClient)
}
But it's a pretty stupid workaround.
t
Is it CDN for existed NPM library?
e
No it's a js library which is a client library of the application which hosts it
It is not open source
I mean, i don't have to do it dynamic, but it's a thing that should be possible
t
Copy code
import js.function.JsFunction
import js.function.invoke
import js.promise.Promise

private val loadLibrary = JsFunction<String, Promise<Unit>>(
    "cloudUrl",
    "return import(cloudUrl + '/assets/js-client-8.5.0/cloud-client.js')",
)

suspend fun MyFun(cloudUrl: String) {
    loadLibrary(cloudUrl).await()
}
In next release:
Copy code
import js.function.AsyncFunction
import js.function.invoke

private val loadLibrary = AsyncFunction<String, Unit>(
    "cloudUrl",
    "return import(cloudUrl + '/assets/js-client-8.5.0/cloud-client.js')",
)

suspend fun MyFun(cloudUrl: String) {
    loadLibrary(cloudUrl)
}
e
Isn't this the same but shorter?
Copy code
suspend fun <T> importLibrary(library: String): T {
    return eval("import('$library')")
}
Or no wait its not awaiting
Copy code
suspend fun <T> dynamicImport(library: String): T {
    val promise: Promise<T> = eval("import('$library')")
    return promise.await()
}
t
In wrappers we can have something like this:
Copy code
inline fun <T> importAsync(
    url: String,
    comment: String,
): Promise<T> {
    return js("/* $comment */ import('$url')")
}
+ suspend variant
js
call is better then
eval
-
eval
is unsafe
Also idea:
Copy code
import js.import.import

suspend fun MyFun(cloudUrl: String) {
    js("/* webpackIgnore: true */)
 
    import<Unit>("$cloudUrl/assets/js-client-8.5.0/cloud-client.js")
}
Should work (in theory)
e
I think the comment needs to be later
import(/* webpackIgnore: true */
😞 1
Thanks for brainstorming anyhow.
t
Copy code
import js.import.import

suspend fun MyFun(cloudUrl: String) {
    import<Unit>(js("/* webpackIgnore: true */ cloudUrl + '/assets/js-client-8.5.0/cloud-client.js'"))
}
😉
e
I'm testing that and the comment is still stripped
in fact if you do this
Copy code
js("/* testcomment */")
The compiler says "An argument for the js() function must be non-empty JavaScript code"