I am trying to test the JS part of my [FirebaseMul...
# javascript
l
I am trying to test the JS part of my [FirebaseMultiplatform](https://github.com/lamba92/firebase-multiplatform/) library. But when using it inside a Kotlin/JS project the webpack errors with:
Copy code
text
ERROR in D:/Progetti/Android-Application/build/js/packages_imported/firebase-multiplatform-auth/0.1.8/firebase-multiplatform-auth.js
Module not found: Error: Can't resolve 'firebase.auth.ActionCodeInfo' in 'D:\Progetti\Android-Application\build\js\packages_imported\firebase-multiplatform-auth\0.1.8'
 @ D:/Progetti/Android-Application/build/js/packages_imported/firebase-multiplatform-auth/0.1.8/firebase-multiplatform-auth.js 3:4-144
 @ ../my-application-kodein-di/kotlin/my-application-kodein-di.js
 @ ./kotlin/my-application-web-client-2.js
 @ multi ./kotlin/my-application-web-client-2.js
Now,
firebase.auth.ActionCodeInfo
is actually a class from the Firebase JS library for which [Dukat](https://github.com/Kotlin/dukat/) wrote [this](https://github.com/lamba92/firebase-multiplatform/blob/9dccf3e1c8b19b5181e8f02266bf6775ecd53f2c/core/src/jsMain/kotlin/firebase/auth/index.firebase.auth.module_firebase.kt#L41-L44) (that i rearranged into packages). Why does this infernal webpack machinery looks for it inside my library instead of the Firebase one?
šŸ‘€ 2
i
Hi! Can you please create an issue http://kotl.in/issue and attach steps to reproduce the problem?
l
Right away!
i
I think, you can try this header instead your
Copy code
@file:JsModule("firebase")
@file:JsNonModule // necessary for umd
@file:JsQualifier("auth")
ā¤ļø 1
l
Here's the issue! https://youtrack.jetbrains.com/issue/KT-36427 I'll test your advice asap, thanks!
Nope, using
@JsModule("firebase")
errors anyway šŸ˜ž
damn i hate js so much
i
Is error the same?
l
Yes
Also a question, how webpack knows which library to bundle and which not? Can it be possible that it skipped Firebase entirely?
i
Webpack bundles all libraries by default, it can be configured through
externals
(https://webpack.js.org/configuration/externals/) Sorry, what command do you use for build? I can’t use webpack tasks in your project
l
The task is
web-client-2:browserDevelopmentRun
You may need to adjust the firebaseMultiplatform version in the
properties.gradle
acconding to the one published. I was iterating using MavenLocal so the version may not be the same
That is 0.1.8
Oh wait a friend of mine may have changed stuff before the commit. I am rolling back right now
ok, update to latest commit the branch
firebase-mpp
and run
./gradlew web-client-2:browserDevelopmentRun
and it will error with:
Copy code
ERROR in D:/Progetti/Android-Application/build/js/packages_imported/firebase-multiplatform-auth/0.1.10/firebase-multiplatform-auth.js
Module not found: Error: Can't resolve 'firebase.auth.ActionCodeInfo' in 'D:\Progetti\Android-Application\build\js\packages_imported\firebase-multiplatform-auth\0.1.10'
 @ D:/Progetti/Android-Application/build/js/packages_imported/firebase-multiplatform-auth/0.1.10/firebase-multiplatform-auth.js 1715:37-76
 @ ../my-application-kodein-di/kotlin/my-application-kodein-di.js
 @ ./kotlin/my-application-web-client-2.js
 @ multi ./kotlin/my-application-web-client-2.js
i
l
The error is from the project that consumes the library, which is this one: https://github.com/CesareIurlaro/Android-Application/commit/e76766125483c282d950f913cd6b99f3e09780e0 The link is at the commit where launching
web-client-2:browserDevelompentRun
triggers the runtime error. Also, in this commit you have to go in
gradle.properties
and change
firebaseMultiplatformVersion
to
0.1.8
.
i
Ok, I see, thank you And I find some problems in
firebase-mpp
The first (it is why you faced with the first problem) you need to change declaration of
Copy code
external object Operations
It should be something like
Copy code
@file:JsModule("firebase")
@file:JsNonModule
@file:JsQualifier("auth")
package firebase.auth


@JsName("ActionCodeInfo")
external object Operations
But further you faced with other problems, the second one you need to change all patterns like
Copy code
@file:JsQualifier("firebase.storage")
or
Copy code
@file:JsQualifier("firebase.auth")
on
Copy code
@file:JsModule("firebase")
@file:JsNonModule
@file:JsQualifier("auth") // or storage and so on
cc @[JB] Shagen
l
Wait i do not get it! Why the
Operations
error?
i
Because
JsModule
means that you find package with that name, so you have only
firebase
npm package, and you need declare module only with
firebase
not all path If you have some hierarchy, you can use
JsQualifier
to model namespaces And finally, these operations are declared in real js object with name
ActionCodeInfo
so if you want to use custom name in Kotlin, you need to declare real js name in
@JsName
l
I get the module-qualifier path but
ActionCodeInfo
actually exists there! Have a look here: https://firebase.google.com/docs/reference/js/firebase.auth.ActionCodeInfo
i
Okay, I see, I think that you can set on
Operations
class this header
Copy code
@file:JsModule("firebase")
@file:JsNonModule
@file:JsQualifier("auth.ActionCodeInfo")
package firebase.auth


@JsName("Operation")
external object Operations {
It means, that you require
firebase
module, and go to ā€œnamespaceā€
firebase.auth.ActionCodeInfo
and get object named
Operation
The common rule Real npm (js) module -
@JsModule
Namespace inside this module -
@JsQualifier
Real name of declaration (optional if name is the same) -
@JsName
i
@Lamberto Basti Did the answers above help you?
l
Thanks! I will try soon. In the end since the due date for the project was close and there were too many errors on the build I decided to go for Angular from ground up for the web client. I will try the fix as soon as possible and put up some tests! Also, is there any common practice to build an NPM module from a Kotlin/JS project with or without all Kotlin/JS Maven dependencies packed inside of it?
i
I recomment to pack it inside, because in fact beacuse JavaScript world is not the same as Java (and Kotlin), it can be some specifically and bring some unexpected behaviours If you will pack it and (ideally) interact with external JS world only through JS types (without Kotlin complex types), everything will be ok JS types, I mean: • primitives, which exists in JS - String, Int, Double and so on • external type (because it is in fact from JS world) • Any, which you can serialize through
kotlinx.serialization
It doesn’t mean that if you can interact through Kotlin types, you will got problems surely, but in some specific and very complex cases, JS environment can show itself
l
Yeah, I tried to initialize a Ktor client from JS code once. It did not end well 🤣. Have you some example task that shows how to pack this stuff out?
i
Yes, it is related with that webpack does it. This tool by default bundle your code with all dependencies (including Kotlin/JS modules and NPM modules). And by default webpack produce just script, not JS library Good news are that you can configure it. You should create folder
webpack.config.d
and create js file with any name, and content which configure library mode for webpack (https://webpack.js.org/configuration/output/#outputlibrary)
Copy code
config.output = config.output || {} // just in case where config.output is undefined
config.output.library = "libraryName" // should be valid js variable name
It forces webpack to put all your export to js variable
libraryName
You can additionally set js module system (https://webpack.js.org/configuration/output/#outputlibrarytarget) if you want You can find example here https://github.com/ilgonmic/kotlinjs-multi-module/blob/master/app/webpack.config.d/library.j
l
Damn, that is a lot of NPM/JS stuff that I yet need to understand. As soon as I'll have some spare time I will study the NPM module system. Thank you for the help šŸ™‚ Soon I'll try the fix for FirebaseMultiplatform and I'll let you know.