Size: a a a

2021 September 09

AI

Arkadii Ivanov in Kotlin JS
Всем доброго времени суток! Можете меня просветить? Зачем некоторые Kotlin/JS/KMP библиотеки публикуют в NPM? Как это можно потом использовать? Например корутины опубликованы в NPM. Спрашиваю, потому что думаю некоторые из своих библиотек опубликовать. Но хочу сначала понять, надо ли и как этим пользуются.
источник

IG

Ilya Goncharov in Kotlin JS
Поскольку в legacy компиляторе на выходе была js и всякая мета информация, можно было это опубликовать в NPM, и дальше воспользоваться таким образом
Взять несколько Kotlin/JS библиотек, написать свою JS библиотеку, где прям руками сделать импорт (require) нужной Kotlin/JS библиотеки и использовать сигнатуры оттуда
Поскольку компиляция в js была помодульной, это можно было в целом более менее безопасно использовать, пока все версии (в том числе и транзитивные) совпадают в рамках проекта (но в рамках NPM совпадение версий никто не гарантирует)
Можно даже в текущий проект Kotlin/JS при желании добавить зависимость на Kotlin/JS либу из npm, но IDE это плохо переваривает, и это плохо переваривает инкрементальная компиляция

Короче это вызывало определенные проблемы, в рамках NPM если указана в проекте например версия корутин 1.2.0, а у зависимости например 1.0.0, то в рамках NPM придут обе версии, и проект будет импортить 1.2.0, а зависимость - 1.0.0, это вызывает несостыковку в рантайме, и всякие тайп чеки, тайп касты и прочие штуки, которые чувствительны именно к сигнатурам - отваливались
Причем отваливались так, что это было довольно сложно отлавливать

Поэтому мы не особо рекомендуем такой способ дистрибьюции библиотек, а рекомендуем через Gradle/Maven

Еще стоит сказать, что в новом компиляторе - тн IR, формат выхода компилятора поменялся - и теперь там бинарный klib, и дальше уже в финальной таске все klib-ы объединяются и выдают js, в которой содержится весь код приложения
Так вот библиотека будет в klib, и ее особо не выложишь в NPM, потому что это смысла особо не имеет
источник

AI

Arkadii Ivanov in Kotlin JS
Большое спасибо за ответ! Я попробовал опубликовать локально одну библиотеку в режиме IR используя плагин
dev.petuska.npm.publish
. Всё в общем то получилось, но появилось несколько вопросов.

Я правильно понимаю, что legacy в итоге уйдёт и останется только IR?

Например если библиотека состоит из нескольких Gradle модулей с зависимостями между ними (например A -> B), и я публикую оба модуля, то NPM модуль A содрежит внутри код из B, и не зависит от рядом опубликованного NPM модуля B.

Экспортируются далеко не всё. Я нашёл только какие-то интерфейсы и какие-то случайные классы. Почти все top-level функции отсутствуют. Видимо, надо везде явно просталвять @JsExport.

А вот в корутинах вроде всё экспортировано, но @JsExport я нигде не нашёл. Там Legacy режим используется для этого?

В целом звучит так, что надо оставить это дело. Но у меня весит issue уже давно, и там целая дискуссия уже развернулась, и надо как-то сформулировать почему "нет", если таки "нет") Есть ли какие-то официальные рекомендации, почему лучше так не делать? Может доки есть? Не смог сходу найти.
источник

IG

Ilya Goncharov in Kotlin JS
В этом плагине действительно реализована история с IR, я ее не осветил в изначальном ответе
Там как раз берется модель закрытого мира, и библиотека компилируется в js, при этом внутри содержит все свои зависимости (например стдлиб, он в скомпилированном виде вбандлен в js файл)
Из зависимостей у этой библиотеки теперь - только external-ы, но не другие Kotlin/JS библиотеки

Собственно с примером A -> B, все так
Компилировать в js предлагается именно тот модуль, который будет смотреть наружу, это обычно приложение, либо библиотека, которая будет светить публичный апи, но информации, что она зависит на другую Kotlin/JS либу, уже не будет

В IR действительно экспортируется только то, что покрыто @JsExport

В корутинах npm пакет это, если я правильно помню, legacy компиляция, ir компиляция в npm не публикуется

По поводу, legacy и ir и кто останется, вкратце - да, так и есть, но тут лучше cc @bashorov

В целом, кейс с Kotlin/Js -> js библиотеки надо будет еще продумывать, особенно в контексте ir, общее правило такое, что компиляцию из klib-ов в js нужно вызывать тогда, когда уже точно готовы полностью в js пространство перейти
источник

AI

Arkadii Ivanov in Kotlin JS
Большое спасибо за комментарии, стало на много понятнее!
источник

AN

Alexander Nozik in Kotlin JS
В IR есть волшебный ключик binaries.library(), который все равно позволяет опубликовать JS библиотеку
источник

AI

Arkadii Ivanov in Kotlin JS
Именно его я и использовал для пробы
источник

AN

Alexander Nozik in Kotlin JS
Ну это в основном нужно тем, кто потом из JS хочет это вызывать. Сейчас в котлин действительно есть проблема с code splitting, который очень бы не помешал и который можно реализовать только через npm. Но я думаю, что это рано или поздно исправят
источник

AI

Arkadii Ivanov in Kotlin JS
Понял, спасибо.
источник

ZB

Zalim Bashorov in Kotlin JS
да, все так, резюмирую:
* в NPM мы наши библиотеки публикуем только для старого тулчейна
* в конечном счете останется только IR
* для IR мы _не_ планируем ничего публиковать в NPM, т.е. мы _перестанем_ публиковать наши библиотеки в NPM
* для IR в NPM стоит публиковать только если вы хотите чтобы библиотеку использовали из JS кода или тулинга
источник

AI

Arkadii Ivanov in Kotlin JS
🙏
источник
2021 September 13

PE

Pavel Erokhin in Kotlin JS
Решил попробовать kotlin js, подключаю npm зависимость через gradle, и передаю true generateExternals параметру

Но сгенерированных классов на котлин для библиотеки не вижу
источник

PE

Pavel Erokhin in Kotlin JS
Для нее есть typescript маппинг на нпм
источник

PE

Pavel Erokhin in Kotlin JS
Вызываю принудительно таску generateExternals и ничего, правильно ли я все понял?
источник

с#

саша сок #KotlinGang... in Kotlin JS
тогда надо его подключать, а не таймскрипт
источник

PE

Pavel Erokhin in Kotlin JS
Это да, я так и делаю, почитал в доке, что оно само подтянет зависимость с типами ибо дукату это нужно
источник

PE

Pavel Erokhin in Kotlin JS
Но пытаюсь любое имя объекта библиотеки написать, ничего в автокомплите нет
источник

PE

Pavel Erokhin in Kotlin JS
еще эта директория пустая, предполагаю что туда и будут экстерналы генерироваться
источник

PE

Pavel Erokhin in Kotlin JS
Скорее всего где-то мой косяк, но где не понимаю, ради прикола подключил is-odd библиотеку,

   implementation(npm("is-odd", "1.0.1", generateExternals = true))

Не вижу в пространстве имен функцию isOdd
источник

AN

Alexander Nozik in Kotlin JS
там есть две разные настройки для экстерналсов. По-умолчанию в билде
источник