0

Gradle 项目由 JS 插件设置:

plugins {
    kotlin("js") version("1.6.10")
}

并使用LEGACY编译后端:

kotlin {
    js(LEGACY) {
        // ...
    }
}

我的目标是在 Kotlin 源代码中使用以下依赖项:

dependencies {
    implementation(npm("i18next", "21.6.11"))
    implementation(npm("react-i18next", "11.15.4"))
    implementation(npm("i18next-browser-languagedetector", "6.1.3"))
}

描述前两个依赖项的 JS-Kotlin 桥接非常容易:

@JsModule("i18next")
@JsNonModule
external val i18next: I18n

external interface I18n {
    fun use(module: dynamic): I18n
}

@JsModule("react-i18next")
@JsNonModule
external val reactI18next: ReactI18next

external interface ReactI18next {
    val initReactI18next: dynamic
}

不幸的是,最后一个——i18next-browser-languagedetector它的配置让我有些抓狂。像这样的东西:

@JsModule("i18next-browser-languagedetector")
@JsNonModule
external val LanguageDetector: dynamic

不起作用 - 上述LanguageDetector声明提供的实际值是{},因此i18next不在 Kotlin 代码中使用它(JS 代码 throws You are passing a wrong module! Please check the object you are passing to i18next.use()):

i18next.use(LanguageDetector) // fails

任何人都可以帮我声明一个 JS-Kotlin 桥LanguageDetector吗?

4

1 回答 1

0

好吧,通过一点调试,我设法解决了这个 JS-Kotlin 桥接问题。工作解决方案是以下声明:

@JsModule("i18next-browser-languagedetector")
@JsNonModule
external val i18nextBrowserLanguageDetector: I18nextBrowserLanguageDetector

external interface I18nextBrowserLanguageDetector {
    @JsName("default")
    val LanguageDetector: dynamic
}

现在可以执行i18next初始化链的第一部分:

i18next
    .use(i18nextBrowserLanguageDetector.LanguageDetector)
    .use(reactI18next.initReactI18next)
    // ...

不幸的是,很难说我背后有任何直觉(可能是因为我在 JS 中存在巨大的盲点) - 所以任何额外的澄清或解释仍然会有所帮助。

我最担心的是,LanguageDetector从上面的声明中应该是一个类,但似乎没有办法使用其他东西而不是dynamic属性。当我尝试提起@JsName("default")注释以用它标记某些类协议时,它不会编译:

@JsModule("i18next-browser-languagedetector")
@JsNonModule
@JsName("default")
external class LanguageDetector

在这种情况下,也不可能在接口内使用嵌套类:

@JsModule("i18next-browser-languagedetector")
@JsNonModule
external interface I18nextBrowserLanguageDetector {
    @JsName("default")
    class LanguageDetector
}

因此,虽然它似乎已解决,但仍然非常令人沮丧。

于 2022-02-18T16:22:49.170 回答