typescriptfirebasekotlinkotlin-jskotlin-js-interop

Uncaught ReferenceError: firebase is not defined in Kotlin/JS project with Dukat generated declarations


In a basic kotlin js project, I imported the firebase dependency. I used Dukat to get access to the type references and got them to compile. My kotlin compiles like a charm, however it seems to me like the bundle created by webpack does not contain the firebase library in the end.

What I did :

enter image description here

After a few changes, my Kotlin compiles fine. When running it however, I am facing a Uncaught ReferenceError: firebase is not defined error in the frontend. This error happens before the code using firebase gets invoked, so I think that the problem comes from the bundling somehow.

Here is my stacktrace:

sample-firebase.js:391 Uncaught Error: Cannot find module 'firebase'
    at webpackMissingModule (sample-firebase.js:3)
    at eval (sample-firebase.js:3)
    at eval (sample-firebase.js:8)
    at Object../kotlin-dce-dev/sample-firebase.js (sample-firebase.js:359)
    at __webpack_require__ (sample-firebase.js:388)
    at sample-firebase.js:1447
    at sample-firebase.js:1450
    at webpackUniversalModuleDefinition (sample-firebase.js:17)
    at sample-firebase.js:18
[webpack-dev-server] Module not found: Error: Package path . is not exported from package /Users/julien/Developer/kotlin-samples/sample-firebase/build/js/node_modules/firebase (see exports field in /Users/julien/Developer/kotlin-samples/sample-firebase/build/js/node_modules/firebase/package.json)

Here is my Client code (the only actually interesting line is the one containing initializeApp.

fun main() {
    val firebaseConfig: Json = json(...)

    val fire = initializeApp(firebaseConfig)
    console.log(fire)
    window.onload = {
        console.log(sorted(arrayOf(1, 2, 3)))
        startFirebase();
        document.body?.sayHello() } }

Commenting out the firebase related code completely removes the error (but obviously also doesn't add firebase functionalities).

My client is available here. You can reproduce by running ./gradlew run in the sample-firebase module.

I have tried quite a few things:

What are ways to find the discrepancy between my Kotlin declarations that compile, and don't throw errors, and my frontend which just fails to import firebase?


Solution

  • Dukat is still experimental. Use handmade wrapper. Something like that:

    external interface FirebaseOptions{
    }
    
    external interface FirebaseAppSettings{
        var setting: String  // needed settings
    }
    
    external interface FirebaseApp{
    }
    
    @JsModule("firebase/app")
    @JsNonModule
    external val firebaseModule: dynamic
    
    val initializeApp: (options: FirebaseOptions, config: FirebaseAppSettings) -> FirebaseApp = firebaseModule.initializeApp
    

    add to build.gradle:

    implementation(npm("firebase", "9.1.3"))
    

    and use it:

    fun main() {
        val options: dynamic = object {}
        val config: dynamic = object {}
        config["setting"] = "xxx"
        val firebaseApp = initializeApp(
            options.unsafeCast<FirebaseOptions>(),
            config.unsafeCast<FirebaseAppSettings>()
        )
        console.log(firebaseApp)
    }