Как использовать Javascript артефакт, созданный мультиплатформой kotlin - PullRequest
0 голосов
/ 12 февраля 2020

Я в настоящее время создаю проект kotlin mutliplatform для jvm и js. Мой build.gradle.kts выглядит так:

plugins {
    id ("org.jetbrains.kotlin.multiplatform")
}

repositories {
    mavenCentral()
}

kotlin {
    jvm() {
        compilations["main"].kotlinOptions{
            jvmTarget = "1.8"
        }
    }
    js() {
        compilations["main"].kotlinOptions{
            outputFile = "${buildDir}/nodejs/common.js"
            moduleKind = "commonjs"
            sourceMap = true
            verbose = true
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation (kotlin("stdlib"))
                implementation (kotlin("stdlib-common"))
            }
        }
        val commonTest by getting {
            dependencies {
                implementation (kotlin("test-common"))
                implementation (kotlin("test-annotations-common"))
            }
        }
        jvm().compilations["main"].defaultSourceSet  {
            dependencies {
                implementation (kotlin("stdlib-jdk8"))
            }
        }
        jvm().compilations["test"].defaultSourceSet  {
            dependencies {
                implementation (kotlin("test"))
                implementation (kotlin("test-junit"))
            }
        }
        js().compilations["main"].defaultSourceSet {
            dependencies {
                implementation (kotlin("stdlib-js"))
            }

        }
        js().compilations["test"].defaultSourceSet  {
            dependencies {
                implementation (kotlin("test-js"))
            }
        }
    }
}

Когда я собираю проект, создается общее. js, содержимое которого выглядит следующим образом:

(function (_, Kotlin) {
    'use strict';
    var Kind_CLASS = Kotlin.Kind.CLASS;
    var ArrayList_init = Kotlin.kotlin.collections.ArrayList_init_287e2$;
    var emptyList = Kotlin.kotlin.collections.emptyList_287e2$;
    var NotImplementedError_init = Kotlin.kotlin.NotImplementedError;
    function commonSharedCode(platform) {
        return 'Common: Hi! ' + platform.greetingMethod + '(' + platform.name + ') AND NOW IN BEAUTIFUL ' + platform.beautifulPlatform();
    }
    function Platform(greetingMethod, name) {
        this.greetingMethod = greetingMethod;
        this.name = name;
    }
    Platform.prototype.beautifulPlatform = function () {
        return '***' + this.name + '***';
    };
    // ... //
    return _;
}(module.exports, require('kotlin')));

Теперь я создал простой javascript файл вне проекта и попытка использовать созданный код (как вы видите в руководствах - они создают приложение, которое использует проект mutliplatform в качестве зависимости). Это кажется невозможным, потому что нет функции et c. экспортируются по созданному коду. Я надеялся, что смогу сделать что-то вроде

const common = require('common');

function myTest () {
    console.log(common.Platform('Hello', 'World'));
}

У вас есть идея о том, как построить проект, чтобы иметь возможность делать эти вещи?

1 Ответ

0 голосов
/ 22 февраля 2020

Вы пробовали на самом деле запустить вышеуказанный код? Если да, что происходит? В этом вопросе есть некоторая двусмысленность, поэтому трудно точно определить, в чем именно заключается проблема.

В любом случае, позвольте мне поделиться тем, что мне удалось сделать, быстрым и грязным способом. Возможно, это доказательство концепции разблокирует вас.

  1. Я создал такой Kotlin файл в своем проекте Kotlin / JS:
class TestLibraryClass {
    @JsName("appendNumberToString")
    fun appendNumberToString(string: String, number: Int) =
        "Appending: $string - $number"

    fun functionWithoutJsNameAnnotation(someStr: String)
            = someStr
}

Я создал проект и получил JS файл результата в build/distributions/project-name.js.

Я открыл любую веб-страницу в веб-браузере с JS консоль и вставьте код файла project-name.js следующим образом - это эквивалент вашей попытки с require:

importedKotlinLib = ...pasted the code here...
[hit enter]
Я создал экземпляр TestLibraryClass:
testLibraryClassInstance = new importedKotlinLib.TestLibraryClass()
Мне удалось вызвать обе функции, первую с пользовательским именем, чтобы избежать искажения имени, а вторая присутствовала с искаженным именем:

JS console dump

Я узнал об искажении имен (и как обойти это) здесь . Обратите внимание, что имя класса TestLibraryClass не искажено. Я проверял, что имена функций верхнего уровня искажены.


Что касается общей картины - если она официально поддерживается для подготовки JS библиотек, написанных в Kotlin - у меня нет полной ясности здесь , Я буду рад обновить этот ответ, как только узнаю. Я также собираюсь включить Kotlin / JS в проекты моей компании.

...