Комментарии 147
По поводу компиляции проектов — она довольно быстрая, но это, конечно, субъективно. А с опытом, как и в других сферах программирования, приходит навык написания большего количества строк кода без ошибок. То есть опытному спецу, которому все эти типизации и компиляторы не нужны, не нужно и страницу перезагружать после каждой измененной строчки в CSS.
Вы так говорите, будто я противопоставляю подходу "по умолчанию" что-то нестандартное. Все перечисленное — и есть самые настоящие стандарты веб-платформы. И их необходимо знать разработчику на любом стеке.
Про TS — я написал: он не работает в браузере. К сожалению.
По поводу больших блоков кода и пересборки — все верно, но только до тех пор, пока вы не взялись за UI.
Про TS — я написал: он не работает в браузере. К сожалению.
А какая, собственно, разница, работает он или нет? Особенно если вы этот факт не можете заметить.
Особенно это незаметно, когда дебажишь транспилированный код, ага.
А зачем вы дебажите транспилированный код, если можно дебажить исходник? Сами себе проблему создаете.
Кроме того, использование отладчиков вообще плохая практика сама по себе, т.к. потворствует написанию низкокачественного кода. Перестаньте пользоваться отладчиком и вскоре начнете писать код, для отладки которого отладчика не требуется :)
Дополню: JSDoc — он слегка сбоку, да, но анализ работает и для простого JS, даже без аннотаций. И это дает привыкнуть и втянуться. А JSDoc потом уже сам в руки просится.
опытному спецу <...> все эти типизации и компиляторы не нужны
Если вы так считаете, добро пожаловать в, например, блог PVS-Studio, много интересного узнаете :)
Пока веб-компоненты поддерживаются только у 60% пользователей, это будет оставаться такой же мета-платформой, с жирнючими, ЕМНИП, полифиллами. Для души дома можно и даже пожалуй нужно.
78.13 != 60, во первых, а во вторых полифилы не жирнее реакта. Ну и чуваки из Youtube и GitHub, к примеру, с вами не согласны.
Для этих (78.13 — 60)% это будет "Дорогие пользователи, чтобы насладиться нашим сайтом, пожалуйста включите настройку dom.webcomponents.shadowdom.enabled". Или "выбросьте уже свой сафари и поставьте нормальный браузер".
ерунду не надо писать, я использую описанный стек в проде
ага, минусануть проще, чем по ссылочке сходить и глянуть, как там safari: https://caniuse.com/#feat=shadowdomv1
А самому сходить и увидеть что там неполная поддержка?
А я очень хорошо знаю в чем ее неполнота, и мне она не мешает. Я еще раз повторю, я использую эти технологии сам и не на сайте "вася-пупкин.ком". Тестирую все лично в разных браузерах и на разных устройствах. Но вот обязательно найдется кто-то "очень умный" и расскажет как у меня ничего не работает, вопреки тестам и собственным глазам. Если уж минусите, потрудитесь аргументацию получше подбирать.
С удовольствием посмотрю на веб-компоненты, когда в FF они наконец-то выйдут из-под флага
А Гитхаб вроде переписывали на что-то свое с jquery, даже была новость. Сомневаюсь что там тяжелые компоненты.
Приятно знать, что я не одинок :-) Чувак с бородой — на моей стороне!
Извиняюсь за много вопросов, у меня тут реально аналитический паралич. Хочется выйти.
По первому абзацу было решил вы тут изложите как организовали свое рабочее место над беговой дорожкой и занимаетесь так веб программизмом...
Если что — в Фейсбуке ребята так и работают многие, у них там есть сидячие места, стоячие и бегучие.
На эту тему можно долго рассуждать, вспомнить JSX, VDOM и прочее, но для нас сейчас главным является вопрос: а альтернатива то какая? Нет, не Vue. И не, тем более, Angular. Для меня это веб-компоненты: набор стандартов CustomElements + ShadowDOM + ES Modules + HTML Templates. Почему? Потому, что это стандарты, поддерживаемые самой веб-платформой, а не мета-платформы и JS-надстройки..
Забавно, раньше под статьей про реакт или про какой-то другой js-фреймворк кто-то непонимающий обязательно напишет «А зачем оно надо, я на жуквери напишу за 15 минут» а теперь похоже настало время фраз — «зачем мне фреймворки если есть веб-компоненты»
Да, вебкомпоненты позволяют разбить на компоненты, изолировать стили и прочее, но они не никак решают самую главную проблему существования js-фреймвоков — проблему синхронизации ui и состояния. На эту тему даже есть отличная статья — medium.com/dailyjs/the-deepest-reason-why-modern-javascript-frameworks-exist-933b86ebc445.
Ну и вдобавок веб-компоненты имеют один фундаментальный недостаток — они не поддерживают svg. Вот захотите вы разбить какой-то svg-шаблон на компоненты также как и html, а нет — нельзя, приплыли. Когда же в реакте да и в остальных популярных js-фреймворках можно свободно разбивать svg на компоненты.
Проблема фреймворков в том, что они, на самом деле, НЕ решают проблему, которая обуславливает их существование. Точнее решают ее не до конца, оставляя миллион возможностей выстрелить себе в ногу в самой сложной ее части. React не умеет ничего делать с состоянием уровня приложения, он работает только с состоянием уровня компонента. А Redux — управляет глобальным состоянием, но ничего не знает про эффективные апдейты DOM. Ему это и не нужно конечно, но вот только мы уже давно вышли за пределы просто библиотеки для постройки UI. На уровне компонента, магия с динамическими привязками может впечатлить только откровенных новичков. И нужна она, по большей части, для задач организации и стандартизации структуры проекта, чтобы было удобнее работать со стандартными шаблонами. А в случае с веб-компонентами и прямым доступом к их DOM у вас нет такой необходимости. А на уровне приложения, вы очень быстро поймете, какая неудобная штука этот Redux, если ваши данные имеют какую-то более сложную структуру, чем нечто самое примитивное.
В конце концов, я написал что не призываю никого все бросать и срочно все переписывать на компонентах. Лично мне они дают очень многое, чего не давали фреймворки. Ну и размеры сборок у меня в РАЗЫ меньше, чем в проетах на реакте. И в тестах производительности они реакт уделывают. Да, пока только в Хроме, но, на минутчку, говоря о Хроме, мы уже говорим о БОЛЬШИНСТВЕ пользователей.
А в случае с веб-компонентами и прямым доступом к их DOM у вас нет такой необходимости.
Я правильно понимаю, что вы тут предлагаете в случае апдейта состояния приложения лезть руками в дом и его обновлять?
На уровне компонента, магия с динамическими привязками может впечатлить только откровенных новичков. И нужна она, по большей части, для задач организации и стандартизации структуры проекта, чтобы было удобнее работать со стандартными шаблонами. А в случае с веб-компонентами и прямым доступом к их DOM у вас нет такой необходимости.
Такое чувство что вы либо троллите либо не работали с вебкомпонентами вручную потому что без этих самых динамических привязок данных к шаблону которые синхронизируют данные с ui (что и является главной фичей всех фреймворков) вам придется написать вручную кучу кода. Как к примеру вы собираетесь отрендерить список компонентов? Если в реакте diff уже встроен и вам нужно будет написать всего одну строчку кода
<div>{state.todos.map(todo=><Todo key={todo.id} todo={todo}/>)}</div>
то с веб-компонентами у которых нет биндингов (привязок данных к шаблону) вам придется писать diff вручную а это примерно в 40 раз больше строк кода
//arr - новый или измененный массив todos
//keyField - имя поля объекта для индефикации по ключу (todo.id)
//elementName - название елемента которого нужно создать если массив пополнится
//parentElement, nextElement - родительский и следующий элемент внутри и перед которым нужно сделать вставку
//this.hash - хеш где ключу соответствует нода двусвязного списка
//this.lastNode - ссылка на последнюю ноду двусвязного списка
let nextNode = null;
let oldNode = this.lastNode;
for (let i = arr.length - 1; i >= 0; i--) {
const item = arr[i];
const key = item[keyField];
let node = this.hash.get(key);
if (!node) {
node = { element: document.createElement(elementName), key }
this.hash.set(key, node);
node.element.item = item;
node.element.index = i;
node.element.arr = arr;
parentElement.insertBefore(node.element, nextNode ? nextNode.element : nextElement)
} else {
if (oldNode === node) {
node.element.item = item;
node.element.index = i;
node.element.arr = arr;
} else {
if (node.prev) node.prev.next = node.next;
if (node.next) node.next.prev = node.prev;
parentElement.insertBefore(node.element, nextNode ? nextNode.element : nextElement)
}
}
node.next = nextNode;
if (nextNode) {
nextNode.prev = node;
} else {
this.lastNode = node;
}
nextNode = node;
if (oldNode && oldNode === node) oldNode = oldNode.prev;
}
let node = nextNode && nextNode.prev;
while (node) {
parentElement.removeChild(node.element);
this.hash.delete(node.key);
node = node.prev;
}
if (nextNode) nextNode.prev = null;
Нет, я никого не троллю и не говорю о том, с чем сам не сталкивался и не пытаюсь тут пропихивать какую-то смутную эзотерику. Меня тут уже обвинили во всех грехах вместо конструктивного диалога, и не раз сходили в карму поклонники динамических привязок. Я устал уже повторять, что если вам они нужны — нет проблем — вы можете использовать готовые библиотеки для этого (Polymer, lit-html) в сочетании с веб-компонентами. При этом на основе самих веб-компонентов можно делать пратформонезависимые UI-библиотеки для последующего использования с любым популярным фреймворком. Также, веб-компоненты являются очень удобной основой для написания своих библиотек и фреймворков, если у вас есть своя интересная концепция либо популярные решения вам чем-то не нравятся. Чем я и занимаюсь. Веб-компоненты — это про свободу в принятии решений. Максимум технических деталей я постараюсь изложить в своей следующей статье, чтобы потом сразу на нее давать ссылку и не писать одно и то-же в каждой ветке комментов. И, судя по всему, эта статья будет последней моей статьей на эту тему.
Решения для синхронизации UI и состояния для фреймворков и компонентов доступны одни и те же.
Во фреймворках (react, vue, angular) это уже встроено а c вебкомпонентами либо придется писать код в стиле jquery вручную меняя дом-элементы либо использовать дополнительно еще фреймворк/шаблонизатор который будет менять ui в зависимости от изменения данных но тогда смысл в веб-компонентах как в самодостаточной технологии теряется.
В чем фундаментальность этого недостатка, можете привести юзкейсы, когда это надо?
Ну как же — без поддержки svg веб-компоненты это какая-то обрезанная и ограниченная версия компонентой модели. Если какой-нибудь html-шаблон можно разбить на компоненты то чем svg хуже? Как с веб-компонентами вы планируете строить какой-нибудь сложный интерфейс на svg например онлайн-фотошоп или приложение для создание презентаций где будут графики, кривые безье, сложные фигуры и т.д?
Графики прекрасно рисуются на canvas и в WebGL, им не нужна древовидная структура документа, там вы оперируете другими сущностями. А вот чтобы нарисовать UI вокруг графиков — веб-компоненты отличный вариант. Что касается SVG — там есть инструментарий специфичный для этого формата, жаль конечно, что нельзя использовать единый подход, но ведь и простой HTML вы не сможете смешать с SVG без большого количества танцев с бубном.
Кстати, насчет SVG, я как-то делал эксперимент с SVG на компонентах: брал дочерние компоненты с описанием элементов и рендерил соответствующие им svg-ноды в теневом DOM компонента-контейнера. Конечно это не нативная поддержка, но вполне рабочий вариант для простых случаев.
Боюсь, что, когда веб-компоненты достигнут уровня React/Angular/Vue, нам оно уже не будет нужно, мы будет писать на чем-то другом.
Селекторы — это часть DOM API. Веб-компоненты дружат с DOM API крепче чем кто-либо из списка React/Angular/Vue, ибо сами являются его частью. Веб-компонентам не нужно достигать уровня React/Angular/Vue, они не для этого существуют. Это не очередной модный хипстерский фреймворк, это новые возможности браузера (как и querySelecto когда-то).
синтаксис [Typescript], скажем так, «рябит» в глазах
Не очень понятно, что не так с этим синтаксисом:
const val: string = 'test';
Альтернатива с JSDoc, которую вы предлагаете, выглядит еще более громоздкой:
/** @type {String} */
const val = 'test';
LESS/SCSS/PostCSS
Одних переменных мало, для того чтобы слезть с препроцессоров. Есть еще, как минимум, вложенные стили. Ни в одном браузере их нет, а без них приходится повторять одни и те же имена классов по многу раз.
CustomElements + ShadowDOM
Сложно, поверить, что нативных технологий тут достаточно. Реакцию на изменение атрибута или событие приходится программировать руками, выходит больше кода, чем у фреймворков.
Покажите пример вашего компонента?
Не очень понятно, что не так с этим синтаксисом
Вы привели какой-то уж слишком частный пример. Добавьте к нему интерфейсы, объявления функций от нескольких переменных, типизацию для элементов массива и т. д. И вот ваш код пестрит большой кучей лишних символов. В случае с JSDoc символов тоже немало, но они все сгруппированы отдельно. Конечно это вкусовщина, и действительно нет ничего особенно страшного в этом, можно привыкнуть. Но мой главный посыл был не в этом, а в том, что ваш код, при этом, не работает сразу в браузере. И здесь многое зависит от вашей специализации: чем в ней больше UI тем этот недостаток значительнее.
Одних переменных мало
Все верно, в препроцессорах мы еще ценим миксины. И даже есть какие-то движения по нативной реализации, но пока все плохо. Но на эту проблему можно взглянуть и под другим углом:
- Для сборки приложения вы можете использовать библиотеку UI-компонентов, в которых все стили упакованы внутри, и на более общих уровнях вам потребуется самый минимум CSS, без особой необходимости в повторениях.
- Если вы храните шаблоны в JS-модулях, как строки, вам доступна обычная интерполяция: миксуйте что угодно, добавляйте, по желанию, любую логику.
Реакцию на изменение атрибута или событие приходится программировать руками
Ее в любом случае придется программировать руками, это же логика компонента, ни один фреймворк не может сам предсказать что вы от него хотите. На изменение атрибутов веб-компоненты сами генерят сallback, и вы можете выполнить в нем любой необходимый код. Либо пробросить измененное значение на сеттер. На события компоненты реагируют как и любой другой DOM-элемент, + есть Custom Events. Не вижу тут ничего сложного.
Покажите пример вашего компонента?
Напишу ради этого статью. Разложить все по полочкам в рамках одного коммента, думаю, для меня непосильно.
Но мой главный посыл был не в этом, а в том, что ваш код, при этом, не работает сразу в браузере.
С этим аргмументом не спорю, все так и есть. А вот про "синтаксис рябит в глазах" — это личное предпочтение, как объективный аргумент — не засчитывается.
Для сборки приложения вы можете использовать библиотеку UI-компонентов, в которых все стили упакованы внутри
Прекрасный аргумент. Если кто-то сделает часть работы за нас, то это, конечно, хорошо, но так бывает не всегда.
Если кто-то сделает часть работы за нас
Почему обязательно за нас? Я это сам для себя делаю. А мои коллеги пользуются готовым.
А в чем тогда суть абзаца, что препроцессоры — не нужны?
Да нет же. В вашу библиотеку UI-компонентов могут входить блоки, которые являются организующими — то есть содержат типовые стили, которые вы хотите повторять по всему проекту. Потом вы просто используете специальный тег в разметке, вместо перечисления классов для каких-либо контейнеров. А необходимые параметры настраиваются CSS-переменными, в одном месте для всех вложенных блоков. Также, все необходимое вы можете указать через атрибуты. Тут меняется подход в целом, и миксины становятся компонентами. Ну и про второй пункт не стоит забывать: вы имеете полную свободу с использованием миксинов в ES-модулях, содержащих стили.
Простите, я не очень понял что точно и у кого конкретно вы спрашиваете, но думаю цитата из моей поверхностной статьи может быть ответом:
Разбить ваш код на аккуратные блоки и организовать его как вашей душе угодно вы можете с помощью нативных модулей. Да, модули поддерживаются всеми современными браузерами и вам не нужна пересборка в процессе разработки.
Ваше решение подразумевает что вы должны будете решить следующие проблемы:
1) Все пакеты (включая все сторонние) должны быть с ES6 module system. Что вообще-то специфическая ситуация. Редкий npm пакет для УИ в main field указывает js c ES6 import'ами.
2) вот у вас есть в коде `import '@babel/polyfill'` я так сходу не понимаю каким образом это в броузере разрешится в загрузку ./libs/@babel/polyfill/polyfill.js (или посчитается что `<script src=''./libs/@babel/polyfill/polyfill.js" >` произвел загрузку ) Вы соглашаетесь на «скинуть все в корневой каталог» я правильно понимаю?
3) гибридная проблема было import $ from 'JQuery' а jquery загружен в global как это будет понято броузером?
Вам не нужны сорс-мапы когда вы работаете напрямую с исходниками в браузере. А если вам требуется поддержка старых браузеров — вы в любом случае будете работать с транспилированным кодом и сгенерированными сорс-мапами. Тут просто нет других вариантов, если вы хотите писать на современном JS. Я решаю этот вопрос очень просто: я не берусь за проекты, в требованиях к которым требуется поддержка всякой некрофилии. Глупо удорожать разработку в полтора-два-три раза ради несчастных полутора пользователей на древнем железе и осях. Если же, не смотря ни на что, вам такое потребуется — с очень многими современными возможностями будут проблемы, далеко не с одними модулями.
Но я понял вам не актуально. ОК.
Вот мы пытаемся без webpackа грузить (то что с webpackом без проблем):
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/popper.js/dist/umd/popper.js" ></script>
<! -- можно и esm/popper.js type="module" -->
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/Es8Test.js" type="module"></script>
При этом внутри Es8Test.js есть `import Popper from 'popper.js';`
И конечно увидим что так не работает.
Вы конечно как-то этот случай отсекли, но я вот так не вижу и этвета на вопрос «что с этим кодом не так-то»?
Какая-бы специфичная система сборки не использовалась в ваших зависимостях, вам она не нужна для пересборки кода вашего приложения. Вы либо подключаете зависимость к проекту глобально, либо делаете ES-модуль-коннектор, который работает с готовой сборкой. Вам ведь не нужно пересобирать код, в котором, априори, нет изменений.
Разбить ваш код на аккуратные блоки и организовать его как вашей душе угодно вы можете с помощью нативных модулей.
Cформулировал ограничение: заменить загрузку `script src` (загрузку бандлера) загрузкой ES6 модулей `script type=«module»` неполучится в случае если имеет значение тот факт что script грузится синхронно, а модули — асинхронно. Т.е. в случае наличия нетривиального инлайн кода. Т.е. по-моему практически для всякой MPA ваша рекомендация неприменима, хотя может я может и не знаю как теперь готовят MPA.
По крайней мере у меня так )))
- TS — не вижу проблемы подождать компиляции. Честно говоря, новые фичи пилю большую часть времени вообще не глядя в браузер, только код в IDE. Спустя час-другой, когда все готово, уже делаю смоук тест в браузере. Обычно все работает с минимальным шаманством как раз благодаря типизации ТС и отлову ошибок ещё во время компиляции.
- Препроцессоры — их клмбинирую с css переменными. У них есть классный синтаксический сахар для описания классов с префиксами.
- Менеджмент стейта — вы предлагаете костылировать самому то, что уже написано? Зачем? Если результат тот же, то не проще ли использовать готовое? Чтобы облегчить боль новых девов на проекте и чтобы использовать уже протестированные
Сильно зависит от задач. Иногда я сам не заглядываю в браузер часами, иногда — жму релоад каждую пару секунд. Особенно потери на перекомпиляцию заметны при работе с UI, с визуализацией данных и при отлове странных багов. А вот проблемы с типами — большая редкость.
Префиксы (если вы говорите о префиксах в именованиях) — не особенно вам нужны, если вы работаете с ShadowDOM.
Про стейт-менеджмент — на мой взгляд, я довольно четко изложил свою позицию. Популярные решения лично меня не устраивают: если ваше приложение чуть сложнее формочки в интернет-магазине — вас ждут проблемы. Но, в вашем конкретном случае, вы можете использовать любое популярное решение. Универсальных рецептов не существует. Я люблю писать велосипеды, потому, что это интересно, это развивает, и вы можете реализовать то, чего нет в популярных либах, например графовое хранилище состояний.
Годная статья. А то у многих разработчиков очень часто на каждую новую, даже очень простую фичу в проекте подключается новый Фреймворк (библиотека)
Простите, а вы не путаете синхронизацию стейта с байндингами? Потому, что никакого стейта приложения в реакте и подобных либах — нет, и для этого нужны дополнительные либы.
Простите, а вы не путаете синхронизацию стейта с байндингами?
Раз есть сомнения, давайте тогда определимся с терминами:
State — состояние компонента, его данных, либо обобщенный термин;
Store — глобальное состояние приложения, вынесенное в отдельную сущность;
Binding — связывание стейта и UI, а автоматической или полуавтоматической синхронизацией изменений в одну или обе стороны;
Потому, что никакого стейта приложения в реакте и подобных либах — нет, и для этого нужны дополнительные либы.
Конечно же там есть стейт:
// React
class App extends Component {
constructor() {
super();
this.state = {
/* state */
};
}
}
// Vue
new Vue({
data: {
/* state */
}
})
В React даже метод называется this.setState(state);. Кроме того там есть Store (Redux/Vuex) и биндинги.
Поэтому да, я говорю о биндингах и о стейте. Эти наиболее важные части никак не покрываются стандартном Web Components, об этом и вопрос. Потому что сама по себе декомпозиция приложения на компоненты — это даже не пол дела, сложнее всего работать со стейтом, с данными и держать UI и данные всегда up-to-date.
Ценность фреймворков совершенно не в его компонентной модели, которую, конечно же, можно будет со временем полностью заменить на Web Components. Ценность именно в data-driven подходе к разработке, а в этом направлении стандарты не дают нам ничего.
Вы написали именно "стейт приложения", а это не стейт компонента. Стейт приложения вы можете хранить в store или в чем вашей душе угодно, и использовать любой популярный стейт-менеджер вам никто не мешает с веб-компонентами, как и использовать для байндингов и прочего сахара готовые решения типа Polymer. При этом у вас также весь рантайм разработки будет доступен без пересборки. И про реакт можете не рассказывать так подробно, я отлично его знаю.
Вы написали именно «стейт приложения», а это не стейт компонента.
Стейт приложения — это ничто иное как суммарный стейт всех компонентов плюс, при наличии, стейт глобального стора. Если бы я хотел сказать про стор, я бы так и написал.
Стейт приложения вы можете хранить в store или в чем вашей душе угодно, и использовать любой популярный стейт-менеджер вам никто не мешает с веб-компонентами,
Никакой Redux биндингами стейта и UI не занимается, также как не занимается change detection, точечными изменениями DOM и так далее, поэтому даже если я будут его использовать, большой пласт работ все еще будет не покрыт.
как и использовать для байндингов и прочего сахара готовые решения типа Polymer.
Так почему бы мне не использовать готовые решения, типа React/Vue/Svelte? Потому что получается с Web Components я получаю несущественную часть фукнционала, по сути только компонентный подход, а далее должен костылись или искать внешние решения для всех остальных потребностей. Зачем все это, если можно использовать готовое решение в комплексе?
При этом у вас также весь рантайм разработки будет доступен без пересборки.
Это такой большой плюс? Немного не уловил.
Если бы я хотел сказать про стор, я бы так и написал
Стор — это хранилище, стейт — это состояние. Никаких иных терминологических уточнений тут не требуется. И реакт не управляет состоянием на уровне приложения, это, также — факт. Состояние на уровне компонента и глобальный стейт-менеджмент — это отдельные вопросы, которые можно разобрать, также, отдельно. В общем случае, свое отношение к ним я изложил как в статье, так и в комментариях, уже не раз. На уровне компонента, лично мне, автобайндинги не нужны, так как на определенном уровне декомпозиции с обычным DOM API — с этим нет никаких проблем, при бОльшем контроле происходящего. На уровне приложения стандартные решения упираются в сложные данные и логику: за определенным порогом вам эти библиотеки начинают больше мешать чем помогать. Но это мое частное мнение, как я уже сказал, если вы хотите больше сахара — можете использовать Polymer. Или вообще использовать классический стек, если он вам подходит больше. Такое впечатление, что люди реагируют как на красную тряпку на определенные слова а остальную статью читаю по диагонали, оставляя общий посыл за скобками.
Стор — это хранилище, стейт — это состояние. Никаких иных терминологических уточнений тут не требуется. И реакт не управляет состоянием на уровне приложения, это, также — факт. Состояние на уровне компонента и глобальный стейт-менеджмент — это отдельные вопросы, которые можно разобрать, также, отдельно.
А до появления Redux приложения на React были stateless что ли? То есть если бы не хранилище, то у приложений на React не было бы состояния? Что вы ерунду то пишете. Раньше просто размазывали стейт приложения по компонентам, теперь стильно и модно держать весь стейт в сторе.
При этом как раньше это называлось состоянием приложения, так и сейчас называется. И React, управляя стейтом отдельных компонентов, всегда управлял в итоге состоянием приложения.
На уровне компонента, лично мне, автобайндинги не нужны, так как на определенном уровне декомпозиции с обычным DOM API — с этим нет никаких проблем, при бОльшем контроле происходящего. На уровне приложения стандартные решения упираются в сложные данные и логику: за определенным порогом вам эти библиотеки начинают больше мешать чем помогать.
Начали какой-то бессмысленный терминологический спор, хотя суть моего вопроса предельно ясна — кто будет делать всю грязную работу? Ваш ответ, по всей видимости, вы сами будете этим заниматься. Не очень понимаю зачем, но дело ваше.
Или вообще использовать классический стек, если он вам подходит больше. Такое впечатление, что люди реагируют как на красную тряпку на определенные слова а остальную статью читаю по диагонали, оставляя общий посыл за скобками.
Почему это? Просто у вас эта тема вообще не раскрыта в статье. Пишете о всяких там Shadow DOM, которые нужны значительно реже, чем то о чем пишу я.
Пишете что фреймворки не нужны, потому что есть Web Components и стандарты вокруг них, но не упоминаете, что они не покрывают и половины возможностей фреймворков.
Всем привет!
Пожалуйста, не надо столь долгих лирических отступлений. Тем более приведённых совершенно не к месту.
TypeScript
JSDoc облагает крайне низкой выразительной мощью и крайне высокой многословностью.
Именно транспиляция TS в JS происходит практически мгновенно. Относительно долго ждать приходится только проверки типов. Вы можете отключить проверку типов для сборки во время разработки.
Ангуляровцы запускают проверку типов асинхронно. Я же предпочитаю всё же подождать и убедиться, что тот код, что я написал действительно корректен, прежде чем руками проверять как он работает.
LESS/SCSS/PostCSS
Транспиляция опять же практически мгновенная.
css переменные нарушают инкапсуляцию, за которую вы далее топите.
Нативной арифметики над цветами до сих пор нет.
React
Вот как раз именно формочки на реакте делать и не удобно из-за отсутствия двустороннего связывания.
Популярным он стал больше за счёт маркетинга, чем из-за каких-то своих особых качеств.
В энтерпрайзе популярней Angular.
CustomElements + ShadowDOM + ES Modules + HTML Templates
Это довольно кривоватый (чего только стоят только текстовые параметры компонент) и тормозной (dom и так не сильно шустрый, а тут ещё и многовложенный) фреймворк. Частичная встроенность его в некоторые браузеры — единственное его преимущество.
Невозможность изменить визуальное представление вложенных компонент извне — просто вишенка на торте. Хотите модалку от Гугла, а датапикер от Яндекса — получайте лоскутное одеяло вместо интерфейса.
Как жить без биндингов вы так и не показали. А ведь это основная причина появления фреймворков — отсутствие среди нативных инструментов каких либо биндингов. Нативные компоненты управляются исключительно интерактивно, ничего не зная про реактивность.
Redux/Mobx
То, что вы поместили их в один ряд красноречиво говорит о том, что вы не понимаете что это и о чём. redux — про процедурное программирование над глобальныхм хранилищем. mobx — про эффективную синхронизацию состояний. С redux в один ряд можно поставить разве что mobx-state-tree. А с mobx — rxjs.
И как раз с mobx вы как никогда вольны организовывать состояние приложение так как вам хочется, без кучи головной боли по актуализации зависимостей.
Webpack
Вы предлагаете в режиме разработки пользоваться нативными импортами, а в проде всё собирать в бандлы. Это источник довольно неприятных багов вида "всё запилил, протестировал, а перед самым релизом вдруг прилетают невозможные баги от тестировщиков". Из последнего, что у нас было, — стандартный ангуляровский минификатор предположил, что обращение к полю не имеет сайд эффектов и вырезал его. У разработчика всё работает. Модульные тесты проходят. А ручное тестирование релиза выявляет проблему.
Что в итоге
Хороший фреймворк — не тот, на котором толковые люди при достаточном времени в запасе смогут сделать всё хорошо, а тот, на котором бестолковые люди с горящими сроками не смогут сделать плохо.
css переменные имеют нелокальное действие. Если у вас есть два компонента использующих переменную foo
, то вам придётся очень не сладко, чтобы изменить её только для одного из них. А вот так пугающие вас пространства имён (my_button_foo
) этой проблеме не подвержены. Более того, пространства имён дают понимание какой именно компонент настраивает та или иная переменная.
Пожалуйста, не надо столь долгих лирических отступлений.
Всем не угодишь. А угодить конкретно вам цели не было.
транспиляция TS в JS происходит практически мгновенно
У меня прямо сейчас перед глазами 2 проекта с двумя версиями одного приложения. Одно написано на реакте и TS, другое, с обновленным дизайном, написано на JS с веб-компонентами. Время реакции на изменения в коде, связанное с транспайлом, отличается ОЧЕНЬ СИЛЬНО. Настолько, что визуальные правки в версии на TS становятся болью. Я сейчас говорю не о каком-то легком дискомфорте, а о серьезных фризах в воркфлоу, которые просто уничтожают идею "дизайна в браузере". Добавьте к этому шаги на пути к определенным стейтам, и возможность работать напрямую с отдельными модулями в случае с веб-компонентами без настройки отдельных эндпоинтов. Кроме того, одной из больших проблем клиентской разработки является сегментация платформы, и в этом ключе дебаг исходного кода — в разы удобнее без пересборок. Как и профайлинг для тонкой оптимизации.
Нативной арифметики над цветами до сих пор нет.
Если хранить шаблоны в виде JS-строк, как это сделано, например, в новом Polymer, и в моих велосипедах, вам становится доступна вся мощь JS: все реализуется элементарно, и работа с цветами, и миксины и любые капризы завязанные на рантайм (что нереально с ПРЕпроцессорами).
css переменные нарушают инкапсуляцию
Вы серьезно? Переменные — это удобный механизм контроля и разделения того, что инкапсулируется и доступно для управления внешними параметрами. По сути, переменные определяют стандартное API для стилизации компонентов, вот уж никак не назвал бы это недостатком. При этом у вас нет никакой необходимости в многоэтажном вырвиглазном именовании классов.
В энтерпрайзе популярней Angular
Откуда такие данные? Какая вообще разница?
Это довольно кривоватый (чего только стоят только текстовые параметры компонент) и тормозной (dom и так не сильно шустрый, а тут ещё и многовложенный) фреймворк.
Блин, вы серьезно? То есть JS-абстракция над тормозным нативным DOM эффективнее чем нативно поддерживаемые низкоуровневые средства расширения его элементов? Я правильно понял? Мантра про тормозной DOM — это вообще дичь какая-то, ибо тормозной не DOM а некоторые ресурсоемкие вычисления при работе с его API. Просто избегайте их, там где можете. Мне доводилось сравнивать по производительности реактовские компоненты с веб-компонентами, угадайте, кто победил?
Частичная встроенность его в некоторые браузеры — единственное его преимущество.
Полная поддержка в Хром и всех его производных, от Оперы до всякой фигни на Хромиуме. С недавних пор — полная поддержка в Electron. Это не "некоторые браузеры", а ПОДАВЛЯЮЩЕЕ БОЛЬШИНСТВО пользователей по статистике. Посмотрите на цифры, я не зря приводил ссылки в статье. Частичная поддержка в Safari, которая имеет ограничения, но в общем случае просто работает (есть нюансы по селекторам в ShadowDOM, которые легко обходятся). Да, остальные работают с полифилами, и да, это ведет к просадке в производительности, но все в рамках приличия, во всяком случае, не уступает особо реактам с ангулярами.
чего только стоят только текстовые параметры компонент
Что не так?
красноречиво говорит о том, что вы не понимаете что это и о чём
Я поставил редакс и мобекс в один ряд в рамках того контекста, где это вполне корректно. Ежу понятно, что в них есть разница, но ее разбор отдельная тема, выходящая немного за рамки. Не готов сейчас начинать еще и этот холивар, по моему я это вполне ясно выразил в самой статье. Не потому, что мне знаний не хватает (я имел дело со всем списком), а потому что в этой теме дофига собственной глубины. Да и без меня уже много воды вылито на эту тему.
Это источник довольно неприятных багов вида "всё запилил, протестировал, а перед самым релизом вдруг прилетают невозможные баги от тестировщиков". Из последнего, что у нас было, — стандартный ангуляровский минификатор предположил, что обращение к полю не имеет сайд эффектов и вырезал его.
То есть, у вас мгновенная компиляция еще и с минификацией при разработке? Или вы работаете постоянно с продакшн сборкой? Ох…
Хороший фреймворк — не тот, на котором толковые люди при достаточном времени в запасе смогут сделать всё хорошо, а тот, на котором бестолковые люди с горящими сроками не смогут сделать плохо.
Все верно. Мой посыл был лишь в том, что всегда есть место для подумать. Есть ситуации, когда популярный "дефолтный" стек — самый разумный вариант, и таких ситуаций куча. Нужно просто отдавать себе отчет в том, что этот вариант не единственный по умолчанию. И не лучший по всем параметрам. И часто выкидывая что-то лишнее вы приобретаете гораздо большее. И новые возможности платформы могут многое изменить и сделать лучше в ваших процессах, именно поэтому их вводят в оборот серьезные бородатые разработчики браузеров, после своих ожесточенных обсуждений принимая как стандарты. Их просто необходимо знать.
Всем не угодишь. А угодить конкретно вам цели не было.
Не переходите на личности, пожалуйста. Не стоит воспринимать негативный фидбек как наезд, требующий ответа.
Время реакции на изменения в коде, связанное с транспайлом, отличается ОЧЕНЬ СИЛЬНО
Прежде чем спорить постарайтесь вникнуть в то, что вам пишут, чтобы не выглядеть дураком. Транспиляция и проверка типов — две различные операции. Первая — быстрая, над одним файлом. Вторая — медленная, над всеми файлами. Склеивание файлов в бандл — тоже быстрая операция. Очевидно в вашем проекте все эти операции выполняются на каждое изменение файла, что приводит к тормозам.
Добавьте к этому шаги на пути к определенным стейтам
Храните стейт в соответствующих хранилищах (сессия, история, локальное, урл) и не занимайтесь ерундой с восстановлением состояния при перезагрузке.
возможность работать напрямую с отдельными модулями в случае с веб-компонентами без настройки отдельных эндпоинтов
Это возможность любого компонентного фреймворка.
в моих велосипедах, вам становится доступна вся мощь JS
Вы уж определитесь, топите вы за веб стандарты или за велосипеды и чем ваши велосипеды лучше велосипедов фейсбука и гугла.
Откуда такие данные? Какая вообще разница?
Как бы кручусь в этой сфере. Вы взяли стек популярный у хипстеров, поругали его, и из этого сделали вывод, что фреймворки — говно, а вот веб-компоненты с вашими велосипедами — добро.
То есть JS-абстракция над тормозным нативным DOM эффективнее чем нативно поддерживаемые низкоуровневые средства расширения его элементов?
Да. Любой выход из js рантайма — медленно. Любое изменение приаттаченного узла — медленно. Обращение ко многим свойствам узла может вызвать их пересчёт. Правильная JS абстракция сводит к минимуму эти ресурсоёмкие операции. У веб-компонентов же всё взаимодействие идёт через dom.
Мне доводилось сравнивать по производительности реактовские компоненты с веб-компонентами, угадайте, кто победил?
Не люблю гадать. Приведите бенчмарки.
Да, остальные работают с полифилами, и да, это ведет к просадке в производительности, но все в рамках приличия
Мы экспериментировали с полимером на мобилках пору лет назад. Выглядело это так: компоненты в течении нескольких секунд появлялись по одному.
Что не так?
Может быть то, что "строка" — далеко не единственный тип данных, который используется в программировании?
Я поставил редакс и мобекс в один ряд в рамках того контекста, где это вполне корректно.
Что за контекст такой? Они как бы перпендикулярны, как тёплое с мягким.
То есть, у вас мгновенная компиляция еще и с минификацией при разработке? Или вы работаете постоянно с продакшн сборкой?
С продакшен сборкой, где нет никакой минификации. Например: http://mol.js.org/app/todomvc/-/web.js
популярный "дефолтный" стек
Нет никакого "дефолтного" стека. В разных компаниях популярны разные стеки. В одних React+Redux, в других Angular+NGRX, в третьих вообще SAPUI5. Я понимаю вашу боль, упомянутый вами стек — далеко не предел мечтаний. Я и сам могу много гадостей про него рассказать. Но поверьте, React+Redux — далеко не самое худшее, что вас может заставить использовать некомпетентное руководство.
Как жить без биндингов вы так и не показали. А ведь это основная причина появления фреймворков — отсутствие среди нативных инструментов каких либо биндингов. Нативные компоненты управляются исключительно интерактивно, ничего не зная про реактивность.
На это вопрос я уже тоже отвечал не раз в комметах: нужны биндинги — используйте готовые решения типа Polymer или lit-html. А можно написать свои. А можно не использовать совсем и быть счастливым вполне. В ваших руках — полная свобода и куча новых возможностей. Я говорю лишь о том, что не стоит запирать себя в клетку одной мета-платформы.
На это вопрос я уже тоже отвечал не раз в комметах: нужны биндинги — используйте готовые решения типа Polymer или lit-html.
Но вы не ответили на вопрос, почему бы не использовать готовые решения вроде Ангуляра или Реакта.
Потому что выбирая Ангуляр или Реакт ради биндингов, мы получаем в нагрузку кучу невыпиливаемых абстракций — VDOM, JSX, TypeScript, RxJS
Чем это плохо?
Тем, что вы получаете в нагрузку кучу сайд-эффектов, лишний код, который делает ваше приложение тяжелее в разы, усложняете без необходимости то, что может быть предельно простым, тащите в проект специфический для мета-платформ синтаксис со своими собственными заморочками, которых и без того во фронтенде достаточно? Тем, что состоянием компонента может быть не только парочка пропсов, но и положение каретки при вводе, определенное положение при прокрутке страницы, элементы из таб-индекса в фокусе, выделение текста? Тем, что работа со всем вышеперечисленным через дополнительные абстракции — это боль, потому, что источником всей правды, учитывающей вышеперечисленное, является DOM и ничто больше, и никакие внешние абстракции ничего о изменениях от непосредственных действий пользователя без обращения к DOM не знают? Тем, что для управления состоянием, в огромном количестве случаев, достаточно CSS и HTML-атрибутов? Тем, что ради изменения textContent одного элемента в DOM нет никакого смысла использовать библиотеки, так как они делают в итоге тоже самое используя тот-же DOM API? Тем, что ваше приложение тормозит, потому что использует JS там, где браузер может справится сам, используя оптимизированный код написанный вендором на C++? Продолжать?
И я в сто-пицотый раз повторю: да, есть случаи, когда все-же лучше взять фреймворк. Но эти случаи не так часты, как считают карго-культисты. А веб-компоненты вам дают свободу выбора: понадобились либы — юзайте, нужно кастомное решение — пишите спокойно, не беспокоясь о том, как скрещивать ужа с ежом.
А веб-компоненты вам дают свободу выбора: понадобились либы — юзайте, нужно кастомное решение — пишите спокойно, не беспокоясь о том, как скрещивать ужа с ежом.
Ну есть практика, которая показывает, что гипотетическая польза от свободы когда-то в будущем в итоге ниже, чем конкретная польза сейчас от использования конкретного фреймворка.
Тем, что лично мне они могут быть не нужны.
Тогда личное вы можете их не использовать.
Я имел ввиду, что вы можете не использовать Реакт или Ангуляр.
Какая-то бессмысленная тогда статья. Это разве не очевидно, что если кто-то не хочет использовать реакт или ангуляр, то может и не использовать? Зачем об этом писать?
Я все же статью понял так, что автор формулирует и далее продвигает свою позицию о том, как правильно.
Конечно, может, и неверно понял, а верна ваша интерпретация.
Ну то есть вы признали, что одними-то только веб стандартами не обойтись — нужны js обвязки типа polymer, lit-html, react и прочих.
Бег на месте и веб-разработка