I'm just getting started and have a dumb question ...
# javascript
b
I'm just getting started and have a dumb question I can't seem to find the answer to: do I need to do anything special to integrate with a js lib pulled from npm? I'm trying to do something with highcharts, and have added the dependency, but not sure the process on what else I need to do to use it (no symbols or anything seem to resolve). This is in a new kotlinjs project.
🤦 looks like the tutorial I'm using has a section on that and I just hadn't gotten far enough...hopefully that should sort it.
r
generally you need to write kotlin external declarations for the js lib you want to use
b
Yeah, that's what I saw and have started getting into. I seem to be having trouble with resolving the underlying values (defined as
external val
) though
r
unfortunately there is no simple way to create externals - you need to know the js library quite well, sometimes check the sources and do some tests
b
Yeah, that'll be a bit rough. At this point I'm trying to verify if the dependency is even included in the bundle
r
you can use dukat tool output as a starting point
b
Ah, I see a reference to that...maybe I'll check that out
I'm looking at what I think is the built/bundled js and don't even see any instance of
highcharts
in there, so something seems wrong there.
Should that be done on the presence in dependencies in gradle alone? Or do I need to do something else there?
r
if you don't use the library it will be removed by DCE and webpack, so it won't be visible in the bundle
you should at least do
require()
b
ok, and
@file:JsModule("highcharts")
counts as use?
ohh
r
I'm not sure if it counts 🙂 It depends on webpack algorithms and probably the library itself
b
Ah, ok I think
@file:JsModule("highcharts")
should compile to some kind of
require
line?
Ok
r
If you are new to Kotlin/JS, you can also try to use KVision framework (disclaimer: I'm the author). It has many features with easy to use Kotlin API, including support for
chart.js
.
b
Thanks! I'll take a look, though I'm a bit more inclined to stay closer to the "metal" rather than adding another layer I won't understand 🙂
r
You need to write this layer (external declarations) anyway 🙂
b
Yes, I just want to understand what's there
d
if you're still struggling, this was my approach for babylon.js: • add dep with generateExternals = true:
implementation(npm("@babylonjs/core", "^4.2.0", generateExternals = true))
• Copy generated externals from build/externals to somewhere else • Remove generateExternals = true from the dependency (otherwise Dukat will always generate broken external declarations that I might import accidentally) • Add a package my.app.externals.babylon with a file called babylon.kt • Add these annotations to the file: @file:JsModule("@babylonjs/core") and @file:JsNonModule • Copy things from the externals files generated by Dukat and fix them/modify them as I go • Refer to Babylon.js docs and source code to figure out how some things need to be modeled
b
thanks @Daan, this is timely as it's basically exactly where I ended up (just going through it now), though highcharts does so much I don't need, I'm using the generated files as a guide and just copying over some pieces I need--though it's so tangled even that is hard.
Unfortunately using the externals directly didn't work as I got some compliation conflict. It seemed ok when I looked at it but compiler wasn't happy so I let it go.
d
yeah Dukat still has a bunch of bugs it seems, but it's usually not too difficult to create external declarations for just the things you need from a library
oh, and remember that you can always use
dynamic
here and there to deal with really gnarly TS types
b
Yeah, I'm getting closer to considering that too.
At least to start
I made my own definitions at first and then needed to use a feature that I realized would require me to redo all my definitions, so now I'm trying to decide how to proceed.
If I use dynamic, I would just create objects via
js("{....}")
, right?
To pass for the arguments, I mean
d
that's one way, but you can still define external interfaces and implement those with an anonymous class
see the discussion a bit lower in this slack channel about how to work with the JS pattern of using objects as arguments so you can have named and optional args
you can always ask here how we would write externals for a specific part of the lib you're using if you're stumped