Концепция дополнений играет важную роль в разработке приложений на фреймворке Jmix. В этой статье мы рассмотрим, что такое дополнение и как Jmix Studio помогает разрабатывать дополнения и модульные приложения.
Дополнение в Jmix — это просто специальное название библиотеки, то есть набора предварительно скомпилированного кода и других ресурсов, которые могут быть использованы в приложениях. Мы используем специальный термин "дополнение", чтобы подчеркнуть, что эта библиотека, в отличие от библиотеки Java в общем, следует определенным правилам и использует некоторые возможности Jmix для автоматической интеграции предоставляемой функциональности в хост-приложение.
Самое главное, что дополнение является full-stack: оно может содержать сущности, схему базы данных и экраны пользовательского интерфейса, которые легко интегрируются в модель данных и пользовательский интерфейс приложения. Таким образом, просто добавив дополнение в качестве зависимости в build.gradle
, вы можете получить совершенно новую подсистему в вашем проекте с данными, хранящимися в вашей базе данных, и пользовательским интерфейсом, интегрированным в главное меню.
Дополнение не обязательно должно быть сложным full-stack проектом. Многие дополнения просто предоставляют некоторый компонент пользовательского интерфейса или альтернативную реализацию какого-либо интерфейса фреймворка, например FileStorage
. В этом случае дополнение может только использовать общую инфраструктуру для публикации на Marketplace и для простой установки в проекты.
Разработка дополнений
Jmix Studio предоставляет шаблон проекта "Single Module Add-on", который позволяет быстро начать разработку дополнения. Проект будет содержать один функциональный модуль и Spring Boot Starter.
При работе над дополнением, предназначенным для многократного использования, обычно также приходится создавать приложение, которое демонстрирует варианты использования дополнения и может содержать дополнительные автоматические тесты, которые трудно создать в самом проекте дополнения. Studio теперь предлагает функцию для оптимизации разработки таких модульных систем. Но, прежде чем рассмотреть ее, давайте разберем процесс разработки, принятый ранее.
В общем случае, работа над дополнением и приложением, которое его использует, требует постоянного переключения между двумя проектами. Необходимо изменить код дополнения, собрать его и опубликовать в локальном Maven-репозитории. Затем вы переключаетесь на проект приложения, и IDE загружает и переиндексирует новые артефакты дополнения. Теперь вы можете корректировать код приложения, тестировать и запускать его, чтобы увидеть изменения в действии.
Ситуация ухудшается, когда вы работаете над приложением, состоящим из нескольких дополнений. Скорее всего, некоторые из ваших дополнений зависят друг от друга. Поэтому вам приходится переключаться между проектами и публиковать несколько дополнений прежде, чем вы сможете запустить свое приложение и убедиться, что получили то, что хотели. Если вы потерпели неудачу, вам придется повторить процесс снова.
Цикл обратной связи при разработке дополнений был далек от идеала: нужно было сделать слишком много шагов, чтобы увидеть результат своих изменений. Очевидным решением видится объединение дополнения и запускаемого приложения как модулей одного проекта. С одной стороны, тогда IDE может обеспечить прозрачный рефакторинг, и разработчик мгновенно видит результаты изменений в любом модуле. С другой стороны, дополнения и приложения становятся тесно связанными на протяжении всего жизненного цикла, и идея дополнения как отдельной библиотеки теряет смысл.
Очевидно, было бы здорово, если бы можно было работать с дополнениями и приложениями как в отдельных проектах, так и в одном проекте, когда это необходимо. Это позволило бы сохранить кодовую базу чистой и управляемой, не жертвуя при этом коротким циклом обратной связи, когда это важно, особенно на ранних стадиях разработки, когда сквозные изменения происходят очень часто.
Именно поэтому мы улучшили Jmix Studio для поддержки этого сценария с помощью функции "композитной сборки" Gradle.
Составные проекты
В Gradle есть несколько функций, которые помогают структурировать проекты, и одна из них - композитная сборка. Она сводится к использованию инструкции includeBuild
в файле settings.gradle
составного проекта:
includeBuild ‘../addon1’
includeBuild ‘../addon2’
includeBuild ‘../myapp’
В композитной сборке Gradle заменяет зависимости от артефактов прямыми зависимостями между подпроектами, поэтому изменения в одном дополнении немедленно отразятся на зависимых дополнениях и приложении. IntelliJ IDEA прекрасно импортирует такой проект, учитывая зависимости, распознанные Gradle. В результате вы получаете композитный проект, который обеспечивает прозрачный рефакторинг и избавляет от необходимости проходить цикл "опубликовать локально".
Jmix Studio поддерживает композитные проекты, начиная с версии 1.2. Она также предлагает ряд возможностей, которые еще больше помогают разработчикам.
Прежде всего, вы можете легко создать пустой составной проект на основе шаблона. Затем вы можете добавить подпроекты, создавая новые дополнения или приложения, загружая существующий проект из VCS или просто добавляя существующую папку с проектом.
Studio показывает составной проект и все подпроекты как узлы верхнего уровня в окне Jmix:
Вы можете редактировать общие свойства всех подпроектов: просто выберите All subprojects, когда Studio спросит вас, какой проект вы хотите редактировать:
Общие свойства включают настройки репозитория артефактов и версию фреймворка Jmix. Таким образом, вы можете сразу обновить все подпроекты до более новой версии Jmix.
Возможно, самой полезной функцией для больших композитных проектов является возможность настройки зависимостей между подпроектами в простом диалоге:
Здесь orders (заказы) - это дополнение, которое зависит от дополнений staff (персонал) и customers (клиенты). В соответствии с изменениями, которые вы делаете в этом диалоге, Studio добавляет артефактные зависимости в файлы build.gradle
подпроектов, а также настраивает аннотации @JmixModule
дополнений. Studio также предотвращает введение циклических зависимостей. На скриншоте ниже вы можете видеть, что диалог не позволяет вам сделать дополнение customers зависимым от orders, потому что orders уже зависит от customers:
Когда вы создаете новые элементы проекта, такие как сущности и экраны, Studio учитывает какой проект в данный момент выбран в окне Jmix:
И последнее, но не менее важное: Studio корректно выполняет hot deploy в дополнениях в запущенном приложении. Таким образом, если вы запустите приложение, а затем измените экран пользовательского интерфейса, предоставляемый дополнением, вы увидите изменения в приложении без его перезапуска, как если бы экран был в исходном коде приложения.
Подводя итог, можно сказать, что функция композитной сборки Gradle вместе с поддержкой IntelliJ IDEA и Jmix Studio позволяет работать с большими семействами дополнений и приложений как с одним многомодульным приложением. В то же время разработчик может в любой момент отсоединить дополнение и продолжить работу над ним как над отдельным проектом.