Has anyone been successful in deploying a kotlin-j...
# javascript
a
Has anyone been successful in deploying a kotlin-js project to firebase? If I target nodejs I can’t deploy it due to dependency issues, and if I try to use browser target it looks like webpack messes up the code enough that it won’t actually run, which all the issues with webpack seem to lie with kotor. I added https://kotlinlang.org/docs/reference/javascript-dce.html#known-issue-dce-and-ktor but still not working.
t
Could you use
1.4-M1
?
a
I can give that a try
t
You can check this test project with node target
Check results in
build/distributions
( location of optimized JS without dependencies)
a
what does
produceExecutable
do?
t
Single JS (for distribution)
All dependencies (required parts) inside
a
cool, I though tthat’s what the webpack stuff was doing, I’m assuming that’s a new 1.4 thing
Also is there a reason you have this set?
kotlin.js.compiler=ir
t
Yes
Imported only classes, marked with
@JsExport
Do you need legacy mode?
a
Umm I don’t think so
or need the export to look like
then in there I have ktor making a call to an api manipulating the data and forwarding it on.
t
Do you have JS API or you have
main
method inside?
a
I was having a hard time getting the exports to work so I have a main method and a then use this
Copy code
external val exports: dynamic
to make exports
t
Looks like a hack 🙂
Is it works for you?
a
So, it works if I use it as a node target, issue with that is telling firebase all the packages I need to actually upload it
So I switched to using browser so I could have webpack put everything together, which mostly works until I start using ktor
just updated to 1.4-M1 and ktor 1.3.2-1.4-M1-2 so i’ll see if that fixed anything
same issue 😞
Copy code
TypeError: controller is not a constructor
    at AbortController_0
Oh, because I’m transpiling for browser the wrong dependencies are getting pulled in 😞
t
Ktor need additional DCE configuration
a
I found
keep("ktor-ktor-io.\$\$importsForInline\$\$.<http://ktor-ktor-io.io.ktor.utils.io|ktor-ktor-io.io.ktor.utils.io>")
in the docs didn’t seem to help
From the googling I did I saw AbortController is used by fetch and appears to be browser only
t
You can include controller manually
With
keep
a
I don’t think that it’s being removed, I think that it’s just not a package available for node
dceOptions.devMode = true
I had that set and was seeing all sorts of funny issues too so I think it might just be the setup
t
I have plugins for JS export configuration. I can add configuration for Ktor
Is
AbortController
for browser only?
a
I think so, but I see there is a polyfill package
I just need to be able to get webpack to run when nodejs is the target and I think I’d be set, I’m guessing the plugin swaps dependencies depending on those targets
t
Do you have many NPM dependencies?
a
I don’t, but I think ktor pulls in a lot
What does
produceExecutable
end up producing? And binary file?
t
JS file
In
build/distributions
a
must only work for browser targets
i don’t have any /distributions when I only target node
t
For Node
a
That doesn’t include the dependencies though, right?
t
Kotlin dependencies or NPM dependencies?
a
both
I’m trying to get a single file with all the dependencies but built for node
because there is no way to tell firebase about my local dependencies
t
NPM dependencies won’t be included as I understand.
a
Trying to use the browser output didnt’ work because dependencies that don’t work on node are added in, and I dont’ think there is a way for me to tell webpack to not use those
t
and I dont’ think there is a way for me to tell webpack to not use those
It’s possible in common case 🙂
I don’t see any problem for
browser
target as pseudo-
node
Could you specify problems of final JS?
a
The final js file that is output is using a version of ktor that is using fetch that uses abort controller which is only available for the browser
sorry it’s using fetch, when I need
node-fetch
t
Ktor is the same for both targets
node-fetch
- NPM dependency?
a
The Js engine, uses the fetch API internally(and node-fetch for node.js runtime).
They must do something to swap those, maybe dce/webpack is removing the node path?
yes node-fetch is
t
Is
node-fetch
declared in your Gradle script?
a
yeah, ktor for some reason doesn’t pull it in
ok, I think you’re right about the browser / node thing I think it’s the tree shaking…
although that should be turned off when I use
dceOptions.devMode = true
keep("abort-controller.AbortController")
should hopefully fix it
t
🙂
a
😕 still not working I have no idea what’s going on now
Copy code
@JsModule("abort-controller")
external object AbortController {
  fun constructor(): dynamic
}

fun main() {
  val a = AbortController.constructor()
  requireNotNull(a)
}
added this to my code and it works fine
it’s just in ktor blowing up
I copied the code from ktor into my main function and yeah works fine on node, blows up after going through webpack no clue what’s going on…
Copy code
val controller = js("require('abort-controller')")
  js("new controller()")
t
Copy code
// valid declaration

@JsModule("abort-controller")
external class AbortController()
+ DCE keep
a
It looks like that’s all setup in ktor already
Copy code
function main() {
    var controller = __webpack_require__(/*! abort-controller */ "../../node_modules/abort-controller/dist/abort-controller.mjs");
    console.log(controller)
    new controller();
  }
that’s the output with webpack set to development mode this is the output of the log statment
Copy code
>  Object [Module] {
>    AbortController: [Getter],
>    AbortSignal: [Getter],
>    default: [Function: AbortController]
>  }
and I have
dceOptions.devMode = true
Copy code
@JsModule("abort-controller")
external class AbortController

fun main() {
  val c = AbortController()
}
has the same issue!
it’s getting late over here, thanks for your help!
d
I'd love to read a blog article or similar of how you eventually solve (or not solve) this
i
@andrewreitz Hi! There is no NPM dependencies in maven dependnecies now. So when you depend on ktor, you don’t get any information about its npm dependencies, and you need to declare it manually. It can be added via
Copy code
implementation(npm(“abort-controller”))
t
Only this single dependency required?
i
Additionally problem can be with
text-encoding
As I remember, these 2 npm dependencies enough.
Since 1.4 library will be published with
package.json
and will include information about npm dependencies.
a
Yeah, I've added those. The issue is that after we pack is run abort& controller is changed somehow. Works fine when not using webpack.
This seems like a bug either with the config for webpack or in webpack but I'm not really sure where to get more info about it. I'll see if webpack gutter and provide more info.
t
Do you have GitHub project with this problem?
a
It’s on gitlab, I don’t think there is any reason I could make it public. I’ve been meaning to. I’m not sure how to accuratly show what is going on though. I’ll try to make some gradle tasks and some notes and share with you.
I guess I could make a really simple example version, that’s probably better.
👍 1
Ok, I think this is the minimum amount of code to represent the issue I’m seeing https://github.com/AndrewReitz/ktor-abort-controller-issue
t
1.
nodejs
->
nodejs()
2 -
Main.kt
3.
keep("ktor-abort-controller-issue")
a
So the code is the way it is because that’s exactly how ktor is loading it. And the keep rules shouldn’t matter since i have
dceOptions.devMode = true
but on top of all that, that implementation has the same issue. 😞
t
Working example can be used for PR
a
I think this might be the culprit https://www.npmjs.com/package/abort-controller#-usage I think it’s loading a version that isn’t meant for node, but I don’t know how to specify the correct one.
t
It can be replaced by local one
a
what do you mean?
t
Any dependency can be replaced locally
1. Add webpack plugin
Copy code
id("com.github.turansky.kfc.webpack") version "0.8.5"
2. Add custom
abort-handler.js
to
src/main/resources
3. PROFIT - local
abort-handler.js
used by webpack
a
is there a way to tell webpack the one to use that’s in the dist folder of abort-controler/dist?
The plugin I don’t think will solve it either because then all the dependencies that abort-controller is bringing in are not now loaded, also it blows away all the configs that were in the webpack.config.d folder so it’s not targeting node anymore.
t
Use patchWebpackConfig for additional config
is there a way to tell webpack the one to use that’s in the dist folder of abort-controler/dist
You can copy it for test
a
So is there a way to tell webpack to not use the browser files in package.json?
I did copy it, that didn’t work because all the dependencies it requires can’t be resolved.
t
You can remove webpack plugin (doesn’t need)
Copy code
tasks.compileKotlinJs {
    doLast {
        // copy abort-controller.js
        // to `build/js/packages/ktor-abort-controller-issue/kotlin-dce`
        // first webpack folder  
    }
}
a
I’ve spent way more time on this than I think this is worth. I could have written this in JS 10 times over now. I really appreciate the help, and hopefully someday firebase and kotlin js can get along better together.
t
😞
a
Alright, going to work on a blog post about this. Was able to finally get it published using the file option in package.json but it was a pain. Maybe I'll put in a feature request to have things packaged up like that since that will make submitting to GCP, firebase and other function services easier. https://firebase.google.com/docs/functions/handle-dependencies?authuser=0#including_local_nodejs_modules_as_part_of_your_deployment_package
👍 1
i
I’ll read with pleasure to improve future DX Sorry for this pain 😞 Kotlin/JS is trying now to cover the most top-level experience - base on which in future step-by-step will cover most important and popular use cases
d
A JB-supported "firebase deploy" would be really neat in the future 🙂
i
Will be cool if you submit issue on youtrack and describe some context of your use case to not missed it
a
👍 yeah I wasn't sure exactly where to file the issue with the abort-controller, but a feature request seems more reasonable. I'll probably whip up a script/Gradle task to do what I want so I can include that to help pin point exactly what I'm looking for.
👍 1
It looks like this is only an issue on firebase, azure, GCP, and aws all let you deploy with a zip file or include your node_modules. I think there’s still a little more work that needs to be done from the given output to tell it which function to use, but shouldn’t be too difficult to do. Seems like a specific firebase deploy plugin would be a solution here.
t
Is firebase require single JS file?
a
You can have multiple I think, it’s not really clear on their docs.
Alright, blog post is here! https://andrewreitz.com/tech_blog/kotlin-multiplatform-android-firebase/ Feel free to let me know if you find anything wrong in it.
👍 3
d
@andrewreitz Hi. Does the repo for this exist anywhere? I cant seem to find it