如何在 jvm + js Kotlin Multiplatform 项目中共享 org.w3c.dom 相关代码?

时间:2021-07-06 18:00:05

标签: kotlin kotlin-multiplatform

我想在 org.w3c.dom.Node 源集中编写一些与 commonMain 相关的代码,但编译器不满意:

import org.w3c.dom.Node // compiler error here: Unresolved reference: Node

fun sayHello(node: Node) {
    node.ownerDocument!!.createElement("div").textContent = "hello"
}

有什么办法吗?我的目标是使用此通用代码在 jvm 部分处理 XML,并在 js 部分处理浏览器 DOM。

请注意,相同的代码在 jvmMainjsMain 源集中正确编译。

以下是有关我的设置的一些信息。

我使用 IntelliJ IDEA 2021.1 创建了一个 Kotlin 多平台库项目。 new project wizard

然后我删除了本机源集,只保留 commonjvmjs(浏览器目标)。 project source sets

我在 1.5.20 中将 kotlin 版本更改为 build.gradle.kts(以防万一它可能有帮助,之前是 1.4.32):

import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack

plugins {
    kotlin("multiplatform") version "1.5.20"
    application
}

group = "me.bfreuden.kotlin"
version = "1.0-SNAPSHOT"

repositories {
    jcenter()
    mavenCentral()
}

kotlin {
    jvm {
        compilations.all {
            kotlinOptions.jvmTarget = "11"
        }
        testRuns["test"].executionTask.configure {
            useJUnit()
        }
        withJava()
    }
    js(IR) {
        moduleName = "hello"
        binaries.executable()
        browser {
            webpackTask {
                output.libraryTarget = "commonjs2"
            }
            commonWebpackConfig {
                cssSupport.enabled = true
            }
        }
    }

    sourceSets {
        val commonMain by getting 
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val jvmMain by getting
        val jvmTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
            }
        }
        val jsMain by getting
        val jsTest by getting {
            dependencies {
                implementation(kotlin("test-js"))
            }
        }
    }
}

application {
    mainClass.set("MainKt")
}

tasks.getByName<KotlinWebpack>("jsBrowserProductionWebpack") {
    outputFileName = "hello.js"
}

1 个答案:

答案 0 :(得分:1)

如果您查看节点 implementation for Kotlin/JS 你可以看到它是一个 abstract class Node : EventTarget,而在 JVM 上是 interface Node

您现在可能需要创建自己的 expect/actual 声明: 在抽象类上声明 expect 并抑制关于 expect/actual 接口不匹配的错误。

Providing an actual interface for an expected abstract class 正在进行中,尽管一旦修复,commonizer 可能会推断出 kotlin-stdlib 的 org.w3c.dom API 与 JVM 提供的 API 之间的相似之处