MPP web wizard: integrate Ktor inside #KT-27491 Fixed

This commit is contained in:
Mikhail Glukhikh
2018-10-17 13:21:05 +03:00
parent c770a80ab9
commit 570c770d58
2 changed files with 146 additions and 6 deletions
File diff suppressed because one or more lines are too long
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder
import java.io.BufferedWriter
class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatformModuleBuilder() {
@@ -28,6 +29,12 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
override fun getDescription() =
"Multiplatform Gradle projects allow reusing the same Kotlin code between JS Client and JVM Server."
override fun BuildScriptDataBuilder.setupAdditionalDependencies() {
addBuildscriptRepositoriesDefinition("jcenter()")
addRepositoriesDefinition("maven { url \"http://dl.bintray.com/kotlin/ktor\" }")
addRepositoriesDefinition("jcenter()")
}
override fun createProjectSkeleton(rootDir: VirtualFile) {
val src = rootDir.createChildDirectory(this, "src")
@@ -38,6 +45,14 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
val jsMain = src.createKotlinSampleFileWriter(jsSourceName, jsTargetName)
val jsTest = src.createKotlinSampleFileWriter(jsTestName, fileName = "SampleTestsJS.kt")
val jvmRoot = src.findChild(jvmSourceName)!!
val jvmResources = jvmRoot.createChildDirectory(this, "resources")
val logBack = jvmResources.createChildData(this, "logback.xml").bufferedWriter()
val jsRoot = src.findChild(jsSourceName)!!
val jsResources = jsRoot.createChildDirectory(this, "resources")
val requireMinJs = jsResources.createChildData(this, "require.min.js").bufferedWriter()
try {
commonMain.write(
"""
@@ -52,10 +67,6 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
}
fun hello(): String = "Hello from ${"$"}{Platform.name}"
fun main(args: Array<String>) {
println(hello())
}
""".trimIndent()
)
@@ -63,6 +74,15 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
"""
package sample
import io.ktor.application.*
import io.ktor.html.*
import io.ktor.http.content.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.html.*
import java.io.*
actual class Sample {
actual fun checkMe() = 42
}
@@ -70,13 +90,71 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
actual object Platform {
actual val name: String = "JVM"
}
fun main(args: Array<String>) {
embeddedServer(Netty, port = 8080, host = "127.0.0.1") {
val currentDir = File(".").absoluteFile
environment.log.info("Current directory: ${"$"}currentDir")
val webDir = listOf(
"web",
"../src/jsMain/web",
"src/jsMain/web"
).map {
File(currentDir, it)
}.firstOrNull { it.isDirectory }?.absoluteFile ?: error("Can't find 'web' folder for this sample")
environment.log.info("Web directory: ${"$"}webDir")
routing {
get("/") {
call.respondHtml {
body {
+"${"$"}{hello()} from Ktor. Check me value: ${"$"}{Sample().checkMe()}"
div {
id = "js-response"
+"Loading..."
}
script(src = "/static/require.min.js") {
}
script {
+"require.config({baseUrl: '/static'});\n"
+"require(['/static/$name.js'], function(js) { js.sample.helloWorld('Hi'); });\n"
}
}
}
}
static("/static") {
files(webDir)
}
}
}.start(wait = true)
}
""".trimIndent()
)
logBack.write(
"""
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
""".trimIndent()
)
jsMain.write(
"""
package sample
import kotlin.browser.*
actual class Sample {
actual fun checkMe() = 12
}
@@ -84,9 +162,19 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
actual object Platform {
actual val name: String = "JS"
}
@Suppress("unused")
@JsName("helloWorld")
fun helloWorld(salutation: String) {
val message = "${"$"}salutation from Kotlin.JS ${"$"}{hello()}, check me value: ${"$"}{Sample().checkMe()}"
document.getElementById("js-response")?.textContent = message
}
""".trimIndent()
)
requireMinJs.write(requireMinJsContent)
commonTest.write(
"""
package sample
@@ -135,16 +223,26 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
""".trimIndent()
)
} finally {
listOf(commonMain, commonTest, jvmMain, jvmTest, jsMain, jsTest).forEach(BufferedWriter::close)
listOf(commonMain, commonTest, jvmMain, jvmTest, jsMain, jsTest, logBack, requireMinJs).forEach(BufferedWriter::close)
}
}
override fun buildMultiPlatformPart(): String {
return """
def ktor_version = '1.0.0-beta-1'
def logback_version = '1.2.3'
kotlin {
targets {
fromPreset(presets.jvm, '$jvmTargetName')
fromPreset(presets.js, '$jsTargetName')
fromPreset(presets.js, '$jsTargetName') {
[tasks.getByName(compilations.main.compileKotlinTaskName), tasks.getByName(compilations.test.compileKotlinTaskName)]*.kotlinOptions {
languageVersion = "1.3"
moduleKind = "umd"
sourceMap = true
metaInfo = true
}
}
}
sourceSets {
$commonSourceName {
@@ -161,6 +259,9 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
$jvmSourceName {
dependencies {
implementation 'org.jetbrains.kotlin: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"
}
}
$jvmTestName {
@@ -181,6 +282,35 @@ class KotlinGradleWebMultiplatformModuleBuilder : KotlinGradleAbstractMultiplatf
}
}
}
def webFolder = new File(project.buildDir, "../src/jsMain/web")
def jsCompilations = kotlin.targets.js.compilations
task populateWebFolder(dependsOn: [jsMainClasses]) {
doLast {
copy {
from jsCompilations.main.output
from kotlin.sourceSets.jsMain.resources.srcDirs
jsCompilations.test.runtimeDependencyFiles.each {
if (it.exists() && !it.isDirectory()) {
from zipTree(it.absolutePath).matching { include '*.js' }
}
}
into webFolder
}
}
}
jsJar.dependsOn(populateWebFolder)
task run(type: JavaExec, dependsOn: [jvmMainClasses, jsJar]) {
main = "sample.Sample${jvmTargetName.capitalize()}Kt"
classpath { [
kotlin.targets.jvm.compilations.main.output.files,
configurations.jvmRuntimeClasspath,
] }
args = []
}
""".trimIndent()
}
}