Spec-Zone.ru › Kotlin 1.4

Модули JavaScript

Вы можете скомпилировать свои проекты Kotlin в модули JavaScript для различных популярных систем модулей. В настоящее время мы поддерживаем следующие конфигурации для модулей JavaScript:

  • Единые определения модулей (UMD), которые совместимы как с AMD, так и с CommonJS. Модули UMD также могут выполняться без импорта или при отсутствии системы модулей. Это значение по умолчанию для целей browser и nodejs.
  • Асинхронные определения модулей (AMD), которые используются, в частности, библиотекой RequireJS.
  • CommonJS, широко используемый в Node.js/npm (require функция и module.exports объект)
  • Простой. Не компилировать для какой-либо системы модулей. Вы можете получить доступ к модулю по его имени в глобальной области видимости.

Целевое использование браузера

Если вы нацеливаетесь на браузер и хотите использовать систему модулей отличную от UMD, вы можете указать требуемый тип модуля в блоке конфигурации webpackTask. Например, для переключения на CommonJS используйте:

kotlin {
    js {
        browser {
            webpackTask {
                output.libraryTarget = "commonjs2"
            }
        }
        binaries.executable()
    }
}

Webpack предоставляет два разных «варианта» CommonJS, commonjs и commonjs2, которые влияют на способ доступности ваших объявлений. Хотя в большинстве случаев вам, вероятно, понадобится commonjs2, который добавляет синтаксис module.exports в сгенерированную библиотеку, вы также можете выбрать опцию «чистый» commonjs, которая точно реализует спецификацию CommonJS. Чтобы узнать больше о различиях между commonjs и commonjs2, ознакомьтесь со статьей здесь.

Создание библиотек JavaScript и файлов Node.js

Если вы создаёте библиотеку, которая будет использоваться из JavaScript или файла Node.js, и хотите использовать другую систему модулей, инструкции немного отличаются.

Выбор целевой системы модулей

Чтобы выбрать тип модуля, установите опцию компилятора moduleKind в скрипте сборки Gradle.

compileKotlinJs.kotlinOptions.moduleKind = "commonjs"

tasks.withType(KotlinJsCompile::class.java).named("compileKotlinJs") {
    kotlinOptions.moduleKind = "commonjs"
}

Доступные значения: umd (по умолчанию), commonjs, amd, plain.

Это отличается от настройки webpackTask.output.libraryTarget. Целевая библиотека изменяет вывод, генерируемый webpack (после того, как ваш код уже был скомпилирован). kotlinOptions.moduleKind изменяет вывод, генерируемый компилятором Kotlin.

В Kotlin Gradle DSL также есть сокращение для установки типа модуля CommonJS:

kotlin {
    js {
         useCommonJs()
         // . . .
    }
}

@JsModule аннотация

Чтобы сообщить Kotlin, что класс, пакет, функция или свойство external является модулем JavaScript, вы можете использовать аннотацию @JsModule. Представьте, что у вас есть следующий модуль CommonJS с именем «hello»:

module.exports.sayHello = function(name) { alert("Hello, " + name); }

Вы должны объявить его так в Kotlin:

@JsModule("hello")
external fun sayHello(name: String)

Применение @JsModule к пакетам

Некоторые библиотеки JavaScript экспортируют пакеты (пространства имён) вместо функций и классов. С точки зрения JavaScript, это объект, имеющий члены, которые являются классами, функциями и свойствами. Импорт этих пакетов в качестве объектов Kotlin часто выглядит неестественно. Компилятор может сопоставить импортированные пакеты JavaScript с пакетами Kotlin, используя следующую запись:

@file:JsModule("extModule")
package ext.jspackage.name

external fun foo()

external class C

где соответствующий модуль JavaScript объявлен так:

module.exports = {
    foo:  { /* some code here */ },
    C:  { /* some code here */ }
}

Файлы, помеченные аннотацией @file:JsModule, не могут объявлять члены, отличные от внешних. Приведенный ниже пример приводит к ошибке времени компиляции:

@file:JsModule("extModule")
package ext.jspackage.name

external fun foo()

fun bar() = "!" + foo() + "!" // error here

Импорт более глубоких иерархий пакетов

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

Например, давайте сделаем наш пример немного сложнее:

module.exports = {
    mylib: {
        pkg1: {
            foo: function() { /* some code here */ },
            bar: function() { /* some code here */ }
        },
        pkg2: {
            baz: function() { /* some code here */ }
        }
    }
}

Для импорта этого модуля в Kotlin вам нужно написать два файла Kotlin:

@file:JsModule("extModule")
@file:JsQualifier("mylib.pkg1")
package extlib.pkg1

external fun foo()

external fun bar()

и

@file:JsModule("extModule")
@file:JsQualifier("mylib.pkg2")
package extlib.pkg2

external fun baz()

@JsNonModule аннотация

Когда объявление помечено как @JsModule, вы не можете использовать его из кода Kotlin, когда не компилируете его в модуль JavaScript. Обычно разработчики распространяют свои библиотеки как модули JavaScript, так и загружаемые .js файлы, которые можно скопировать в статические ресурсы вашего проекта и включить с помощью тега <script>. Чтобы сообщить Kotlin, что разрешено использование объявления @JsModule из среды без модулей, добавьте аннотацию @JsNonModule. Например, рассмотрим следующий код JavaScript:

function topLevelSayHello(name) { alert("Hello, " + name); }
if (module && module.exports) {
    module.exports = topLevelSayHello;
}

Вы можете описать его в Kotlin следующим образом:

@JsModule("hello")
@JsNonModule
@JsName("topLevelSayHello")
external fun sayHello(name: String)

Система модулей, используемая стандартной библиотекой Kotlin

Kotlin распространяется со стандартной библиотекой Kotlin/JS в виде одного файла, который сам компилируется как модуль UMD, поэтому вы можете использовать его с любой системой модулей, описанной выше. Хотя для большинства случаев использования Kotlin/JS рекомендуется использовать зависимость Gradle от kotlin-stdlib-js, она также доступна в NPM как пакет kotlin.

© 2010–2020 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/reference/js-modules.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API