kotlin - 如何在 build.gradle.kts 中的 Kotlin(1.4) 多平台项目中设置 gradle 任务以创建 fatJar

标签 kotlin gradle kotlin-multiplatform fatjar

我一直在寻找一种创建 jar 的方法,其中包含我拥有一个包含前端和后端的功能完备的应用程序所需的一切。 fatJar 是解决方案,但我如何在创建此 fatJar 的 kotlin/多平台项目中创建 gradle 任务? 我找不到开箱即用的解决方案。我必须修改和扩展找到的任务以获得我想要的结果。

最佳答案

所以这是适合我的任务:

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
import org.gradle.jvm.tasks.Jar

val kotlinVersion = "1.4.0"
val serializationVersion = "1.0.0-RC"
val ktorVersion = "1.4.0"

plugins {
    kotlin("multiplatform") version "1.4.0"
    application //to run JVM part
    kotlin("plugin.serialization") version "1.4.0"
    id("com.github.johnrengelman.shadow") version "6.1.0"
}

group = "com.bantolomeus"
version = "0.1"

repositories {
    maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
    mavenCentral()
    jcenter()
    maven("https://kotlin.bintray.com/kotlin-js-wrappers/") // react, styled, ...
}

kotlin {
    jvm {
        withJava()
    }
    js {
        browser {
            binaries.executable()
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(kotlin("stdlib-common"))
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
                implementation("io.ktor:ktor-client-core:$ktorVersion")
//                implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }

        val jvmMain by getting {
            dependencies {
                implementation("io.ktor:ktor-serialization:$ktorVersion")
                implementation("io.ktor:ktor-server-core:$ktorVersion")
                implementation("io.ktor:ktor-server-netty:$ktorVersion")
                implementation("ch.qos.logback:logback-classic:1.2.3")
                implementation("io.ktor:ktor-websockets:$ktorVersion")
                implementation("org.litote.kmongo:kmongo-coroutine-serialization:4.1.1")
            }
        }

        val jsMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-js:$ktorVersion") //include http&websockets

                //ktor client js json
                implementation("io.ktor:ktor-client-json-js:$ktorVersion")
                implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")

                implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.21")
                implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.21")
                implementation(npm("react", "17.0.1"))
                implementation(npm("react-dom", "17.0.1"))
            }
        }
    }
}

application {
    mainClassName = "ServerKt"
}

// include JS artifacts in any JAR we generate
tasks.getByName<Jar>("jvmJar") {
    val taskName = if (project.hasProperty("isProduction")) {
        "jsBrowserProductionWebpack"
    } else {
        "jsBrowserDevelopmentWebpack"
    }
    val webpackTask = tasks.getByName<KotlinWebpack>(taskName)
    dependsOn(webpackTask) // make sure JS gets compiled first
    from(File(webpackTask.destinationDirectory, webpackTask.outputFileName)) // bring output file along into the JAR
}

tasks {
    withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
}

distributions {
    main {
        contents {
            from("$buildDir/libs") {
                rename("${rootProject.name}-jvm", rootProject.name)
                into("lib")
            }
        }
    }
}

// Alias "installDist" as "stage" (for cloud providers)
tasks.create("stage") {
    dependsOn(tasks.getByName("installDist"))
}

tasks.getByName<JavaExec>("run") {
    classpath(tasks.getByName<Jar>("jvmJar")) // so that the JS artifacts generated by `jvmJar` can be found and served
}

// tasks to create an executable jar with all components of the app
tasks.getByName<ShadowJar>("shadowJar") {
    val webpackTask = tasks.getByName<KotlinWebpack>("jsBrowserProductionWebpack")
    dependsOn(webpackTask) // make sure JS gets compiled first
    from(File(webpackTask.destinationDirectory, webpackTask.outputFileName)) // bring output file along into the JAR
    archiveBaseName.set("shadow")
    mergeServiceFiles()
    manifest {
        attributes["Main-Class"] = "ServerKt"
    }
}

// task to create executable jar during build task
//tasks {
//    build {
//        dependsOn(shadowJar)
//    }
//}

我注释掉了最后一部分,不要总是在构建过程中创建 shadowJar (fatJar),因为这只是需要时间,而在我的情况下不需要。 相关任务是最后一个未被注释掉的任务。 我还发布了我的整个 build.gradle.kts 文件,因为您需要一些导入、插件和依赖项(与 jengelman 的 shadowJar 相关的所有内容)。

我希望对遇到同样问题的其他人有所帮助。

关于kotlin - 如何在 build.gradle.kts 中的 Kotlin(1.4) 多平台项目中设置 gradle 任务以创建 fatJar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66855276/

相关文章:

android - 如何为终端和Android Studio运行相同的Gradle守护程序?

gradle - Jitpack和Kotlin跨平台工件groupId

kotlin-multiplatform - 为什么我无法在 Windows 上使用 KMM 插件运行 iOS 项目?

testing - 如何拥有一个使用 JUnit 测试业务逻辑的 KotlinJS 模块?

android - Anko 警报文本颜色显示错误

android - 如何通过 viewModels 实现?

java - 如何使用 Gradle 运行 JUnit 测试?

metadata - 为什么 Kotlin 在 Kotlin 类文件中保存 MetaData?

string - Kotlin 条件格式字符串

java - 如何为 Iotivity 构建 native 库以便在 Java 中加载它们