【发布时间】:2020-02-16 20:06:50
【问题描述】:
我正在尝试使用 jetbrains 团队的 Kotlin 类型安全包装器为在后端运行 ktor 和在前端运行 react 的 Kotlin Multiplatform 项目配置模板。要在前端和后端之间共享代码,我需要使用 gradle
build.gradle.kts:
val kotlin_version: String by project
val ktor_version: String by project
val logback_version: String by project
val annotations_version: String by project
val kotlin_react_version: String by project
val kotlin_react_dom_version: String by project
val kotlin_extensions_version: String by project
val kotlin_css_version: String by project
val kotlin_css_js_version: String by project
val kotlin_styled_version: String by project
val kotlinx_serialization_version: String by project
val kotlinx_html_version: String by project
plugins {
kotlin("multiplatform") version "1.3.61"
kotlin("kapt") version "1.3.61"
kotlin("plugin.serialization") version "1.3.61"
}
apply {
plugin("kotlin-dce-js")
}
group = "com.jaro2gw"
version = "0.0.1"
repositories {
mavenCentral()
mavenLocal()
maven(url = "https://kotlin.bintray.com/kotlin-eap")
maven(url = "https://kotlin.bintray.com/js-externals")
maven(url = "https://kotlin.bintray.com/kotlin-js-wrappers")
maven(url = "https://dl.bintray.com/kotlinx/kotlinx")
jcenter()
}
kotlin {
js("frontend") {
useCommonJs()
nodejs()
browser {
compilations.all {
kotlinOptions {
metaInfo = true
sourceMap = true
sourceMapEmbedSources = "always"
moduleKind = "commonjs"
main = "call"
}
}
}
}
jvm("backend")
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
val frontendMain by getting {
dependsOn(commonMain)
dependencies {
implementation(kotlin("stdlib-js", kotlin_version))
implementation(kotlinDependency("react", kotlin_react_version))
implementation(kotlinDependency("react-dom", kotlin_react_dom_version))
implementation(kotlinDependency("extensions", kotlin_extensions_version))
implementation(kotlinDependency("css", kotlin_css_version))
implementation(kotlinDependency("css-js", kotlin_css_js_version))
implementation(kotlinDependency("styled", kotlin_styled_version))
implementation(kotlinxDependency("html-js", kotlinx_html_version))
implementation(kotlinxDependency("serialization-runtime-js", kotlinx_serialization_version))
implementation("org.jetbrains:annotations:$annotations_version")
implementation(npm("webpack"))
implementation(npm("webpack-cli"))
implementation(npm("webpack-dev-server"))
implementation(npm("react"))
implementation(npm("react-dom"))
implementation(npm("react-draggable"))
implementation(npm("react-list"))
implementation(npm("react-is"))
implementation(npm("inline-style-prefixer"))
implementation(npm("core-js"))
implementation(npm("styled-components"))
implementation(npm("jquery"))
}
}
val backendMain by getting {
dependsOn(commonMain)
dependencies {
implementation(kotlin("stdlib-jdk8", kotlin_version))
implementation(ktorDependency("server-netty"))
implementation(ktorDependency("server-core"))
implementation(ktorDependency("locations"))
implementation(ktorDependency("server-sessions"))
implementation(ktorDependency("websockets"))
implementation(ktorDependency("gson"))
implementation("ch.qos.logback:logback-classic:$logback_version")
}
}
}
}
fun ktorDependency(name: String, version: String = ktor_version) = "io.ktor:ktor-$name:$version"
fun kotlinDependency(name: String, version: String) = "org.jetbrains:kotlin-$name:$version"
fun kotlinxDependency(name: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$name:$version"
gradle.properties:
kotlin.code.style=official
kotlin_version=1.3.61
ktor_version=1.3.0
logback_version=1.2.1
kotlin_react_version=16.9.0-pre.90-kotlin-1.3.61
kotlin_react_dom_version=16.9.0-pre.90-kotlin-1.3.61
kotlin_extensions_version=1.0.1-pre.90-kotlin-1.3.61
kotlin_css_version=1.0.0-pre.90-kotlin-1.3.61
kotlin_css_js_version=1.0.0-pre.90-kotlin-1.3.61
kotlin_styled_version=1.0.0-pre.90-kotlin-1.3.61
annotations_version=16.0.2
kotlinx_serialization_version=0.11.1
kotlinx_html_version=0.6.12
项目结构如下:
/src
/backendMain (ktor kotlin code)
/commonMain
/kotlin
/model
>User.kt
/frontendMain
/kotlin
>index.kt
/resources
/public
>index.html
/webpack.config.d
>webpack.config.js
User.kt
package model
data class User(val ID: Long, val name: String)
index.kt
import kotlinext.js.require
import kotlinext.js.requireAll
import react.dom.render
import kotlin.browser.document
import model.User
fun main() {
requireAll(require.context("kotlin", true, js("/\\.css$/")))
val user = User(1, "ReactUser")
render(document.getElementById("root")) {
+"Hello, $user!"
}
}
index.html
<!doctype html>
<html lang="en">
<head>
<!-- some meta information, shortcut icon and title -->
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div>Hello</div>
<div id="root"></div>
</body>
</html>
webpack.config.js:
path = require("path")
config = config || {};
config.devServer = config.devServer || {};
config.devServer = {
"hot": true,
"open": false,
"port": 3000,
contentBase: [
path.resolve(__dirname, "..\\..\\..\\processedResources\\frontend\\main\\public")
]
}
config.devServer.proxy = config.devServer.proxy || {};
config.devServer.proxy = {
"/api": "https://localhost:8080"
}
config.devServer.watchOptions = config.devServer.watchOptions || {};
config.devServer.watchOptions = {
"aggregateTimeout": 5000,
"poll": 1000
};
module.exports = {
entry: {
main: path.resolve(__dirname, "kotlin\\kotlin-fullstack-mpp-frontend.js")
}
}
后端运行流畅,但是前端无法加载生成的 .js 文件(我认为?)。
访问localhost:3000 时预期的 html 页面应如下所示:
Hello
Hello, (ID=1, name="ReactUser")!
但我得到的只是第一个Hello
我认为问题在于自动生成的webpack.config.js 。我在网上搜索了一下,发现您可以在项目中包含您自己的webpack.config.js 文件。我设法设置了contentBase、proxy 和其他选项,但似乎无法正确配置entry.main 选项?我认为项目结构也可能在这里发挥作用。 build文件夹结构如下:
/build
/js
/node_modules (project dependencies)
/packages
/kotlin-fullstack-mpp-frontend
/kotlin
/kotlin-fullstack-mpp-frontend (compiled common code)
>kotlin-fullstack-mpp-frontend.js (compiled frontend code)
/node-modules (not sure what is here)
>package.json
>webpack.config.js
/packages_imported (kotlin wrapper for react)
>package.json
>yarn.lock
/processedResources
/frontend
/main
/public
>index.html
/reports
/webpack
/kotlin-fullstack-mpp-frontend
>webpack.config.evaluated.js
为了构建和运行我使用 gradlew frontendBrowserRun -t 的 react 应用程序
整个项目都可以在这里访问:https://github.com/jaro2gw/kotlin-fullstack-mpp
[编辑]
这个问题已经过时了,因为 Intellij IDEA 现在包含一个用于 kotlin 多平台项目的项目向导。
【问题讨论】:
-
你有没有让它工作并有一个最新的 git repo 可以查看?
-
我认为这个问题现在已经过时了,因为现在 Intellij IDEA 包括一个用于 kotlin 多平台项目的项目向导。
-
但是,如果您仍然想查看一些实际代码 - 这是我使用上述项目向导创建的另一个 repo。 github.com/jaro2gw/kotlin-multiplatform-full-stack
标签: reactjs gradle kotlin webpack