Современный фронтенд активно двигается в сторону усложнения, и эту сложность необходимо контролировать. Для начала хочется отметить, что проблема существует давно, и было опробовано и даже адаптировано несколько её решений, но конкретная идея должна была выкристаллизоваться и оформиться. О чем и пойдет речь далее. Компания, в которой я сейчас работаю, занимается разработкой фронтенда для различных заказчиков, и размеры проектов варьируются от совсем небольших до весьма солидных (например, Enterprise-системы). Мы столкнулись с тем, что решения, которые хорошо подходят для крупных проектов, плохо адаптируются для маленьких, и наоборот – то, что в маленьких проектах работает очень хорошо, не соответствует требованиям больших. В духе времени можно сказать, что тут нужен свой собственный бойлерплейт для проектов, позволяющий эффективно структурировать проекты разного масштаба так, чтобы держать под контролем их сложность и не давать ей произвольно расти, т.к. это может привести либо к срыву сроков проекта, либо к авралам. И, разумеется, не стоит забывать о стоимости поддержки и разработки.  Первоначальная реализация предполагала просто разделение проекта на независимые части, и основной упор делался на развитие инструмента, облегчающего работу с проектом. Проект начал представлять собой монорепозиторий под управлением lerna, который формировался на основании общих модулей, открыто публикующихся на github, а также специфических модулей, находящихся в самом проекте. Для общения между этими модулями использовалась шина событий, и в целом данная реализация стабильно работала. Однако у такой структуры был существенный недостаток: модули, которые не планировалось изменять в рамках проекта, всё равно нужно было подключать как часть монорепозитория, так как иначе мы получали разные версии одного и того же пакета в разных местах. Это, конечно, не проблема, но только если это не пакет с конфигами.  Второй важной проблемой стало описание способа написания плагинов, ведь при всей своей модульности они всё равно оказались сильно связанными, а общая концепция общения между модулями отсутствовала. Нужна была некая целостная спецификация для написания таких плагинов любым человеком, которая также позволила бы решить вопрос с разрешением зависимостей на уровне старта приложения. Далее я постараюсь описать наш вариант устранения этих проблем и начну с описания идеального возможного результата. Написанное ниже не претендует на истину в последней инстанции и является просто ещё одним мнением. Мы ищем свой путь и хотим сделать мир чуточку лучше и удобнее, хотя бы для себя. Проблема: Монолитность приложения. Сейчас уже предпринимаются шаги к разделению клиентского кода на отдельные части в рамках некоторого монолита, но по своей сути проект так и остаётся единым целым, и в нём сложно быстро заменить или удалить определённую часть, так как она не имеет четких границ. Решение: Разбить проект на физически разграниченные модули с чётко очерченными границами и ответственностью. Также необходима возможность конфигурирования поведения одного модуля из другого. Профит: Проект можно собирать как конструктор. То есть модуль сам обеспечивает свою работоспособность в рамках существующей инфраструктуры. Хорошим примером тут является настройка линтинга. Конфиг самого линтера можно собирать по частям из разных пакетов, но вот используемые плагины нужно подключать в самом проекте. Идеальный модуль, подключающий линтер, вместе с собой принесёт все необходимые плагины, и при использовании в проекте сам внесёт изменения для своего подключения. В случае eslint это команды в package.json и сам конфиг .eslintrc. Проблема: Усложнение внутренней структуры приложения приводит к сложностям в управлении зависимостями, конфигурацией проекта и запуском команд. Решение: Необходимо проработанное cli приложение, которое предоставляет простой и понятный интерфейс для управления, расширения и поддержки проекта. Команды должны быть лаконичны и интуитивны. Профит: Разработчик тратит намного меньше времени на рутинные операции — например, на создание типовых компонентов для интерфейса. Проблема: Большинство шаблонов заканчивают своё участие в проекте сразу после генерации проекта или клонирования шаблона. Иногда добавляется инструмент, который умеет генерировать атомарные части проекта. Решение: Каждый модуль должен содержать определённый набор шаблонов своих составных частей, которые можно быстро добавлять в проект. Профит: Мощность автоматизации рутинных задач — это ответственность самого проекта, а не шаблона. То есть чем сложнее проект, тем более сложные генераторы он будет требовать, но их добавление никак не затронет, например, другой, более локальный проект. Но при необходимости его можно будет легко подключить как отдельный модуль.  Кратко: набор генераторов в проекте определяется набором установленных модулей. Проблема: После старта проекта на определённом шаблоне обновление используемых пакетов, а так же структуры проекта остаётся за разработчиками проекта. Решение: Необходимо предоставлять возможность быстрого обновления зависимостей и проведения миграций кодовой базы в случае необходимости. Профит: Миграция ломающих версий может производиться только в одном месте. В конечных проектах произойдет просто обновление версий зависимостей проекта с дополнительной миграцией кодовой базы, если необходимо (стоит сказать, что, так как эта задача пока не решена, её определение и способ реализации расплывчаты). Получается, что проект Rispa можно разбить на несколько уровней: Главная особенность этого приложения заключается в том, что набор исполняемых команд зависит от самого проекта. То есть существует два типа команд: Более подробно про cli можно прочитать в описании. Наиболее очевидным решением для организации такой инфраструктуры видится использование в конечном проекте формата монорепозитория. Изначально использовался инструмент lerna.js, однако он лучше подходит для управления проектами разработки библиотек — таких, как, например, jest, babel и многие другие. Основной используемой фичей было разрешение зависимостей в рамках монорепозитория, однако сейчас, с появлением yarn workspaces, переключились на использования именно их, ведь это позволяет решить проблемы организации проекта как монорепозитория наиболее эффективно. Второй частью модульности приложения можно назвать rispa-core. Этот пакет предоставляет возможность организовывать взаимодействие плагинов друг с другом, а также декларирует спецификацию для написания плагинов. На текущий момент сформировался достаточно большой корпус плагинов, однако они в основном обслуживают потребности проектов на React, которые в перспективе могут быть пересмотрены для внедрения поддержки других фреймворков или систем сборки. Вот их краткий перечень: Экспериментальные плагины: Предварительно необходимо установить cli:  После успешной установки нужно запустить ris new, что позволит создать новый проект, ответить на вопросы, выбрать плагины и дождаться установки всех зависимостей: Теперь у нас есть свежесгенерированный и настроенный проект. Однако в нём нет ни одного роута. Нужно его добавить. Для этого воспользуемся генератором feature-plugin, который создаёт новый модуль и регистрирует его в @rispa/routes. После ответа на несколько вопросов плагин будет сгенерирован и подключён в проект, а также обновятся зависимости. Теперь у нас есть настроенный плагин, далее нужно доставить основной компонент для страницы. Вновь воспользуемся генератором ris g container, в процессе будет предложено выбрать, в какой плагин произвести генерацию. Кстати, чтобы увидеть все генераторы, можно просто указать ris g — будет выдан список генераторов, доступных в проекте. Теперь необходимо связать роут с созданным контейнером, это делается в файле /packages/home/src/register.js: Теперь можно запускать проект и после завершения сборки увидеть его в браузере: Сейчас Rispa позволяет решать задачи по упрощению старта проекта, а также оптимизации рабочего процесса. Дальнейшее развитие видится именно в расширении возможностей и поддержке новых фреймворков, а кроме того, в поиске других возможных применений для самой базы в виде rispa-cli + rispa-core.  Если вам понравилась идея данного проекта, то о чем хотелось бы еще прочитать, например, особенности организации плагинной инфраструктуры поверх монорепозитория, или туториал по разработке плагинов и экскурс в окружения или режимы, с которыми работает cli с проектом, или архитектура клиентского приложения, но пока она react специфичная, она остается достаточно стандартной. Так как проект развивается, и нет возможности протестировать все во различных окружениях, то не исключены проблемы, о которых можно рассказать через issues. Также приглашаем желающих присоединиться к данному проекту, чтобы развивать его на благо разработчиков. Frontend developer