Используйте библиотеки Javascript в Котлине

в последний раз я использовал Kotlin был Dec 2015, когда я использовал его для решите пару задач проекта Эйлера.

на этот раз я хочу попробовать его совместимость с Javascript. Теперь мой вопрос: как импортировать / использовать существующие библиотеки Javascript в Kotlin? Я видел, как некоторые люди используют native ключевое слово, и я просто хочу кратко пояснить его.

3 ответов


нет native ключевое слово больше, там @native Примечание. В настоящее время, это рабочее решение, и вы можете использовать его с 1.0.X ветвь компилятора Kotlin. Тем не менее, мы собираемся сделать устаревшую эту аннотацию в пользу extern аннотации, поэтому будьте готовы переписать свой код в конечном итоге для 1.1.х филиал.

когда ты ставишь @native аннотация в классе или на функции верхнего уровня происходят две вещи:

  1. его тело не компилируется в Яваскрипт.
  2. компилятор ссылается на этот класс или функцию напрямую, без имени пакета и искажения.

я думаю, что это проще объяснить, приведя пример библиотеки JavaScript:

function A(x) {
    this.x = x;
    this.y = 0;
}
A.prototype.foo = function(z) {
    return this.x + this.y + z;
}

function min(a, b) {
    return a < b ? a : b;
}

и соответствующий Котлин декларации

@native class A(val x: Int) {
    var y: Int = noImpl

    fun foo(z: Int): Int = noImpl
}

@native fun min(a: Int, b: Int): Int = noImpl

отметим, что noImpl специальный заполнитель, который требуется из-за неабстрактный функций органов и неабстрактные свойства требуют инициализаторы. Кстати, когда мы заменить @native С extern, мы избавимся от этой noImpl.

другим аспектом взаимодействия с библиотеками JS является включение библиотек через модульную систему. Извините, у нас нет никакого решения прямо сейчас (но скоро мы его выпустим). См.предложение. Для node можно использовать следующий обходной путь.с JS/на CommonJS:

@native interface ExternalModule {
    fun foo(x: Int)
}

@native fun require(name: String): dynamic = noImpl

fun main(args: Array<String>) {
   val module: ExternalModule = require("externalModule")
   module.foo(123)
}

где внешний модуль объявлен так

function foo(x) {
    return x + 1;
}
module.exports = { foo : foo };

Я добавил простой проект barebone в качестве примера того, как делать Kotlin2Js.

https://bitbucket.org/mantis78/gradle4kotlin2js/src

вот файл gradle, который является основным рецептом.

group 'org.boonhighendtech'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.1.2-5'
    repositories {
        maven { url 'http://dl.bintray.com/kotlin/kotlin-dev/' }
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'kotlin2js'

repositories {
    maven { url 'http://dl.bintray.com/kotlin/kotlin-dev/' }
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}

build {
    outputs.dir("web/")
}

build.doLast {
    copy {
        from 'src/main/webapp'
        into 'web/'
        include '**/*.html'
        include '**/*.js'
        include '**/*.jpg'
        include '**/*.png'
    }

    configurations.compile.each { File file ->
        copy {
            includeEmptyDirs = false

            from zipTree(file.absolutePath)
            into "${projectDir}/web"
            include { fileTreeElement ->
                def path = fileTreeElement.path
                path.endsWith(".js") && (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/"))
            }
        }
    }
}

clean.doLast {
    file(new File(projectDir, "/web")).deleteDir()
}

compileKotlin2Js {
    kotlinOptions.outputFile = "${projectDir}/web/output.js"
    kotlinOptions.moduleKind = "amd"
    kotlinOptions.sourceMap = true
}

во-первых, вы можете назначить динамическую переменную, а затем по существу кодировать ее, как вы кодируете JavaScript, динамически.

например

val jQuery: dynamic = passedInJQueryRef
jQuery.whateverFunc()

но если ваше намерение состоит в том, чтобы ввести его, то вам нужно ввести типы в внешняя библиотека. Один из способов-использовать относительно обширные библиотеки typedefs поhttps://github.com/DefinitelyTyped/DefinitelyTyped

найдите ts.d там, затем запустите ts2kt (https://github.com/Kotlin/ts2kt), чтобы получить ваши файлы Kotlin. Это обычно приводит вас туда. Иногда некоторые преобразования выполняются не очень хорошо. Вам придется вручную исправить преобразование. Е. Г. snapsvg snapsvg по.вызов attr () принимает " {}", но он был преобразован в некоторые странный интерфейс.

Он был

fun attr(params: `ts`): Snap.Element

и Я заменил его с

 fun attr(params: Json): Snap.Element

и это работает как шарм.


Котлин 1.1 вводит externalмодификатор, который можно использовать для объявления функций и классов, написанных непосредственно в JS, см. http://kotlinlang.org/docs/reference/js-interop.html