Хорошая мысль, но слишком радикальна. Почему 3-4? Сколько фронтенд-разработчиков должно поддерживать, например, Booking, Reddit или Gitlab? Бизнес может иметь очень много потребностей, и большинство из них требуют работы на фронте тоже, и бизнес не должен упираться в кол-во 4 разработчиков, у которых в сумме всего 160 (после митингов и то меньше) рабочих часов в неделю. В принципе тезис "чем меньше разработчиков, тем эффективнее" применим не только к фронту, так везде. Поэтому тоже считаю, что каждый разработчик должен иметь свою зону ответственности в приложении, в котором он главный. Так и разрабы растут в скиллах, и работать легче, когда каждый несет какую-то ответственность.
Докину немного про разделение entrypoints/modules/shared. Entrypoints - интерфейс сайта, точки входа, разделы, страницы. Entrypoint имеет свой роутинг, собирает свои страницы с помощью других модулей и базовых компонентов. Modules - переиспользуемые блоки, закрывающие бизнес-задачи, например карточка товара, появляющаяся на многих страницах и меняющая стор корзины, или модалка чата с поддержкой, который обычно расположен в правом нижнем углу. Shared - переиспользуемые блоки без бизнес-логики, фундамент приложения, на базе которого строится все остальное. Мне видится это очень естественным, такая модель понятна и читаема, но она по-сути мало на что влияет, в конечном счете это просто папки. Если в вашем случае удобнее хранить и разделять все в одном месте, то пусть будет так.
Хочу остановиться на api и спросить: что вы делаете в случае надобности apiClient одного модуля в другом? Импортируете или копируете? Я вижу тут сложность в том, что интерфейс сервера не копирует интерфейс сайта, поэтому такое разделение выглядит натянутым. К тому же сейчас набирает популярность подход автогенерации апи клиентов и их типов, например tRPC.
В целом, я согласен с тем, что в больших командах FSD ведет к боли. Это замедляет онбординг сотрудников, потому что это не стандарт, и в итоге получается мешанина из разных разночтений. Складывается ощущение, что все должно быть проще, чем в FSD, но сложнее, чем у вас.
Касательно предложенной реализации, почему shared это отдельный модуль? Хочется видеть модуль независимым элементом, в который не протекают другие модули, чтобы не было циклической зависимости. Слой shared должен быть утилитарным, то есть элементы дизайн системы, вспомогательные функции, композоблы, директивы и все такое, что лишено груза решения бизнес задач. Плюс очко FSD, где слой shared стоит особняком.
Далее стоит очертить границы понимания модуля. Как мне видится, это не страница и не их группа. Модуль - это определенный блок, реализующий бизнес логику в рамках фронтенда, например виджет калькулятора ипотеки на сайте банка или виджет супер-юзера, появляющийся вообще на всех страницах и подключающийся на корневом уровне. Если вы согласны с таким утверждением, то стоит разделить роутинг и модули, чтобы получить более универсальный конструктор. Как вариант, вынести все страницы в отдельный слой entrypoints (называйте как хотите, но такой термин более понятен, нежели views или pages). По своей структуре entrypoint похож на модуль, но с большими полномочиями, в нем также могут быть свои сам-модули, привязанные к конкретной странице/группе страниц. В случае необходимости такие саб-модули легко поднимаются в modules и шарятся на другие страницы.
Также я бы предложил вынести api в слой shared, так как это банально дешевле в плане разработки. Бизнес требования к одному модулю могут меняться, появляется необходимость дергать разные апи-роуты, которые уже реализованы на бэкенде, но в вашем случае они привязаны к одному модулю. Также такой способ позволяет перейти на автогенерацию апи-клиентов и их типизаций.
И наконец про любимые сторы. В целом, страничный стор это скользкая дорожка, ведущая к перепотреблению памяти и, иногда, плохо читаемому коду. Такие сторы имеют привычку сильно разрастаться, в них теряется драгоценный контекст и нарушается принцип единичной ответственности. Что-то может выйти за рамки страничного стора, тогда нужно выносить логику в какой-то другой глобальный стор, чтобы не стереть данные случайно. Компоненты начинают смотреть в несколько сторов, в общем код превращается в спагетти. Например, вы разрабатывали приложение для управления задачами и использовали страничный стор. Со временем стор начал разрастаться из-за добавления новых функций, таких как фильтрация, сортировка и уведомления. Компоненты стали зависеть от нескольких сторов, в том числе глобальных, что усложнило код и сделало его трудным для поддержки. В таком случае решением может стать TanStack/Query, который управляет состоянием и кэшированием серверных данных, упрощая код, позволяя сосредоточиться на бизнес логике, а не на хранении данных, кэшированием и инвалидацией состояния стора.
Хотелось бы еще посмотреть на структуру тестов, как разделяются разные виды тестов, как шарятся в них моки/стабы и тому подобное.
Подведу итог, вам плюсик в карму за попытку систематизировать подход к построению стабильных и больших фронтенд приложений! Как мне кажется, мы, js-сообщество, еще только на середине этого тернистого пути к построению идеального фронтенд-конструктора, слишком много разного бэкграунда. Пока оптимальным решением я вижу такую структуру: Tests->App->Entrypoints->Modules->Shared, вышестоящий слой может пользоваться всеми нижестоящими. Своим комментарии я хочу лишь подчеркнуть возможные проблемы и найти их решения, вполне возможно, что и эти подходы имеют существенные минусы, которые я не заметил со своей колокольни.
Мне не нравится то, как tailwind в своем основном подходе портит разметку. Люди пишут об использовании с маленькими компонентами, но в жизни так получается не всегда. Когда элементы остаются без семантических классов по тому же БЭМу, мне становится грустно.
Лично для себя в своих pet проектах нашел более удобный путь. Я заношу дизайн систему в конфиг tailwind и даю ему сформировать необходимые мне утилитарные стили. Если я пишу стили какой нибудь страницы, то оставляю классы по бэму, а прикольные и нужные вещи от tailwind заношу через apply в postcss
Существует ли хоть один успешный продукт с широким ui функционалом, который поддерживается 3-4 фронтенд-разработчиками много лет?
Хорошая мысль, но слишком радикальна.
Почему 3-4? Сколько фронтенд-разработчиков должно поддерживать, например, Booking, Reddit или Gitlab? Бизнес может иметь очень много потребностей, и большинство из них требуют работы на фронте тоже, и бизнес не должен упираться в кол-во 4 разработчиков, у которых в сумме всего 160 (после митингов и то меньше) рабочих часов в неделю.
В принципе тезис "чем меньше разработчиков, тем эффективнее" применим не только к фронту, так везде. Поэтому тоже считаю, что каждый разработчик должен иметь свою зону ответственности в приложении, в котором он главный. Так и разрабы растут в скиллах, и работать легче, когда каждый несет какую-то ответственность.
Докину немного про разделение entrypoints/modules/shared.
Entrypoints - интерфейс сайта, точки входа, разделы, страницы. Entrypoint имеет свой роутинг, собирает свои страницы с помощью других модулей и базовых компонентов. Modules - переиспользуемые блоки, закрывающие бизнес-задачи, например карточка товара, появляющаяся на многих страницах и меняющая стор корзины, или модалка чата с поддержкой, который обычно расположен в правом нижнем углу.
Shared - переиспользуемые блоки без бизнес-логики, фундамент приложения, на базе которого строится все остальное.
Мне видится это очень естественным, такая модель понятна и читаема, но она по-сути мало на что влияет, в конечном счете это просто папки.
Если в вашем случае удобнее хранить и разделять все в одном месте, то пусть будет так.
Хочу остановиться на api и спросить: что вы делаете в случае надобности apiClient одного модуля в другом? Импортируете или копируете?
Я вижу тут сложность в том, что интерфейс сервера не копирует интерфейс сайта, поэтому такое разделение выглядит натянутым. К тому же сейчас набирает популярность подход автогенерации апи клиентов и их типов, например tRPC.
В целом, я согласен с тем, что в больших командах FSD ведет к боли. Это замедляет онбординг сотрудников, потому что это не стандарт, и в итоге получается мешанина из разных разночтений. Складывается ощущение, что все должно быть проще, чем в FSD, но сложнее, чем у вас.
Касательно предложенной реализации, почему shared это отдельный модуль? Хочется видеть модуль независимым элементом, в который не протекают другие модули, чтобы не было циклической зависимости. Слой shared должен быть утилитарным, то есть элементы дизайн системы, вспомогательные функции, композоблы, директивы и все такое, что лишено груза решения бизнес задач. Плюс очко FSD, где слой shared стоит особняком.
Далее стоит очертить границы понимания модуля. Как мне видится, это не страница и не их группа. Модуль - это определенный блок, реализующий бизнес логику в рамках фронтенда, например виджет калькулятора ипотеки на сайте банка или виджет супер-юзера, появляющийся вообще на всех страницах и подключающийся на корневом уровне. Если вы согласны с таким утверждением, то стоит разделить роутинг и модули, чтобы получить более универсальный конструктор. Как вариант, вынести все страницы в отдельный слой entrypoints (называйте как хотите, но такой термин более понятен, нежели views или pages). По своей структуре entrypoint похож на модуль, но с большими полномочиями, в нем также могут быть свои сам-модули, привязанные к конкретной странице/группе страниц. В случае необходимости такие саб-модули легко поднимаются в modules и шарятся на другие страницы.
Также я бы предложил вынести api в слой shared, так как это банально дешевле в плане разработки. Бизнес требования к одному модулю могут меняться, появляется необходимость дергать разные апи-роуты, которые уже реализованы на бэкенде, но в вашем случае они привязаны к одному модулю. Также такой способ позволяет перейти на автогенерацию апи-клиентов и их типизаций.
И наконец про любимые сторы. В целом, страничный стор это скользкая дорожка, ведущая к перепотреблению памяти и, иногда, плохо читаемому коду. Такие сторы имеют привычку сильно разрастаться, в них теряется драгоценный контекст и нарушается принцип единичной ответственности. Что-то может выйти за рамки страничного стора, тогда нужно выносить логику в какой-то другой глобальный стор, чтобы не стереть данные случайно. Компоненты начинают смотреть в несколько сторов, в общем код превращается в спагетти. Например, вы разрабатывали приложение для управления задачами и использовали страничный стор. Со временем стор начал разрастаться из-за добавления новых функций, таких как фильтрация, сортировка и уведомления. Компоненты стали зависеть от нескольких сторов, в том числе глобальных, что усложнило код и сделало его трудным для поддержки. В таком случае решением может стать TanStack/Query, который управляет состоянием и кэшированием серверных данных, упрощая код, позволяя сосредоточиться на бизнес логике, а не на хранении данных, кэшированием и инвалидацией состояния стора.
Хотелось бы еще посмотреть на структуру тестов, как разделяются разные виды тестов, как шарятся в них моки/стабы и тому подобное.
Подведу итог, вам плюсик в карму за попытку систематизировать подход к построению стабильных и больших фронтенд приложений! Как мне кажется, мы, js-сообщество, еще только на середине этого тернистого пути к построению идеального фронтенд-конструктора, слишком много разного бэкграунда. Пока оптимальным решением я вижу такую структуру: Tests->App->Entrypoints->Modules->Shared, вышестоящий слой может пользоваться всеми нижестоящими.
Своим комментарии я хочу лишь подчеркнуть возможные проблемы и найти их решения, вполне возможно, что и эти подходы имеют существенные минусы, которые я не заметил со своей колокольни.
Как говорится в фразе-меме - "а что случилось?"
Более того, эта кнопка не всегда отписывает в действительности. Сообщение, что отписался есть, а спам фактически продолжает приходить
Тот же ref и computed из vue composition api? Или есть разница?
Мне не нравится то, как tailwind в своем основном подходе портит разметку. Люди пишут об использовании с маленькими компонентами, но в жизни так получается не всегда. Когда элементы остаются без семантических классов по тому же БЭМу, мне становится грустно.
Лично для себя в своих pet проектах нашел более удобный путь. Я заношу дизайн систему в конфиг tailwind и даю ему сформировать необходимые мне утилитарные стили. Если я пишу стили какой нибудь страницы, то оставляю классы по бэму, а прикольные и нужные вещи от tailwind заношу через apply в postcss