Идиоматическая установка Kotlin2JS Gradle - PullRequest
0 голосов
/ 19 марта 2019

Я хочу написать библиотеку JavaScript в Kotlin, используя 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
есть котлинские скрипты. Фрагмент кода для 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 , но я бы предпочел автоматизировать объединение этих источников в один.

Я также попытался отключить настройку 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 it описывают другой вид плагина для помощи веб-разработке, но опять же Все примеры только 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")
    }
}

В другом сообщении в блоге предлагаются некоторые Gist с командами, которые якобы извлекают файлы JavaScript из зависимостей и помещают их в мой выходной каталог. Я могу себе представить, что это сработает, но я пока не готов согласиться с тем, что это будет лучшим способом решения проблем, что нет более упорядоченного способа достижения этого результата.

1 Ответ

1 голос
/ 19 марта 2019

Webpack может использоваться для создания единого JS, содержащего все зависимости.

https://github.com/eggeral/kotlin-single-js-file-lib показывает полный пример

  1. Убедитесь, что KotlinJSКомпилятор использует как модульную систему, понятную веб-пакету.

    tasks.withType<Kotlin2JsCompile> {
        kotlinOptions {
            moduleKind = "umd"
        }
    }
    
  2. Скопируйте все зависимости в какое-то место в каталоге сборки

    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")
    }
    
  3. Используйте плагин 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"))
    }
    
  4. Убедитесь, что все выполняется на gradle build

    tasks {
        named("webpack") { dependsOn("assembleJsLib") }
        assemble { dependsOn("webpack") }
    }
    
  5. Создание минимального package.json для Npm.

    {
        "devDependencies": {
            "webpack": "^4.29.0",
            "webpack-cli": "^3.2.1"
        }
    }
    
  6. Создание минимального 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'),
        }
    
    };
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...