А как SOLID решит проблему циклических зависимостей? Учитывая что D в SOLID это Dependency Injection, а этот подход упрощает создание циклических зависимостей.
Все решения циклических зависимотей в DI контейнерах сводятся либо к внедрению функций вместо значения, либо к динамическим импортам (которые тоже функции). В лучшем случае контейнер может выдать сообщение об ошибке. Но это скорее костыль, нежели решение проблемы.
Я не поленился и решил поперфтестить данные примеры на JS
Понимаю что статья не об этом, но это крайне спорное утверждение (особенно без цифр и кода). К тому же оригинал написан на другом языке, и не ясно как исходный пример был адаптирован
а ORM господам есть разница на каком фреймворке формошлепить SQL запросы размером с lock файл?
сам не очень люблю nest из-за его мнимой простоты: он за милую душу завернет 3 строки ORM запроса в аккуратнейший 10 секундный запрос в базу (тут к nest'у вопросов нет, проблема по ту сторону монитора), после чего знатно навернет пару секунд class-validator сверху, выкинет ошибку при попытке внедрить зависимость, и упадет в рантайме при попытке сконвертировать тип из декораторов, добавив еще пару секунд к запросу (если заработает)
И это прекрасно: одна общая библиотека реактивных примитивов и адаптированных под реактивность браузерных функций. Эдакая std для vue которой нет в самом vue
Это зависимость
Как и сам vue, но она очень сильно облегчает работу, поэтому это просто trade-off
Утилиты в ней не делают то, что надо именно тебе
Если одна функция не подошла по какой-то причине, это не повод отказываться от всей библиотеки. Можно всегда адаптировать исходный код под свой случай
избыточная и чрезмерная логика и код
Composabl'ы из библиотеки поддерживают 2 и 3 версии vue, по возможности дружат с Nuxt'ом и vue-router'ом, а также поддерживают SSR и уже пофиксили баги о которых невозможно знать заранее при разработке "в лоб"
диктует реализацию элементов архитектуры всего проекта
Вы привели пример исходного кода своего проекта интернет магазина которому мешает архитектура vueuse, но я вижу проблемы с архитектурой:
Отсутствует поддержка SSR, и ее нельзя будет подключить без переписывания части утилит (довольно серьезная проблема для интернет магазина, где важна отдача данных внутри html для поисковых ботов)
Отсутствует code splitting по роутам, из-за чего у приложения один большой бандл
Не вижу в проекте каких-то требований к супер сложным вычислениям, где считался бы каждый computed (это не повод плодить лишние, я согласен, но это также не повод делать велосипеды с возможными багами)
Из беглого осмотра проекта, как минимум две вышеперечисленные проблемы можно решить, либо минимизаровать, с помощью vueuse. Поэтому считаю совет "не берите vueuse, пишите сами" как минимум вредным
При этом ChatGPT вполне может помогать искать ошибки в коде и быстро сгенерировать
...новые ошибки в коде. В примере 3 typescript будет жаловаться на попытку индексации типа {} с помощью string, так что спим спокойно, скайнет еще не скоро заберет работу
Выглядит как немного неуместная реклама. Статья описывает использование module federation для объединения сборок разных библиотек в одно приложение, а в Вашем примере используются обычные компоненты одного фреймворка в одном приложении.
Возможно, но, во-первых, осмысленные имена классов дробят полотно разметки на блоки и элементы
Придумывать и переименовывать осмысленные блоки очень трудозатратно во время активной разработки. Иногда нужно добавить один или два лишних wrapper'а, которые полностью меняют структуру и добавляют классы уровня .element-wrapper-wrapper (я утрирую, но идея примерно та же)
Но ведь CSS tailwind'а уже распух описанием все возможных комбинаций
Все неиспользующиеся классы tailwind'а вырезаются во время сборки, поэтому размер итогового css не такой уж и большой (уж точно меньше кода с sass, где на каждый класс вешают миксин)
tailwind подход выглядит как шаг назад, (привет, аттрибут style!)
так может показаться, но у utility-first подхода есть плюсы перед обычным запихиванием стилей в style:
utility-first предоставляет классы, специфичность которых меньше чем правил внутри style (переопределение обычными классами, без !important)
build-step для минификации и анализа всего что используется в приложении
кастомизация (можно переопределять различные отступы, цвета, тени и т.д.)
проще переиспользование кода (не нужно делать сборку или css-in-js, все стили помещаются в render функцию или в template)
Безусловно tailwind это не таблетка от всех болезней, но это хороший инструмент и отличный представитель utility-first подхода. Все еще есть вопросы с переопределением классов одной группы на элементе, многословность при создании интерактивных элементов, сложности с переиспользванием кода в дизайн системе. Но примерно тот же набор болячек есть и у других фреймворков, но к этому добавляется еще больший размер и меньшая скорость разработки
И разумно использовать или WP или полный кастом, потому что возможностей больше а костылей меньше. Есть только одно исключение — у вас уже есть команда фронтедщиков, а бэкенд делается по остаточному принципу. Это фронтенд головного мозга или попытки использовать то что есть в наличии, невзирая на кривизну.
Не обязательно так радикально идти в какую-то сторону. Например можно взять несколько решений и объединить в одно, напрмер cms + сторонний сервис для медиа контента, или сторонний полнотекстовый поиск. А бэкэнд в любом случае делается под фронт. Например если для открытия домашней страницы нужно сделать 20 JOIN операций, то это точно ни к чему хорошему не приведет. Но в JAM подходе мы можем разбить один большой монолит бэкэнда на отдельные сервисы
Складывается впечатление, что вы создаете проблему и тут же мужественно ее решаете. В чем преимущество гидрации перед традиционным подходом?
А эта проблема была изначально: представим что нам нужно передать состояние с бэка на фронт. Это будет либо через глобальные JS переменные записанные в script тэги, либо через data-* атрибуты прямо в DOM элементы. Тогда придется работать с одной и той же логикой в темплейте, записывая туда данные с бэка, а затем на фронте. Это очень плохо масштабируется и поддерживается, а при использовании UI фреймворков становится совсем тяжело из-за того что они берут на себя рендер страницы. В случае server-side rendering этот процесс происходит автоматически, и DOM дерево построенное на сервере совпадает с DOM деревом которое построит клиент, а значит с ним можно работать без дополнительных обработок глобальных переменных и data-* атрибутов, а самое главное что это происходит автоматически.
Вы очень сильно лукавите, особенно если речь о сайтах постарше, где половина фронтенда jQuery и несколько страниц на Vue/React.
Тут уже вопрос поддержки legacy кода: фиксировать версии плагинов jQuery или скачивать их на свой хостинг. Новые же страницы на Vue/React не будут страдать от таких проблем с поддержкой.
А можно и не запустить, особенно если часть пакетов была на гитхабе. Или просто вам попадется неудачная комбинация nodejs + npm на текущем сервере
Это опять вопрос к работе с legacy на jQuery, сейчас все компоненты для react/Vue/angular ставятся через npm, где можно зафиксировать версии и где есть уверенность в том что версия не будет удалена. Версия npm не влияет на сборку (кроме версий <5, из-за package-lock), но его можно обновить через него самого. У того же gatsby версии node поддерживаются все корторые обозначены как lts, и бинарные зависимости скорее всего для них уже будут собраны.
Ну и последнее: любую новую технологию пытаются продать, и многие будут ее представлять как серебрянную пулю, что не есть правильно. На своем опыте «JAM» (название появилось уже после того как он был применен, до этого я не знал что пишу на JAM) стэк хорошо себя показал как внутренняя система для сотрудников (nuxt + firebase для realtime), как быстрый способ создать документацию (такую как сейчас делают многие opensource проекты, прямо из readme файла с редактируемыми примерами, поиском и локализацией) и как способ создавать дополнительные страницы в уже существующем проекте, без больших migration скриптов и создания сущностей в cms на каждый чих
Ощущение конструктивности критики начинает исчезать уже во втором абзаце, но я не мог пройти мимо
Наверное вы неправильно поняли весь смысл тех же Next, nuxt, gatsby и прочих. По своей сути они представляют собой фреймворк для создания всего frontend'а для проекта с уже решенными проблемами навигации, server-side rendering'а, сборки и прочего. При этом использование любого бэкэнда, хоть того же php, это вполне нормальная практика, которая объединяет компонентный подход клиента и server-side render для быстрой загрузки и SEO с аккуратным API со стороны бэкэнда, где нет необходимости мучаться с шаблонами и можно отдавать обычный json из любой cms.
Возможность создания статических страниц из набора даннных это просто одна из побочных функций SSR. «Эй, мы же и так рендерим страницу полностью на сервере, почему бы нам не срендерить сразу несколько страниц?». Кардинальное отличие этих инструментов от ого же wp2satic это возможность гидрации динамического контента (объединение результата server-side рендера с клиентскими данными), что избавляет от пустых страниц с появляющимся контеном и от дополнительных запросов на сервер.
Само понятие JAM не привязывается ни к Netlify, ни к Contentfull. Это просто идея использования микросервисов напрямую из клиентского приложения, убирая лиший сервер в инфраструктуре. Тот же Firebase это хорошо демонстрирует, а вместе с realtime функциональностью firestore это становится просто сказкой для чего-то вроде комментариев/сообщений или совместной работы над документом. Разумеется в этом подходе можно как использовть сторонние SaaS решения, так и свои собственные, со всеми вытекающими последствиями vendor lock-in'а / необходимости поддержки, просто нужно выбирать подходящие решения под задачу, а простой запрос в managed базу не важно из чего писать: хоть php, хоть js.
Про поддержку можно много чего написать, но я вкратце поясню: уже давно прошли времена jquery, когда нужно было рукми подбирать специфические версии UI компонентов друг под друга. С приходом общего и стабильного API этого стало в разы меньше, но как и в любой другой экосистеме можно найти примеры обратного. Есть способы зафиксировать версии зависимостей (это уже стало поведением по умолчанию, если мы говорим про npm) и запустить проект хоть через полгода, хоть через два. Тут уже все на совести разработчика, а сделать плохо ни один язык не может запретить, хоть и очень сильно стараются.
Как я понял, вам очень комфортно работать с Wordpress CMS и вы противопоставляете его тем же gatsby и next. Но на самом деле они могут работать в связке: Wordpress CMS может работать как headless cms для клиента на gatsby и обеспечивать доступ в базу, интеграции со сторонними сервисами, и так далее, но со всеми преимуществами nuxt, такими как server side rendering, быстрая загрузка контента, отсутствие мигающего контента, счет в 100 баллов от lighthouse и так далее.
Завязка на .toString() для выполнения DI не очень хорошая мысль. Подобный подход провернули еще в первом ангуляре при иджекте сервисов по именам параметров, но это очень хорошо выстрелило в ногу с минификацией, т.к. замена имен параметров невозможна при таком подходе, а если принимать во внимание отдельный транспилятор как babel или ts, то ситуация становится еще хуже.
Также возникают вопросы с правильной типизацией всего, т.к. перебивание типа у this вызывает слишком большие вопросы как в ts, так и во flow.
Хороший набор хитрых хаков, но не самый лучший выбор для чего-то чем будут пользоваться люди
Каждый пример имеет какое-то ограничение: не работает на старых браузерах, отсутствие интерактивности, хардкод размеров элементов, хардкод id самих элементов в css, ограничения с навигацией и с доступностью, сильно урезанный функционал.
Вот и получается что необходимо выбрать 2 пункта из 3 возможных:
— отсутствие JavaScript
— поддержка
— функционал
Есть хуки в контексте хуков жизненного цикла самого Nuxt приложения: https://nuxt.com/docs/guide/going-further/hooks
А все остальное и правда composables (кроме $fetch, это функция)
А как SOLID решит проблему циклических зависимостей? Учитывая что D в SOLID это Dependency Injection, а этот подход упрощает создание циклических зависимостей.
Все решения циклических зависимотей в DI контейнерах сводятся либо к внедрению функций вместо значения, либо к динамическим импортам (которые тоже функции). В лучшем случае контейнер может выдать сообщение об ошибке. Но это скорее костыль, нежели решение проблемы.
Понимаю что статья не об этом, но это крайне спорное утверждение (особенно без цифр и кода). К тому же оригинал написан на другом языке, и не ясно как исходный пример был адаптирован
это если очень сильно повезет, и все зависимотси будут поддерживать такой фокус
чаще всего попытка переключения заканчивается откатом к express из расчета: "ну раньше хоть как работало"
а ORM господам есть разница на каком фреймворке формошлепить SQL запросы размером с lock файл?
сам не очень люблю nest из-за его мнимой простоты: он за милую душу завернет 3 строки ORM запроса в аккуратнейший 10 секундный запрос в базу (тут к nest'у вопросов нет, проблема по ту сторону монитора), после чего знатно навернет пару секунд class-validator сверху, выкинет ошибку при попытке внедрить зависимость, и упадет в рантайме при попытке сконвертировать тип из декораторов, добавив еще пару секунд к запросу (если заработает)
И это прекрасно: одна общая библиотека реактивных примитивов и адаптированных под реактивность браузерных функций. Эдакая std для vue которой нет в самом vue
Как и сам vue, но она очень сильно облегчает работу, поэтому это просто trade-off
Если одна функция не подошла по какой-то причине, это не повод отказываться от всей библиотеки. Можно всегда адаптировать исходный код под свой случай
Composabl'ы из библиотеки поддерживают 2 и 3 версии vue, по возможности дружат с Nuxt'ом и vue-router'ом, а также поддерживают SSR и уже пофиксили баги о которых невозможно знать заранее при разработке "в лоб"
Вы привели пример исходного кода своего проекта интернет магазина которому мешает архитектура vueuse, но я вижу проблемы с архитектурой:
Отсутствует поддержка SSR, и ее нельзя будет подключить без переписывания части утилит (довольно серьезная проблема для интернет магазина, где важна отдача данных внутри html для поисковых ботов)
Отсутствует code splitting по роутам, из-за чего у приложения один большой бандл
Не вижу в проекте каких-то требований к супер сложным вычислениям, где считался бы каждый computed (это не повод плодить лишние, я согласен, но это также не повод делать велосипеды с возможными багами)
Из беглого осмотра проекта, как минимум две вышеперечисленные проблемы можно решить, либо минимизаровать, с помощью vueuse. Поэтому считаю совет "не берите vueuse, пишите сами" как минимум вредным
...новые ошибки в коде. В примере 3 typescript будет жаловаться на попытку индексации типа
{}
с помощьюstring
, так что спим спокойно, скайнет еще не скоро заберет работуВыглядит как немного неуместная реклама. Статья описывает использование module federation для объединения сборок разных библиотек в одно приложение, а в Вашем примере используются обычные компоненты одного фреймворка в одном приложении.
делаешь
увеличиваешь продажи
????
profit
Не думаю что сравнивать набор css классов и библиотеку для фреймворка корректно, но:
как и в tailwind, но все еще остается проблема с порядком селекторов с одинаковой специфичностью
как и в обычном css
не думаю что можно применять понятие "семантика" к utility-first библиотекам, но уникальность также присутствует
Придумывать и переименовывать осмысленные блоки очень трудозатратно во время активной разработки. Иногда нужно добавить один или два лишних wrapper'а, которые полностью меняют структуру и добавляют классы уровня
.element-wrapper-wrapper
(я утрирую, но идея примерно та же)Все неиспользующиеся классы tailwind'а вырезаются во время сборки, поэтому размер итогового css не такой уж и большой (уж точно меньше кода с sass, где на каждый класс вешают миксин)
так может показаться, но у utility-first подхода есть плюсы перед обычным запихиванием стилей в style:
utility-first предоставляет классы, специфичность которых меньше чем правил внутри style (переопределение обычными классами, без !important)
build-step для минификации и анализа всего что используется в приложении
кастомизация (можно переопределять различные отступы, цвета, тени и т.д.)
проще переиспользование кода (не нужно делать сборку или css-in-js, все стили помещаются в render функцию или в template)
Безусловно tailwind это не таблетка от всех болезней, но это хороший инструмент и отличный представитель utility-first подхода. Все еще есть вопросы с переопределением классов одной группы на элементе, многословность при создании интерактивных элементов, сложности с переиспользванием кода в дизайн системе. Но примерно тот же набор болячек есть и у других фреймворков, но к этому добавляется еще больший размер и меньшая скорость разработки
Не обязательно так радикально идти в какую-то сторону. Например можно взять несколько решений и объединить в одно, напрмер cms + сторонний сервис для медиа контента, или сторонний полнотекстовый поиск. А бэкэнд в любом случае делается под фронт. Например если для открытия домашней страницы нужно сделать 20 JOIN операций, то это точно ни к чему хорошему не приведет. Но в JAM подходе мы можем разбить один большой монолит бэкэнда на отдельные сервисы
А эта проблема была изначально: представим что нам нужно передать состояние с бэка на фронт. Это будет либо через глобальные JS переменные записанные в script тэги, либо через data-* атрибуты прямо в DOM элементы. Тогда придется работать с одной и той же логикой в темплейте, записывая туда данные с бэка, а затем на фронте. Это очень плохо масштабируется и поддерживается, а при использовании UI фреймворков становится совсем тяжело из-за того что они берут на себя рендер страницы. В случае server-side rendering этот процесс происходит автоматически, и DOM дерево построенное на сервере совпадает с DOM деревом которое построит клиент, а значит с ним можно работать без дополнительных обработок глобальных переменных и data-* атрибутов, а самое главное что это происходит автоматически.
Тут уже вопрос поддержки legacy кода: фиксировать версии плагинов jQuery или скачивать их на свой хостинг. Новые же страницы на Vue/React не будут страдать от таких проблем с поддержкой.
Это опять вопрос к работе с legacy на jQuery, сейчас все компоненты для react/Vue/angular ставятся через npm, где можно зафиксировать версии и где есть уверенность в том что версия не будет удалена. Версия npm не влияет на сборку (кроме версий <5, из-за package-lock), но его можно обновить через него самого. У того же gatsby версии node поддерживаются все корторые обозначены как lts, и бинарные зависимости скорее всего для них уже будут собраны.
Ну и последнее: любую новую технологию пытаются продать, и многие будут ее представлять как серебрянную пулю, что не есть правильно. На своем опыте «JAM» (название появилось уже после того как он был применен, до этого я не знал что пишу на JAM) стэк хорошо себя показал как внутренняя система для сотрудников (nuxt + firebase для realtime), как быстрый способ создать документацию (такую как сейчас делают многие opensource проекты, прямо из readme файла с редактируемыми примерами, поиском и локализацией) и как способ создавать дополнительные страницы в уже существующем проекте, без больших migration скриптов и создания сущностей в cms на каждый чих
Наверное вы неправильно поняли весь смысл тех же Next, nuxt, gatsby и прочих. По своей сути они представляют собой фреймворк для создания всего frontend'а для проекта с уже решенными проблемами навигации, server-side rendering'а, сборки и прочего. При этом использование любого бэкэнда, хоть того же php, это вполне нормальная практика, которая объединяет компонентный подход клиента и server-side render для быстрой загрузки и SEO с аккуратным API со стороны бэкэнда, где нет необходимости мучаться с шаблонами и можно отдавать обычный json из любой cms.
Возможность создания статических страниц из набора даннных это просто одна из побочных функций SSR. «Эй, мы же и так рендерим страницу полностью на сервере, почему бы нам не срендерить сразу несколько страниц?». Кардинальное отличие этих инструментов от ого же wp2satic это возможность гидрации динамического контента (объединение результата server-side рендера с клиентскими данными), что избавляет от пустых страниц с появляющимся контеном и от дополнительных запросов на сервер.
Само понятие JAM не привязывается ни к Netlify, ни к Contentfull. Это просто идея использования микросервисов напрямую из клиентского приложения, убирая лиший сервер в инфраструктуре. Тот же Firebase это хорошо демонстрирует, а вместе с realtime функциональностью firestore это становится просто сказкой для чего-то вроде комментариев/сообщений или совместной работы над документом. Разумеется в этом подходе можно как использовть сторонние SaaS решения, так и свои собственные, со всеми вытекающими последствиями vendor lock-in'а / необходимости поддержки, просто нужно выбирать подходящие решения под задачу, а простой запрос в managed базу не важно из чего писать: хоть php, хоть js.
Про поддержку можно много чего написать, но я вкратце поясню: уже давно прошли времена jquery, когда нужно было рукми подбирать специфические версии UI компонентов друг под друга. С приходом общего и стабильного API этого стало в разы меньше, но как и в любой другой экосистеме можно найти примеры обратного. Есть способы зафиксировать версии зависимостей (это уже стало поведением по умолчанию, если мы говорим про npm) и запустить проект хоть через полгода, хоть через два. Тут уже все на совести разработчика, а сделать плохо ни один язык не может запретить, хоть и очень сильно стараются.
Как я понял, вам очень комфортно работать с Wordpress CMS и вы противопоставляете его тем же gatsby и next. Но на самом деле они могут работать в связке: Wordpress CMS может работать как headless cms для клиента на gatsby и обеспечивать доступ в базу, интеграции со сторонними сервисами, и так далее, но со всеми преимуществами nuxt, такими как server side rendering, быстрая загрузка контента, отсутствие мигающего контента, счет в 100 баллов от lighthouse и так далее.
Да,
constructor
это вообще writable свойство, поэтому его можно переопределить просто в лоб:поэтому полагаться на него не лучшая идея
поправил в статье
спасибо, хорошо хоть одним вопросом меньше)
Также возникают вопросы с правильной типизацией всего, т.к. перебивание типа у this вызывает слишком большие вопросы как в ts, так и во flow.
Каждый пример имеет какое-то ограничение: не работает на старых браузерах, отсутствие интерактивности, хардкод размеров элементов, хардкод id самих элементов в css, ограничения с навигацией и с доступностью, сильно урезанный функционал.
Вот и получается что необходимо выбрать 2 пункта из 3 возможных:
— отсутствие JavaScript
— поддержка
— функционал