What is the name of my Kotlin-generated JavaScript module?

I think the JavaScript module is named “untitled2”, because that’s the project name, as well as the name of the .js file produced in build/js/packages. However, that doesn’t seem to work, or else I misunderstand how to use it.

Scenario 1.

I include the script in the body, and call the function I want from JavaScript’s main(), like so:

fun main() { apply("myCanvas") }

<canvas id="myCanvas" width="400" height="300"></canvas>
<script src="untitled2.js">
    untitled2.apply("myCanvas")
</script>

Everything works fine.

Scenario 2.

I include the script in the header:

<head> <!-- standard boilerplate omitted -->
<script src="untitled2.js"></script>
</head>

When I try to reference this in my HTML file:

<canvas id="myCanvas" width="400" height="300"></canvas>
<button type="button" id="button1" onclick="untitled2.apply('myCanvas')">Plot it</button>

the JavaScript debugger console reports, Can't find variable: untitled2. So apparently that isn’t the module name. Omitting untitled2 also doesn’t work.

How do I determine the module name – or – how do I import it properly? I have read the usual suspects cited here.

(I hope it’s allowed to bump this topic in the hope that someone notices.)

Hi,

try window.untitled2.

If you have a special character in your module name like ‘-’ then window[‘untitled-2’].

Thank you for the suggestion. After a couple of days with no reply, I just refactored my code to take a different approach, but the approach I use now is arguably suboptimal. I will try to refactor it again at some point & if I do I will report back.

Can you attach a link to your project, please?

I don’t have it on GitHub, and I don’t believe I have a copy of the older code. Do you want a link to a webpage that shows the code in action? (It will also so how I execute it in JavaScript.)

I don’t think this link will help. I failed to reproduce the problem, and it’s hard to help you without a sample project.

Sorry it’s taken so long to get back to you. I only had the time to rework my code today, to see if I could make it work. The good news is that I believe I have figured out the problem.

When I tried analyzing the module via Firefox’s Web Console I noticed the name mangling. I added a @JSName annotation, and it worked beautifully. Previously I was mainly using Safari’s Web Console, but even today Safari’s Web Console was not showing me anything from my module, and sometimes not even the module name! It seems to be quite buggy.

A couple of Caveats:

  • I am not entirely sure this was the problem. As part of my attempts to get this working, I created a new project today and copied the relevant code, but I noticed that Idea set up the new project differently from the old one. So, there may have been something else at work.

  • This page states that names may be mangled, but the example and the wording strongly imply that this is rare: “In some cases (for example, to support overloads).” Nearly all of my function names are mangled, and none of them are class members; indeed, none of them clash with anything else! I don’t think the automatically-generated program’s functions were mangled, so perhaps it kicks in only at a certain size, but as far as I can tell, the only function in my code whose name was not mangled is main(). If true, I humbly suggest that the documentation be reworded. (If this means I should fill out a ticket, tell me where to go.)

I have encountered and a related problem, which may well have been the same thing. When I tried to produce a BrowserProductionRun, the resulting JavaScript files lacked any references to anything but the main() function.

I am writing a JavaScript library that I want to call from an HTML file, so I have a number of functions that aren’t called within the module itself, but will be called from JavaScript. Unfortunately, Kotlin’s Dead Code Elimination was eliminating those functions. As per this page, simply adding

dceTask {
   keep("myModule.myFunction")
}

to build.gradle.kts did the trick.

Is this the only way to prevent the compiler from eliminating functions it thinks are pointless?

1 Like