如何从常规Java脚本调用Kotlin / JS函数?

时间:2020-02-12 07:37:11

标签: javascript gradle kotlin kotlin-js

我一直在使用Kotlin开发小型2D仿真软件,并且我正在使用Kotlin多平台项目以使其在JVM和浏览器中均可运行。到目前为止,效果很好。

但是,当我想从常规Javascript调用Kotlin / JS中定义的函数时遇到问题。

为使我的应用程序在浏览器中正常运行,我在运行“ build” Gradle任务后在“ build / distributions”文件夹下添加了一个大型JS文件。当我的Kotlin / JS应用程序包含一个 main()函数时,打开引用该JS文件的HTML pag时会自动调用此函数,并且效果很好。

但是,如果我删除了main函数,而是创建了一个 start()函数,该函数应该手动调用(例如,单击按钮后),那么它将无法正常工作:它表示即使在Kotlin代码中声明了函数 start(),也未定义。

打开生成的JS文件后,似乎确实没有 start()函数。看来所有函数的名称都已缩小。

我尝试添加 @JsName ,但没有任何改变。

所以我想我做错了,但是我真的不知道该怎么做以及如何使它起作用。

注意:我正在使用Kotlin 1.3.70

编辑:这是我的build.gradle.kts的核心:

plugins {
    kotlin("js") version "1.3.70-eap-184"
}


repositories {
    mavenLocal()
    mavenCentral()

    maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
}

dependencies {

}

kotlin {
    target {
        nodejs {

        }
        browser {
            webpackTask {
                mode = org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode.PRODUCTION
                bin = "$projectDir/node_modules/$bin"
            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

您应该使用模块名称和限定名称来调用函数:

https://kotlinlang.org/docs/reference/js-to-kotlin-interop.html#package-structure

package my.qualified.packagename

fun foo() = "Hello"
alert(myModule.my.qualified.packagename.foo());

https://kotlinlang.org/docs/reference/js-to-kotlin-interop.html#jsname-annotation

在某些情况下(例如,为了支持重载),Kotlin编译器会破坏JavaScript代码中生成的函数和属性的名称。要控制生成的名称,可以使用@JsName注释

UPD: 您可以通过两种方式更改模块名称:

1)如果使用gradle,则可以将此代码添加到build.gradle

compileKotlinJs {
    kotlinOptions.outputFile = "${rootDir}/web/app.js" // should be valid js variable name
}

或在您的build.gradle.kts

kotlin {
    target {
        compilations.all {
            kotlinOptions.outputFile = "${rootDir}/web/app.js"
        }
    }
}

在这种情况下,您应该在app.js文件夹中使用生成的文件(web) (您可以使用其他文件夹和文件名)。

2)您应该创建文件夹webpack.config.d并创建具有任何名称和内容的js文件,该内容应为webpack配置库模式

config.output = config.output || {} // just in case where config.output is undefined
config.output.library = "libraryName" // should be valid js variable name