Компилятор Kotlin/JS IR
Компилятор Kotlin/JS IR — это основной фокус инноваций в Kotlin/JS и прокладывает путь вперёд для этой технологии.
Вместо непосредственного генерации JavaScript-кода из Kotlin-исходного кода, компилятор Kotlin/JS IR использует новый подход. Kotlin-исходный код преобразуется в промежуточное представление Kotlin (IR), которое затем компилируется в JavaScript. Для Kotlin/JS это позволяет применять агрессивную оптимизацию и улучшить слабые места предыдущего компилятора, такие как размер генерируемого кода (через удаление неиспользуемого кода) и взаимодействие с экосистемой JavaScript и TypeScript, и это лишь некоторые примеры.
Бэкенд IR-компилятора доступен начиная с Kotlin 1.4.0 через плагин Kotlin/JS Gradle. Чтобы включить его в свой проект, передайте тип компилятора в функцию js в вашем скрипте Gradle:
kotlin {
js(IR) { // or: LEGACY, BOTH
// ...
binaries.executable() // not applicable to BOTH, see details below
}
}
IRиспользует новый бэкенд компилятора IR для Kotlin/JS.LEGACYиспользует стандартный бэкенд компилятора.BOTHкомпилирует ваш проект как с новым бэкендом IR-компилятора, так и со стандартным бэкендом. Используйте этот режим для создания библиотек, совместимых с обоими бэкендами.
Тип компилятора также можно установить в файле gradle.properties, используя ключ kotlin.js.compiler=ir. Однако это поведение переопределяется любыми настройками в build.gradle(.kts).
Ленивая инициализация свойств верхнего уровня
Для лучшей производительности запуска приложения компилятор Kotlin/JS IR лениво инициализирует свойства верхнего уровня. Таким образом, приложение загружается без инициализации всех свойств верхнего уровня, используемых в его коде. Инициализируются только необходимые при запуске свойства; другие свойства получают свои значения позже, когда код, использующий их, фактически выполняется.
val a = run {
val result = // intensive computations
println(result)
result
} // value is computed upon the first usage
Если по какой-то причине вам нужно инициализировать свойство сразу (при запуске приложения), отметьте его аннотацией @EagerInitialization.
Инкрементальная компиляция для бинарных файлов разработки
Компилятор JS IR предоставляет режим инкрементальной компиляции для бинарных файлов разработки, ускоряющий процесс разработки. В этом режиме компилятор кэширует результаты задачи compileDevelopmentExecutableKotlinJs Gradle на уровне модуля. Он использует кэшированные результаты компиляции для неизменённых исходных файлов во время последующих компиляций, что делает их выполнение быстрее, особенно при небольших изменениях.
Чтобы включить инкрементальную компиляцию для бинарных файлов разработки, добавьте следующую строку в gradle.properties или local.properties:
kotlin.incremental.js.ir=true // false by default
Вывод файлов .js: по одному на модуль или один для всего проекта
В результате компиляции компилятор JS IR выводит отдельные .js файлы для каждого модуля проекта. Также можно скомпилировать весь проект в один .js файл, добавив следующую строку в gradle.properties:
kotlin.js.ir.output.granularity=whole-program // 'per-module' is the default
Игнорирование ошибок компиляции
Компилятор Kotlin/JS IR предоставляет новый режим компиляции, недоступный в стандартном бэкенде — игнорирование ошибок компиляции. В этом режиме вы можете протестировать своё приложение, даже если в его коде есть ошибки. Например, когда вы выполняете сложное рефакторинг или работаете над частью системы, которая совершенно не связана с ошибкой компиляции в другой части.
С этим новым режимом компилятор игнорирует весь некорректный код. Таким образом, вы можете запустить приложение и попробовать части, которые не используют некорректный код. Если вы попытаетесь запустить код, который был некорректным во время компиляции, вы получите исключение во время выполнения.
Выберите одну из двух стратегий для игнорирования ошибок компиляции в вашем коде:
SEMANTIC. Компилятор будет принимать код, который синтаксически корректен, но не имеет смысла семантически. Например, присваивание числа строковой переменной (несоответствие типов).SYNTAX. Компилятор примет любой код, даже если он содержит синтаксические ошибки. Независимо от того, что вы напишете, компилятор всё равно попытается сгенерировать исполняемый файл.
В качестве экспериментальной функции игнорирование ошибок компиляции требует предварительной активации. Чтобы включить этот режим, добавьте опцию компилятора -Xerror-tolerance-policy={SEMANTIC|SYNTAX}:
kotlin {
js(IR) {
compilations.all {
compileKotlinTask.kotlinOptions.freeCompilerArgs += listOf("-Xerror-tolerance-policy=SYNTAX")
}
}
}
Предварительный просмотр: генерация файлов объявлений TypeScript (d.ts)
Компилятор Kotlin/JS IR может генерировать определения TypeScript из вашего Kotlin-кода. Эти определения могут использоваться JavaScript-инструментами и IDE при работе с гибридными приложениями для предоставления автодополнения, поддержки статических анализаторов и упрощения включения Kotlin-кода в JavaScript- и TypeScript-проекты.
Декларации верхнего уровня, помеченные аннотацией @JsExport в проекте, генерирующем исполняемые файлы (binaries.executable()), будут иметь сгенерированный файл .d.ts, который содержит определения TypeScript для экспортированных Kotlin-деклараций. Эти декларации можно найти в build/js/packages/<package_name>/kotlin вместе с соответствующим не-упакованным JavaScript-кодом.
Текущие ограничения компилятора IR
Существенным изменением с новым бэкендом компилятора IR является отсутствие бинарной совместимости с стандартным бэкендом. Библиотека, созданная с новым компилятором IR, использует klib формат и не может использоваться со стандартным бэкендом. В то же время библиотека, созданная старым компилятором, представляет собой jar с js файлами, которые не могут использоваться с бэкендом IR.
Если вы хотите использовать бэкенд компилятора IR для своего проекта, вам необходимо обновить все Kotlin-зависимости до версий, поддерживающих этот новый бэкенд. Библиотеки, опубликованные JetBrains для Kotlin 1.4+ и предназначенные для Kotlin/JS, уже содержат все необходимые артефакты для использования с новым бэкендом компилятора IR.
Если вы являетесь автором библиотеки, желающим обеспечить совместимость как со стандартным, так и с новым бэкендом компилятора IR, дополнительно ознакомьтесь с разделом об авторизации библиотек для компилятора IR.
Бэкенд компилятора IR также имеет некоторые расхождения по сравнению со стандартным бэкендом. При тестировании нового бэкенда полезно учитывать эти возможные трудности.
Некоторые библиотеки, которые полагаются на определённые характеристики стандартного бэкенда, такие как
kotlin-wrappers, могут демонстрировать некоторые проблемы. Вы можете следить за развитием и прогрессом в YouTrack.Бэкенд IR по умолчанию не делает Kotlin-декларации доступными для JavaScript. Для того, чтобы Kotlin-декларации были видны в JavaScript, они должны быть помечены аннотацией
@JsExport.
Миграция существующих проектов к компилятору IR
Из-за существенных различий между двумя Kotlin/JS-компиляторами, для работы вашего Kotlin/JS-кода с компилятором IR могут потребоваться некоторые корректировки. Узнайте, как мигрировать существующие Kotlin/JS-проекты к компилятору IR в руководстве по миграции компилятора Kotlin/JS IR.
Библиотеки для компилятора IR с обратной совместимостью
Если вы — разработчик библиотеки, который хочет обеспечить совместимость с базовым бэкендом, а также новым бэкендом компилятора IR, доступна настройка выбора компилятора, позволяющая создавать артефакты для обоих бэкэндов. Это позволит сохранить совместимость с существующими пользователями, одновременно обеспечивая поддержку следующего поколения компилятора Kotlin. Этот так называемый both-режим можно включить, используя настройку kotlin.js.compiler=both в вашем файле gradle.properties, или же установить в качестве одного из параметров проекта внутри блока js в файле build.gradle(.kts).
kotlin {
js(BOTH) {
// ...
}
}
В режиме both, при построении библиотеки из исходного кода используются и бэкенд компилятора IR, и базовый компилятор (отсюда и название). Это означает, что будут сгенерированы оба типа файлов: klib файлы с Kotlin IR, а также jar файлы для базового компилятора. При публикации под одними и теми же координатами Maven, Gradle автоматически выберет правильный артефакт в зависимости от ситуации — js для старого компилятора и klib для нового. Это позволяет компилировать и публиковать вашу библиотеку для проектов, использующих любой из этих двух бэкэндов компилятора.
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/js-ir-compiler.html