Используйте библиотеки Javascript в Котлине
в последний раз я использовал Kotlin был Dec 2015, когда я использовал его для решите пару задач проекта Эйлера.
на этот раз я хочу попробовать его совместимость с Javascript. Теперь мой вопрос: как импортировать / использовать существующие библиотеки Javascript в Kotlin?
Я видел, как некоторые люди используют native
ключевое слово, и я просто хочу кратко пояснить его.
3 ответов
нет native
ключевое слово больше, там @native
Примечание. В настоящее время, это рабочее решение, и вы можете использовать его с 1.0.X ветвь компилятора Kotlin. Тем не менее, мы собираемся сделать устаревшую эту аннотацию в пользу extern
аннотации, поэтому будьте готовы переписать свой код в конечном итоге для 1.1.х филиал.
когда ты ставишь @native
аннотация в классе или на функции верхнего уровня происходят две вещи:
- его тело не компилируется в Яваскрипт.
- компилятор ссылается на этот класс или функцию напрямую, без имени пакета и искажения.
я думаю, что это проще объяснить, приведя пример библиотеки 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