我尝试使用Kotlin创建一个全栈项目。由于多平台项目在Kotlin中处于试验阶段,因此没有太多可用信息,因此我尝试从IDEA项目向导的项目框架(Kotlin> JS Client和JVM Server)开始。它生成基本代码,甚至添加“ hello world”类型的示例代码。
但是,当我构建项目并启动它(逐步运行)时,网页控制台会告诉我kotlin-js软件包不可用:
The script from “http://127.0.0.1:8080/static/piggy-bank.js” was loaded even though its MIME type (“”) is not a valid JavaScript MIME type.
Loading failed for the <script> with source “http://127.0.0.1:8080/static/piggy-bank.js”. [127.0.0.1:8080:8:1](http://127.0.0.1:8080/)
该示例使用Netty作为嵌入式Web服务器,并且预先生成的代码为:
embeddedServer(Netty, port = 8091, host = "127.0.0.1") {
routing {
get("/") {
call.respondHtml {
head {
title("Hello from Ktor!")
}
body {
+"${hello()} from Ktor. Check me value: ${Sample().checkMe()}"
div {
id = "js-response"
+"Loading..."
}
script(src = "/static/piggy-bank.js") {}
}
}
}
static("/static") {
resource("piggy-bank.js")
}
}
}.start(wait = true)
在static
文件夹中看起来已编译的js代码,但是gradle任务不会创建,也不会将生成的文件复制到静态文件夹中。
通过一些重构,我成功管理了示例。首先,我找到了所需的代码并在build/js/packages/piggy-bank/kotlin
中找到了,所以我更改了静态配置:
val buildDir = System.getProperty("user.dir")+"/build"
val jsDir = "$buildDir/js/packages/piggy-bank/kotlin"
val jsImpDir = "$buildDir/js/packages_imported/kotlin/1.3.50"
embeddedServer(Netty, port = 8090, host = "127.0.0.1") {
routing {
get("/") {
call.respondHtml {
head {
title("Hello from Ktor!")
}
body {
+"${hello()} from Ktor. Check me value: ${Sample().checkMe()}"
div {
id = "js-response"
+"Loading..."
}
// Note, that I had to add Kotlin system js file manually!
script(src = "/static/kotlin.js") {}
script(src = "/static/piggy-bank.js") {}
}
}
}
static("static") {
// Here comes the new references
files( "$jsDir")
files( "$jsImpDir")
}
}
}.start(wait = true)
这暂时解决了问题,但仅在IDEA(直接引用build文件夹)中起作用。正确的解决方案应该是,gradle构建脚本创建一个自包含的,完全可操作的代码。
这是我(也是生成的)gradle文件(我已经从Groovy迁移到Kotlin DSL):
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
buildscript {
repositories {
jcenter()
}
}
plugins {
id("org.jetbrains.kotlin.multiplatform") version "1.3.50"
}
repositories {
jcenter()
maven( "https://dl.bintray.com/kotlin/ktor" )
mavenCentral()
}
val ktor_version = "1.1.3"
val logback_version = "1.2.3"
kotlin {
js {
browser { }
}
jvm {
compilations.named("main") {
tasks.getByName<Copy>(processResourcesTaskName) {
dependsOn("jsBrowserWebpack")
tasks.named<KotlinWebpack>("jsBrowserWebpack") {
println(this.outputs)
from(entry.name, destinationDirectory)
}
}
}
}
sourceSets {
commonMain {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
commonTest {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
named("jvmMain") {
dependencies {
implementation( kotlin("stdlib-jdk8"))
implementation( "io.ktor:ktor-server-netty:$ktor_version")
implementation( "io.ktor:ktor-html-builder:$ktor_version")
implementation( "ch.qos.logback:logback-classic:$logback_version")
}
}
named("jvmTest") {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-testng"))
}
}
named("jsMain") {
dependencies {
implementation( kotlin("stdlib-js"))
}
}
named("jsTest") {
dependencies {
implementation( kotlin("test-js"))
}
}
}
}
tasks.register<JavaExec>("run") {
dependsOn("jvmJar")
group = "application"
main = "sample.SampleJvmKt"
val t = tasks.named<Jar>("jvmJar")
classpath(configurations.named("jvmRuntimeClasspath"), t.get() )
}
如何更改构建文件以构建正确的代码?
答案 0 :(得分:0)
我重现了"org.jetbrains.kotlin.multiplatform" 1.3.50
的问题,但未能重现1.3.61
。您可以在项目中检查它吗?