Мне удалось немного улучшить удобство использования KotlinJ в Angular.Я располагаю свои эксперименты в https://github.com/svok/kotlin-multiplatform-sample
Во-первых, мы должны создать мультиплатформенный подмодуль в Gradle.Мы генерируем js-файлы (среди других возможных платформ).
Затем добавляем в package.json ...
{
"dependencies": {
"kotlin": "^1.3.21",
"proj-common": "file:../build/javascript-compiled"
}
}
proj-common - это наш скомпилированный модуль Kotlin.Путь, по которому создаются файлы kotlin-js.
Таким образом, в машинописном тексте мы просто используем еще один модуль npm
import {sample} from 'proj-common/proj-common';
// For class Sample
sample = new sample.Sample();
// For object Platform
platform = sample.Platform;
Компиляция проходит без необходимости использования // @ts-ignore
Обновление
В приведенном выше объяснении возникла проблема с зависимостями.Они не были экспортированы, но не у всех подзависимостей есть свои эквиваленты в репозитории npm.Приведенный ниже код решает эту проблему.
tasks {
task<Sync>("assembleWeb") {
val dependencies = configurations.get("jsMainImplementation").map {
val file = it
val (tDir, tVer) = "^(.*)-([\\d.]+-\\w+|[\\d.]+)\\.jar$"
.toRegex()
.find(file.name)
?.groupValues
?.drop(1)
?: listOf("", "")
var jsFile: File? = null
copy {
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement ->
val path = fileTreeElement.path
val res = (path.endsWith(".js") || path.endsWith(".map"))
&& (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/"))
if (res && path.endsWith(".js") && ! path.endsWith(".meta.js")) jsFile = fileTreeElement.file
res
}
})
into("$npmTarget/$tDir")
}
jsFile?.also { packageJson(tDir, it, tVer) }
tDir to jsFile
}
.filter { it.second != null }
.map { it.first to it.second!! }
.toMap()
packageJson(npmDir, File(jsOutputFile), project.version.toString(), dependencies)
dependsOn("jsMainClasses")
}
assemble.get().dependsOn("assembleWeb")
}
fun packageJson(dir: String, jsFile: File, version: String, dependencies: Map<String, File> = emptyMap()) {
val deps = dependencies.map {
""""${js2Name(it.value)}": "file:../${it.key}""""
}.joinToString(",\n ")
val text = """
{
"name": "${js2Name(jsFile)}",
"version": "${version}",
"main": "./${jsFile.name}",
"dependencies": {
${deps}
}
}
""".trimIndent()
File("$npmTarget/$dir/package.json").apply {
if (parentFile.exists()) {
parentFile.delete()
}
parentFile.mkdirs()
writeText(text)
}
}
fun js2Name(jsFile: File) = jsFile.name.replace("""\.js$""".toRegex(), "")
Затем импортируйте из переднего подмодуля:
{
"dependencies": {
"proj-common": "file:../build/npm"
}
}
И в файле машинописи:
import {sample} from 'proj-common';
// For class Sample
sample = new sample.Sample();
// For object Platform
platform = sample.Platform;
ПримерПроект см. на https://github.com/svok/kotlin-multiplatform-sample
Обновление 2
Теперь вы можете создавать проекты полного стека с общим подпроектом kotlin так же просто, как просто подключить плагин в gradle
plugins {
id("com.crowdproj.plugins.jar2npm")
}
ThisПлагин автоматически внедрит все ваши jar-пакеты kotlin-js в ваши node_modules во время компиляции.
Проект https://github.com/svok/kotlin-multiplatform-sample теперь переписан с этим плагином.См. proj-angularfront субмодуль.