Is it possible to import a JavaScript file in a Kotlin/JS project?

2.6k views Asked by At

If I have a JavaScript file called myfile.js as follows:

function myJsFunc() { return "Hello from JavaScript"; }

How can I import this file into a Kotlin/JS project and invoke myJsFunc() from Kotlin code?

2

There are 2 answers

6
Joffrey On

You will probably find some interesting information in the doc: Use JavaScript from Kotlin.

Essentially, you'll need to write external declarations manually to tell Kotlin about the functions and types that should be available in JS.

Making the file itself available depends on your build and how you deploy your code.

1
Martynas Petuška On

Copied-over from slack discussion


First you need to declare an npm dependency in gradle

kotlin.sourceSets.named("jsMain") {
  dependencies {
    implementation(npm("package-name", "version"))
  }
}

Then you can either use ./gradlew generateExternals and pray that dukat works or write external declarations yourself.

package-name and version appears the same as it would in package.json, so all the protocols like file:xxx are supported as well.

You can also hack it with local TS sources, however I do not recommend it. If you still must stick with it, create a small npm module somewhere on your repo and use that via file:path/to/that/module version instead. I recommend generating absolute path to that module in gradle instead of trying to work out relative path from package.json that kotlin plugin generates

kotlin.sourceSets.named("jsMain") {
  dependencies {
    val pathToLocalNpmModule = rootProject.projectDir.resolve("js/my-module").canonicalPath
    implementation(npm("my-module", "file:$pathToLocalNpmModule"))
  }
}

Finally, for that particullar function, kotlin external declaration would look like this (assuming that you point your package.json#main field directly to that js file)

// Explicit export
export function myJsFunc() { return "Hello from JavaScript"; }

// Default export
export default myJsFunc
// Explicit export
@JsModule("my-module")
public external fun myJsFunc(): String

// Default export
@JsModule("my-module")
@JsName("default")
public external fun myJsFunc(): String

Now on the inverse, if you want to integrate your kotlin/js gradle module into local js/ts project, I recommend just using ./gradlew pack task provided by npm-publish gradle plugin (configures itself, just apply it) and use the bundle via file:xxx version protocol in your js/ts package.json.