Перестаньте писать 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% того, от чего, по моему мнению, стоит отказаться.

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

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