我也想在Kotlin中编写一个JavaScript库,使用Gradle作为构建工具,并以Kotlin作为其配置语言。最后,我想得到一个可以用作独立库的JS文件,即将Kotlin库(其中的所有必需部分)捆绑到其中。
要使这项工作看起来像什么最少的设置?特别是,如何将Kotlin库捆绑在一起?
这是我到目前为止所拥有的。
https://kotlinlang.org/docs/tutorials/javascript/getting-started-gradle/getting-started-with-gradle.html
仅使用Groovy来配置Gradle。它还将buildscript
与apply plugin
语句结合使用,在这种情况下,我给人的总体印象是,这被认为是传统方法,而plugins
部分将是首选方法。>
https://kotlinlang.org/docs/reference/using-gradle.html#targeting-javascript
有Kotlin脚本。 settings.gradle
的代码片段在Groovy和Kotlin之间没有切换,但是在我的settings.gradle.kts
中无需修改就可以正常工作。这样会创建一个文件js/build/classes/kotlin/main/${project.name}.js
,如下所示(带有moduleKind = "commonjs"
):
(function (_, Kotlin) { … }(module.exports, require('kotlin')));
因此,我可以看到它包含我的源代码的转译版本,但它不会单独运行;它需要标准库的副本。我可以使用
将其添加为依赖项dependencies {
compile("org.jetbrains.kotlin:kotlin-stdlib-js")
testImplementation("org.jetbrains.kotlin:kotlin-test-js")
}
,但是仅凭这一点还不足以使标准库最终出现在输出中。我想我也许可以使用kotlin
npm package,但我更愿意将这些资源自动组合成一个。
我还尝试使用禁用noStdlib
设置
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile> {
kotlinOptions {
noStdlib = false
}
}
包含相当多的猜测,因为执行此类操作的示例倾向于使用Groovy表示法和compileKotlin2Js
块,如果我的构建脚本位于Kotlin中,则会导致语法错误。因此,有了上面的代码,我得到了一个编译器错误:
w: Unable to find kotlin-stdlib-js.jar in the Kotlin home directory.
Pass either '-no-stdlib' to prevent adding it to the classpath, or
the correct '-kotlin-home'
那么我该如何使用依赖项提供的标准库呢?这甚至是正确的方法吗?
https://blog.kotlin-academy.com/kotlin-js-configuration-made-simple-ef0e361fcd4和它引用的https://github.com/Kotlin/kotlin-frontend-plugin描述了另一种有助于Web开发的插件,但是同样,所有示例仅是Groovy的,我什至无法解决该插件。我尝试过类似的事情
plugins {
id("org.jetbrains.kotlin.frontend").version("0.0.45")
}
repositories {
jcenter()
maven {
url = java.net.URI("https://dl.bintray.com/kotlin/kotlin-eap")
}
}
Another blog post建议使用一些Gist命令,据称这些命令将从依赖项中提取JavaScript文件并将其放入我的输出目录中。我可以想象这会起作用,但是我还不愿意接受这是解决问题的最佳方法,没有其他简化方法可以实现此结果。
答案 0 :(得分:1)
可以使用Webpack来创建包含所有依赖项的单个JS。
https://github.com/eggeral/kotlin-single-js-file-lib显示了完整的示例
确保KotlinJS编译器使用webpack可以理解的模块系统。
tasks.withType<Kotlin2JsCompile> {
kotlinOptions {
moduleKind = "umd"
}
}
将所有依赖项复制到构建目录中的某个位置
task<Copy>("assembleJsLib") {
configurations.compile.get().resolve().forEach { file: File ->
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement ->
val path = fileTreeElement.path
(path.endsWith(".js") || path.endsWith(".js.map")) && (path.startsWith("META-INF/resources/") ||
!path.startsWith("META-INF/"))
}
})
}
from(tasks.withType<ProcessResources>().map { it.destinationDir })
into("$buildDir/js")
dependsOn("classes")
}
使用com.moowork.node
插件运行Webpack。
import com.moowork.gradle.node.task.NodeTask
plugins {
id("kotlin2js") version "1.3.21"
id("com.moowork.node") version "1.2.0"
}
node {
download = true
}
task<NodeTask>("webpack") {
dependsOn("npm_install")
setScript(File("$projectDir/node_modules/webpack/bin/webpack"))
}
确保在gradle build
上执行所有操作
tasks {
named("webpack") { dependsOn("assembleJsLib") }
assemble { dependsOn("webpack") }
}
为Npm创建最小的package.json
。
{
"devDependencies": {
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1"
}
}
创建最小的webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: path.resolve(__dirname, 'build/classes/kotlin/main/kotlin-lib.js'),
resolve: {
"modules": [
path.resolve(__dirname, 'build/js'),
"node_modules"
]
},
output: {
filename: "kotlin-lib.js",
libraryTarget: "umd",
path: path.resolve(__dirname, 'build/webpack'),
}
};