Frontender Magazine

Перестаньте писать JavaScript фреймворки!

JavaScript фреймворки подобны смерти и налогам — неминуемы и неизбежны. Я уверен, что если бы мог подслушать всех, кто начинает веб-проект, каждый раз первый вопрос был бы о том, какой JavaScript фреймворк в нем будет использоваться. Вот насколько укоренилась роль фреймворков в нашей отрасли. Это не так, как должно быть, пора остановиться.

Давайте оглянемся назад и постараемся понять, как мы к этому пришли.

Angular и Backbone и Ember, о боже

Долгое время веб-платформы, технологичный стек наиболее лаконично описываемый как HTML+CSS+JS, был, из-за отсутствия лучшего термина, катастрофичным. Кто может забыть блочную модель IE или тег layer? Я уверен, что у некоторых из вас от одних только этих слов начался нервный тик из-за воспоминаний о старых, не добрых, временах веб-разработки.

Долгое время было много несоответствий в поведении браузеров и мы, как отрасль, должны были писать фреймворки, чтобы скрыть эти недостатки. Проблема в том, что расхождения были даже в фундаментальных вопросах, например как события распространяются или какие теги поддерживаются, так что каждый фреймворк не только прикрывал дырки, но разрабатывал свою собственную модель того, как браузер должен работаь. На самом деле свои собственные модели, во множественном числе, потому что вы должны изобрести модель распространения событий, модель взаимодействия с DOM, и т.д. Много изобретений было сделано. Фреймворки писались, каждый уникальный, как снежинка. Они расцвели как тысяча цветов и дали нам все эти JQuery и Dojo и MochiKit и ExtJS и AngularJS и Backbone и Ember и React. Прошедшие десять лет мы наблюдали устойчивый парад JS фреймворков.

Но что-то ещё произошло за последние десять лет — браузеры стали лучше. Их поддержка стандартов улучшилась, и сейчас есть вечнозелёные браузеры: браузеры автоматически обновляются, и в каждой новой версии больше возможностей и лучше соответствие стандартам, чем у предыдущих. И с новыми стандартами, такими как:

Я думаю, пришло время переосмыслить модель JS фреймворков. Нет необходимости изобретать ещё один способ сделать что-то, просто используйте HTML+CSS+JS.

Так почему же мы всё ещё пишем JS фреймворки? Я думаю, по большей части по инерции, это привычка. Но так ли это плохо, фреймворки же, вроде, не наносят вреда сами по себе? Что ж, давайте сначала определим то, что я имею в виду под веб-фреймворком. Категории кода — это градиент. Он начинается простым фрагментом, например Gist, и потом направляется ко всё более крупной коллекции кода, достигая библиотеки, и, наконец, фреймворка:

Gist → библиотека → фреймворк

Фреймворки не только крупные библиотеки, они имеют свои собственные модели для того, как взаимодействовать с событиями, с DOM, и т.д. Так почему избегать фреймворков?

Абстракции

Ну, одна из проблем фреймворков, как правило, в том, что их и продаёт, то что они абстрагируются от платформы, так что вы можете сосредоточиться на создании программного обеспечения. Проблема в том, что теперь вам нужно знать две системы: HTML+CSS+JS и фреймворк. Конечно, если фреймворк был бы идеально абстрагирован от веба как платформы, за его пределы не пришлось бы выходить, но абстракции не идеальны. Таким образом, вы должны знать HTML+CSS+JS, потому что в какой-то момент код перестанет работать так, как вы ожидаете, и вы будете копать, пробираясь через все слои фреймворка, чтобы понять что не так, вплоть до HTML+CSS+JS.

Картографирование айсберга

Фреймворк как айсберг: 10%, плавающие над водой, не выглядят опасно, зато скрытые 90% — именно то, на чём вы в конечном счете попадётесь. Я склонен считать, что изучение фреймворка похоже на картографирование айсберга. Для того, чтобы использовать его, вам нужно узнать о нем всё, приложить усилия и изучить все его особенности, и в конечном счете всё будет напрасно, потому что айсберг в любом случае растает.

Виджеты

Второе, что помогает продавать фреймворки, это то, что вы получаете в своё распоряжение библиотеку виджетов. Но, на самом деле, не стоит использовать фреймворк, чтобы получить доступ к виджетам, все они должны быть ортогональными и независимыми. На сегодняшний день хороший пример — CodeMirror, редактор подсветки синтаксиса кода написанный на JavaScript. Вы можете использовать его везде, никаких фреймворков не требуется.

А ещё усилия, приложенные для написания виджета с использованием фреймворка, могут пропасть впустую. Помните все виджеты, которые вы написали для MochiKit? Много ли пользы они приносят сейчас, после перехода на Ember или Angular?

Связывание данных

Честно говоря мне это никогда не требовалось, но, в любом случае, это стоит реализовать в виде библиотеки, а не фреймворка.

Проблема фреймворков в долгосрочной перспективе в том, что они в конечном итоге заканчивают как хранилища, они сегментируют отрасль, виджет построенный для фреймворка А не работает в Б. Это потерянные усилия.

Итак, как выглядит пост-фреймворковый мир?

Мой фреймворк — это HTML+CSS+JS

Основная идея в том, что фреймворки не нужны, используйте возможности уже встроенные в HTML+CSS+JS для создания виджетов. Разбейте монолиты на куски ортогональных компонентов, которые можно смешивать в любом сочетании. В итоге всё это будут включать в себя Веб-компоненты.

HTML Imports, HTML шаблоны, настраиваемые элементы и Shadow DOM — все эти технологии расширяют наши возможности. Они должны позволить нам разорвать связь с фреймворками, позволяя создавать пригодные для повторного использования элементы и функционал. Для наглядного представления смотрите эти статьи и библиотеки:

И что, мы все создадим <x-flipbox>, объявим о победе, и вернемся домой?

Нет, не совсем, первое, что вам нужно для работы с веб-компонентами — полифиллы для этой функциональности, такие как X-Tag и Polymer. Потребность в этом будет уменьшаться с течением времени, по мере того как браузеры конкретизируют свои реализации этих спецификаций.

Момент, который следует подчеркнуть: это полифиллы, не фреймворки, предоставляющие собственные модели для веб-разработки, они действуют по модели HTML5. Но нам необходимо не только это, есть ещё и небольшие пробелы в платформе, когда один браузер немного отклоняется от действующих стандартов, и это то, что мы должны полифиллить. В MDN, похоже, есть много необходимого кода, потому как в документации часто содержится короткие полифиллы для каждой функции.

Хорошо, если бы у нас была одна огромная библиотека полифиллов HTML5, но ещё лучше было бы то, что я назвал бы «html-5-polyfill-o-matic», набор инструментов, который позволил бы мне использовать Веб-компоненты минуя трясину HTML+JS, а затем анализировал мой код, или статическим анализом, или через Object.observe при работе, и выдал бы мне из всего полифилла HTML5 только то, что нужно для моего проекта.

Этот вид функциональности ещё более важен, потому что я начал пытаться совместить веб-компоненты и библиотеки из нескольких источников, т.е. <x-foo> от X-Tag и <core-bar> от Polymer, значит ли это, что мне придётся подключать обе эти библиотеки полифиллов? (Оказывается, что ответ нет.) И как именно я должен получать эти специфические элементы? И X-Tag, и Brick имеют собственные пакеты генераторов:

Если я начну создавать собственные элементы, мне нужно будет создавать и свой собственный пакет? Я не думаю, что это масштабируемая идея, я считаю, что нам нужны идиомы и инструменты, которые справлялись бы с этим гораздо лучше. Это на самом деле может означать изменение того, как пишется открытый код. «Виджет» не проект, поэтому наша работа с этими вещами должна изменится. Конечно, продолжайте хранить код в Git, но нужны ли вам накладные расходы в виде GitHub? Что-то более легковесное, ближе к Gist, чем к проекту, подошло бы лучше. А как минимизировать/вулканизировать весь этот код в подходящий для использования в моем проекте вид? Что-то вроде Asset Graph может стать хорошим началом.

И так, что нам теперь нужно?

  1. Идиомы и принципы построения повторно используемых компонентов.
  2. Инструменты, которые работают в рамках этих идиом, для компиляции, сжатия, и т.п. HTML, CSS, и JS.
  3. Масштабируемый полифилл HTML5, полностью или частично построенный на основе тех, которые сейчас реально используются.

Это то, что нам требуется для того, что бы построить будущее, в котором нам не придётся знать последнюю модель новейшего фреймворка, вместо этого мы просто будем работать напрямую с платформой, загружая элементы и библиотеки для своих нужд, и тратя своё время на написание приложений, а не на картографирование айсбергов.

Вопросы и ответы

В: Почему вы ненавидите авторов фреймворков?

О: Я не ненавижу их. Некоторые из моих лучших друзей — авторы фрейворков. Признаюсь, я немного вдохновлялся ироничной статьёй «ты погубил JavaScript», но я ни в коем случае не высмеиваю авторов фреймворков.

В: Вы не можете сделать ____ на HTML5, для этого вам нужен фреймворк.

О: Во-первых, это не вопрос. Во-вторых, спасибо что указали на это. А теперь давайте работать вместе, чтобы добавить в HTML5 возможность делать ____ без фреймворка.

В: Но ____ не фреймворк, это библиотека!

О: Да, как я уже сказал, есть градиент от gist до фреймворка, и вы можете видеть всё немного иначе, чем я. Это нормально, я не про классификацию какой-либо конкретной части программного обеспечения, речь идет об отдалению от фреймворков.

В: Я делал это годами с помощью ____ и ____ и ____.

О: Опять же, это не вопрос, но всё равно, это хорошо, вы должны быть в хорошей форме, чтобы помочь всем остальным.

В: Таким образом, каждый должен переписать выпадающие меню, вкладки, ползунки и переключатели сам?

О: Абсолютно нет, дело в том, что должен быть способ, чтобы создать те элементы таким образом, чтобы не требовалось установки фреймворка.

В: Чувак, все эти HTML Imports скажутся на производительности сайтов

О: Если вы используете все это бездумно, то да. Вот, почему я указывал на необходимость инструментов, компилирующих и сжимающих HTML, CSS, и JS.

В: Так что я не должен использовать никакие библиотеки?

О: Нет, это не то, что я сказал. Я был очень осторожен с разграничением библиотек и фреймворков. Библиотека обеспечивает ортогональный кусок функциональности, которая может быть использована с другими библиотеками. Библиотеки — это хорошо. А вот фреймворки требуют 100% того, от чего, по моему мнению, стоит отказаться.

В: Но мне нравится связывание данных!

О: Много кому нравится, я только высказываю личные предпочтения. Я не говорю, что вы не должны использовать связывание данных, только то, что вам не нужно прикручивать весь фреймворк, чтобы получить привязку данных, для этого есть автономные библиотеки.

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Joe Gregorio
Автор:
Joe Gregorio
Сaйт:
http://bitworking.org/
GitHub:
jcgregorio
Twitter:
@bitworking
Александр Краснокутский

Комментарии (13 комментариев, если быть точным)

Автар пользователя
unel

ну, справедливости ради, polymer уже сложно назвать библиотекой (и тем более просто полифилом) очень уж в нём много дополнительных фишечек типа двустороннего дата-биндинга

Автар пользователя
mr47

Зря автор так, фремворки очень полезны но в меру. А насчет HTML Imports давайте подождем полной поддержки es5 го, а там и es6 и забудем мы про многие фремворки на JS.

Автар пользователя
SilentImp

У многих, похоже, идея подобного «дауншифтинг» вызывает боль в пятой точке.

Как по мне автор, предлагая писать плагины независимые от фреймворков, как то упустил из виду тот момент, что они пишутся так ввиду того, что используют их возможности и работают в рамках диктуемой фреймворком архитектуры приложения.

Я могу понять его желание сделать компоненты/плагины независимыми и несвязанными, но давно ли вы писали что то на dom api и воевали с кроссбраузерностью?

Даже если отказаться от фреймворков, что бы ускорить и упростить процесс придется использовать библиотеки и за компонентом/плагином в любом случае будет тянуться хвостик зависимостей.

Ну или процесс разработки копонента будет долгим и сложным.

Автар пользователя
TrySound

Поэтому я и стал создавать свои независимые компоненты. Github.com/trysound

Автар пользователя
mikeyakimenko

@TrySound Вот это подход! И отчасти да, это правильно. Потому что я уверен что es6 будет ок. И тогда портировать свои блоки будет проще в 100 раз. И как–бы всегда при деле...

Автар пользователя
vyushin

С точки зрения frontend разработчика я понимаю и в какой-то степени разделяю вашу точку зрения. Но жизнь - это не только frontend. Есть бизнес, маркетинг, перспективы проектов, планирование прибыли и т. д. Это хорошо. Надо работать в команде, иначе не выжить. Если выйти за рамки frontend и кодинга, то на фреймворки можно взглянуть иначе. Фреймворк - это прежде всего comminity, единомышленники, документация, масштабируемость. Фреймворки объединяют людей во всем мире. Это хорошо. Проще найти человека, который уже умеет что-то делать, чем обучать его своим технологиям. Обучение стоит денег, а фреймворки бесплатные и популярные. Целесообразней нанять уже готового специалиста, чем обучать его своему "совершенному коду".

Автар пользователя
vyushin

Если работать в одиночку, то тут конечно хозяин - барин. Фреймворки не ля одиночек. Они для команды.

Автар пользователя
TrySound

@vyushin Так почему бы не использовать коллекцию компонентов внутри команды? Не подключать сразу весь bundle, а по кусочкам собирать, по потребностям)

Автар пользователя
vyushin

@TrySound Хорошее решение. Им пользуются обеспеченные IT компании. Например, среди российских - это Mail.ru Group, yandex. Там для фронтенда используются свои наработки. Это не дешево. :) Не у всех есть столько ресурсов на создания таких вещей... Яндекс сделали БЭМ и популяризируют его. Mail.ru Group используют для фронтента собственный фреймворк т. к. возможностей jQuery, Angular, Backbon и т. д. им не хватает. Свой фреймворк и сборщик фронтенда они не популяризируют. Я по крайней мере не слышал.

У них реально есть ресурсы и время для обучения сотрудников и разработку на высоком уровне. Под ресурсами я подразумеваю время, люди и деньги. Если взять среднестатистическую IT компанию, то таких ресурсов просто не откуда взять... Например, устраивается программист, пишет все с нуля, потом увольняется и что делать? Комментариев в коде нет, документации нет, никакого сообщества нет. Все знания программист уносит с собой. Остальным в этот момент приодится не просто, ведь появляется риск что весь проект встанет и разрабатывать ему будет некому. Даже если это группа разработчиков, все равно не каждый может позволить себе обучать каждого нового сотрудника... Суровые реалии.

Если есть ресурсы, то стремиться к совершенству - это хорошо. Но кушать тоже надо :)

Автар пользователя
TrySound

@vyushin И опять, надо использовать какой-то фреймворк. Я говорю о самодостаточных компонентах на VanillaJS. Нужен аккордион, подключил акктордион, нужно меню - вот и меню.

Автар пользователя
vyushin

@TrySound я понимаю о чем вы. Так, например, делается в ExtJS начиная с 4 версии. Методом define вызывается нужный класс, который подгружается через AJAX. В проекте используется только тот компонент, который реально нужен. Остальной код не подгружается. Это хороший способ разработкию

Автар пользователя
vyushin

Backbone.js к примеру - это всего 1500 строк. Подгрузится при старте страницы и не очень-то заметно. Если у вас десятки тысяч строк кода, тогда конечно желательно делить на модули и собирать.

Автар пользователя
TrySound

@vyushin В простых проектах я просто загружаю через bower библиотечки, галпом конкатенирую, что нужно, перемещаю, правлю пути в css и готово) А другого пока не делал. А насчет Backbone согласен, в умелых руках не будет лишним. Но и его точно так же через bower грузить можно и конкатенировать.