Kotlin Multiplatform Compose + 桌面 + Web + 移动

Kotlin Multiplatform Compose + Desktop + Web + Mobile

目前是否可以有一个使用 compose 的 kotlin 多平台项目来同时共享桌面、Web 和移动设备的 ui 代码?我找到的所有示例都只涵盖了 JS Front + Jvm Backend 或 JVM Android + Desktop + Common Module 的多平台,我在同时使用所有这些设置项目时遇到了麻烦。

我试过:

plugins {
    kotlin("multiplatform")
    id("org.jetbrains.compose") version "1.0.1-rc2"
    id("com.android.library")
}
kotlin {
    android()
    jvm("desktop") {
       ...
    }
    js{
       ...
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
               ...
            }
        }
        val commonTest by getting {
            dependencies {
               ...
            }
        }
        val androidMain by getting {
            dependencies {
                ...
            }
        }
        val androidTest by getting {
            dependencies {
                ...
            }
        }
        val desktopMain by getting {
            dependencies {
                ...
            }
        }
        val desktopTest by getting
        val jsMain by getting{
            dependencies{
                ...
            }
        }
        val jsTest by getting {
            dependencies {
                ...
            }
        }
    }
}

但它产生错误:

:common:jsMain: Could not resolve org.jetbrains.compose.runtime:runtime:1.0.1-rc2.
Required by:
    project :common

如果我评论 JS 相关的部分它有效,或者如果我评论所有非 js 相关的东西它也有效

评论所有与撰写相关的内容也有效

问题只出现在组合一切的时候

简短的回答是:,目前不可能。

JB 团队正在开发这样的支持,可以在 these examples 中进行测试,但目前它是实验性的,不能保证很快就会发布。 Compose JB 版本现在与 Android Compose 同步,所以我预计 1.2.0 将在大约同一时间由两者发布,即使 Web 支持还没有完成。


我无法重现您的错误,但我假设您没有从公共依赖项中删除 compose.foundationcompose.material

目前只有compose.runtime可用于公共模块,这使得此时几乎不可能进行任何布局:甚至ButtonText都不是可用。

在JS应用示例中可以看到,Text不是从androidx.compose.material.Text导入的,而是从org.jetbrains.compose.web.dom.Text导入的,这是完全不同的元素,所以不能使用在一个公共模块中。

在这一点上,我会说 Compose JS 是另一个允许您以 Compose 风格编写 UI 的框架。

**

This answer is not an exact answer to this question. The correct answer for this is the answer by @PhilipDukhov. However, this might help others who land on this page for finding a solution to the other problem I am just leaving it here. For more info read comments between me and @PhilipDukhov for this answer.

**

是的,可以将所有三个模块都放在一个项目中。 TLDR

我做了一些变通办法,并设法在一个项目中得到所有东西,即

  1. 为桌面撰写
  2. 撰写 Android
  3. 为 Web 撰写

进一步前的建议

Although below code snippets works and by going through you will be able to achieve what you want actually. I personally recommend you to just go to the Github repository here . I think it will save time if you are creating a new project. However if you are adding web module to current KMM project continue reading.

可以通过保持正确的依赖项来解决问题

所以项目结构应该是这样的

注意:如果您正在创建一个新的 KMM 项目,您将只有通用模块、桌面模块和 android 模块。(如您所知)

第 1 步:您需要将 a 文件夹添加到根目录(android、common、desktop 文件夹所在的位置)并将其命名为 web(不应该事)

第 2 步:将几个文件夹添加到这个新创建的目录 web 你的网站目录应该是这样的

注意:不要添加构建(它是自动生成的)仅添加

src/jsMain
   -kotlin
   -resources
src/jsTest 
    -kotlin
   -resources

并创建一个名为 build.gradle.kts

的文件

第 3 步:将这个新添加的 Gradle 文件的内容更改为类似这样的内容

import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat

plugins {
    kotlin("multiplatform")
    id("org.jetbrains.compose") version "1.0.0"
}

group = "com.example"
version = "1.0"

kotlin {
    js(IR) {
        browser {
            testTask {
                testLogging.showStandardStreams = true
                useKarma {
                    useChromeHeadless()
                    useFirefox()
                }
            }
        }
        binaries.executable()
    }
    sourceSets {
        val jsMain by getting {
            dependencies {
                implementation(compose.web.core)
                implementation(compose.runtime)
            }
        }
        val jsTest by getting {
            dependencies {
                implementation(kotlin("test-js"))
            }
        }
    }
}

第 4 步:将 Main.kt 添加到 jsMain/kotlin,内容如下

 renderComposable(rootElementId = "root") {
    Div(
        attrs = {
            // specify attributes here
            style {
                // specify inline style here
            }
        }
    ) {
        Text("A text in <div>")
    }
}

第 4 步:将 index.html 添加到 jsMain/resources,内容为

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MultiplatformTest Sample</title>
</head>
<body>
<div id="root"></div>
<script src="web.js"></script>
</body>
</html>

Note: web.js file mentioned in the above snippet is sensitive and the project generated you need to make sure it is web.js only or else the folder_name.js which you created in step 1

第 5 步:最后将 Web 模块添加到 settings.gradle.kts 文件

pluginManagement {
    repositories {
        google()
        jcenter()
        gradlePluginPortal()
        mavenCentral()
        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    }
    
}
rootProject.name = "MultiplatformTest"


include(":android")
include(":desktop")
include(":common")
include(":web")  // Note web module is included here 

我已经创建了一个 repo 检查这个 repo,你可以将它用作你的项目的模板

Link 到回购:https://github.com/PSPanishetti/ComposeMultiplatform

如果您有任何疑问,请随时询问他们。

Jetbrains 使用一些示例更新了 github 存储库:

https://github.com/JetBrains/compose-jb/tree/master/experimental/examples

现在可以使用“1.2.0-alpha01-dev675”版本,但并非所有组件都能正常工作,它仍处于早期的 alpha 阶段。