Компилятор 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 Multiplatform 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=false // true 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 {
compileTaskProvider.configure {
compilerOptions.freeCompilerArgs.add("-Xerror-tolerance-policy=SYNTAX")
}
}
}
}
Минификация имён членов в режиме производства
Компилятор Kotlin/JS IR использует внутреннюю информацию о взаимосвязях ваших классов и функций Kotlin для применения более эффективной минификации, сокращая имена функций, свойств и классов. Это уменьшает размер итоговых скомпилированных приложений.
Этот тип минификации автоматически применяется при сборке вашего приложения Kotlin/JS в режиме производства и включен по умолчанию. Чтобы отключить минификацию имён членов, используйте параметр компилятора -Xir-minimized-member-names:
kotlin {
js(IR) {
compilations.all {
compileTaskProvider.configure {
compilerOptions.freeCompilerArgs.add("-Xir-minimized-member-names=false")
}
}
}
}
Предварительный просмотр: генерация файлов объявлений TypeScript (d.ts)
Компилятор Kotlin/JS IR способен генерировать определения TypeScript из вашего кода Kotlin. Эти определения могут быть использованы инструментами JavaScript и IDE при работе с гибридными приложениями для предоставления автодополнения, поддержки статических анализаторов и упрощения включения кода Kotlin в проекты JavaScript и TypeScript.
Если ваш проект генерирует исполняемые файлы (binaries.executable()), компилятор Kotlin/JS IR собирает все объявления верхнего уровня, отмеченные аннотацией @JsExport, и автоматически генерирует определения TypeScript в файле .d.ts.
Если вы хотите сгенерировать определения TypeScript, вам необходимо явно настроить это в файле Gradle. Добавьте generateTypeScriptDefinitions() в ваш файл build.gradle.kts в секции js. Например:
kotlin {
js {
binaries.executable()
browser {
}
generateTypeScriptDefinitions()
}
}
Определения можно найти в 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–2023 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