Код
#статьи

Вернём веб-разработке былое величие

Мы накопили кучу лишних инструментов. Как теперь оптимизировать рабочий процесс, сделать код чистым и красивым, а результат — эффективным?

 vlada_maestro / shutterstock

Джо Хонтон

(Joe Honton)

об авторе

Основатель софтверной компании Read Write Tools, инженер-программист, поклонник open source, технический писатель. Его кредо — писать современный код, не срезать углы, даже если никто этого не заметит, и не добавлять функции, которые могут понадобиться позже.


Ссылки


Каждый фронтенд-разработчик наверняка не раз перестраивал рабочий процесс под новые технологии. Свежие плюшки в HTML, CSS и JavaScript помогают апгрейдить устаревшие методы работы. И это отлично — таким изменениям мы всегда рады. Правда, есть одно но: новинки требуют серьёзно переосмыслить методы работы. А значит, нам каждый раз придётся набивать новые шишки, пробовать и ошибаться.

Тем временем open source проекты и разработчики инструментария для программистов постоянно релизят новые версии своего ПО. Целая индустрия отчаянно пытается не отставать от последних достижений в ключевых технологиях. Для всех, кто имеет дело с кодом, поддержание актуального стека и рабочих инструментов для фронтенд-разработки — это совсем не мелкие разовые усилия.

Так, постойте! А вы вообще помните время, когда всё это не было таким сложным? Когда не существовало препроцессоров, транспиляторов и систем для сборки, на вход которых мы подавали навороченный и модный код, а на выходе получали код с «наименьшим общим знаменателем», который подходит для разных платформ. Когда нам не нужны были автоматизированные системы сборки и программные конвейеры, чтобы сохранить свою адекватность. Когда не нужно было создавать Source Map, только чтобы использовать отладчик без искажённого кода. Когда во фреймворке, с которым мы работаем, не были намешаны все языки подряд. В те времена всё было гораздо проще.

А вы ещё помните, когда нам так прекрасно жилось?

Представляете, недавно я снова получил удовольствие от веб-разработки — просто потому, что научился оптимизировать свой рабочий процесс. Секрет простой: надо просто выкинуть всё лишнее. Теперь я трачу гораздо меньше времени на текучку и больше — на творчество. Расскажу, как я пришел к такой жизни.

Золотая эпоха

За это недолгое время много всего произошло, но наш коллективный разум отчётливо помнит, как мы оказались в своём веб-девелоперском сегодня. Без истории никуда — она критически важна, чтобы понять мои аргументы о том, как упростить рабочий процесс и пофиксить лишнее. Так что заглянем в прошлое.

Всё началось с HTML — без CSS, JavaScript и вот этого всего. Только аскетичный набор тегов, которые помогали структурировать макет, выделять слова и ставить гиперссылки.

Но к HTML быстро подтянулись CSS и JavaScript. Они дали нам возможность исправлять проблемы по частям. И нашим кредо стала декомпозиция проблем:

  • HTML — для смысла и структуры;
  • CSS — для вёрстки и оформления;
  • JavaScript — для интерактива.

Но это был не идеальный мир. Пришлось бороться с несовместимостью браузеров. Поначалу мы игнорировали эти различия и просто вставляли в футере каждой веб-страницы предупреждения: «Лучше всего открывать в Internet Explorer». Мы как бы просили пользователей, чтобы они позаботились о себе самостоятельно.

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

Эпоха библиотек

А вот когда мы начали вовсю использовать JavaScript, всё сильно запуталось. Сперва доставила немало хлопот несовместимость браузеров. Потом мы учились делать AJAX-вызовы и споткнулись о кривую обучения — асинхронное программирование против синхронного. Представляете, нам приходилось делать это с помощью document.getElementById (). А после всех этих мучений мы открыли для себя JQuery и больше никогда не оглядывались назад.

Библиотека JQuery принесла нам освобождение от браузерных войн, дала единый интерфейс, который нивелировал несовместимости. У нас впервые появилась возможность зарелизить код и спокойно ожидать: «Вот, сейчас придут пользователи и будут наслаждаться тем опытом, который мы для них спроектировали».

Сегодня мы содрогаемся при одной только мысли о том, что придётся использовать JQuery, но в то время от него некуда было деться. Хочу отметить, что свой легендарный статус JQuery получила не автоматически — эта библиотека отвоевала своё место под солнцем в жестокой схватке с open source решениями вроде MooTools, Dojo и YUI.

У конкурентов JQuery была куча дополнительных функций и вариантов дизайна пользовательского интерфейса — такие швейцарские ножи от библиотек. JQuery пошла другой дорогой — осталась чётко сфокусированной и не распылялась на универсальные функции.

У JQuery была одна крутейшая фича: библиотека расширяла ограниченные возможности метода document.getElementById (), а потом использовала их вместе с набором функций-обёрток, которые убирали различия DOM разных браузеров. Наконец, она сделала XMLHttpRequest простым в использовании, открыв для множества разработчиков прекрасный новый мир асинхронного программирования.

И вдруг простых обратных вызовов onclick стало уже недостаточно, интерактивность перестала казаться горячей новинкой, и пользователи потянулись на сайты с динамическим контентом. Так умерло движение <noscript> — даже не успев родиться, а фразочки типа «ненавязчивый JavaScript» и «изящная деградация» быстро потеряли популярность. Работа с DOM перестала быть необязательной, и всё это прочно укоренилось в наших профессиональных обязанностях.

Сегодня JQuery считается «легаси» только потому, что её первоначальная крутейшая фича была включена прямо в DOM через document.querySelector (). Вторая же по популярности фича, $.ajax (), была вытеснена стандартизированным API Fetch. Всё, что раньше можно было сделать только в JQuery, теперь можно сделать на JavaScript — и с точно таким же количеством строк кода.

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

Эпоха препроцессоров

Когда HTML и DOM развивались, заказчики услуг по веб-разработке всё настойчивее требовали утончённого стиля. И какое-то время этот запрос можно было удовлетворять, просто сделав страничку немного интерактивной. Adobe Flash помог нам закрыть потребность в красоте — мы начали добавлять Flash-анимацию на главные страницы клиентских сайтов.

Но совсем скоро в стандарте CSS появились две самые популярные функции Flash: переходы и анимация. Потом новые теги из стандарта HTML5: <canvas>, <audio> и <video> окончательно отобрали работу у оставшихся фишек Flash. В тот момент проприетарный Flash стал не особо-то и нужен, а многочисленные уязвимости лишь ускорили его смерть.

Нашим лучшим другом стал CSS — мы играли с градиентами на фоне, скруглением углов и тенями. А потом, словно безумцы, начали писать всё больше и больше кода CSS — для компоновки макета, украшения страницы, типографики — пока каскадные таблицы не вышли из-под контроля и нам не потребовалась помощь.

Прошло время, и мы поняли: нужно объявлять переменные в CSS. Например, чтобы настроить цвета и значения разных тем в одном месте и применить эти настройки во всех таблицах стилей. Поэтому мы перешли на препроцессоры, такие как Less и Sass. Они смогли дать нам это.

Таблицы стилей становились всё сложнее, и нам пришлось научиться организовывать все правила в отдельные файлы — чтобы изолировать друг от друга их контекст и снизить количество конфликтов имён. Мы начали полагаться на директиву @import препроцессора — она помогала объединить все файлы и правила. А сделав это, мы приняли препроцессоры как неотъемлемую часть своей работы.

Из-за этой безобидной, на первый взгляд, предварительной обработки мы и встали на ту скользкую дорожку, по которой идём до сих пор. Мы больше не имели права просто ввести URL в адресной строке браузера и кликнуть по кнопке «Обновить». Нет, теперь мы просто обязаны были создать свой сайт.

Однако стандарты W3C эволюционировали и опередили возможности Less и Sass:

  • CSS позволяет объявлять и использовать переменные. Например, --width: 40rem.
  • CSS позволяет вычислять величины. Например, calc (var (--width)+2rem).
  • CSS позволяет изолировать контекст и предотвращать конфликты имён внутри компонентов с помощью селекторов: host и: slotted.
  • CSS позволяет организовывать правила с помощью директивы @import.

И для этого больше не нужны препроцессоры. Всё зиждется на стандартах и призвано привести нас в светлое будущее.

Теперь в новых проектах надо семь раз подумать, а стоит ли вообще заморачиваться с Less и Sass. Выкинув их из технологической цепочки, мы можем объявлять чёткий набор необходимых правил — в чистом виде, без всяких дополнительных инструментов.

Эпоха стандартов

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

Тогда же Apple, Mozilla и Opera решили, что хватит внедрять инновации и раздувать ненужную конкуренцию на ровном месте. Они стали совместно разрабатывать стандарты и создали рабочую группу по гипертекстовым веб-технологиям для приложений (WHATWG, Web Hypertext Application Technology Working Group). Вскоре к ним присоединились Microsoft и Google. Так родился стандарт HTML5.

До этого разработка стандартов шла очень медленно. Например, CSS2 вымучивали много лет, а улучшений в этом стандарте почти и не было. HTML4 пилили ещё дольше, а в итоге родили монстра с мешаниной из строгих правил, компромиссных костылей и фреймов.

Мудрые разработчики браузеров понимали: «Любые попытки устранить различия должны идти в ногу с инновациями; затормаживать развитие стандартов — значит подрывать веб».

WHATWG совершенно по-новому стала относиться к инновациям и стандартам — они смотрели на них как на живые, динамичные стандарты. То есть вместо единой всеобъемлющей спецификации начали выпускать отдельные документы, которые охватывали разные части технологий. Например, стандарт HTML5 — это набор мини-стандартов. В итоге «HTML5 и его друзья» охватывают сам ​​HTML, а также отладку, DOM, выборку, потоки, хранилище, веб-сокеты, веб-воркеры и ещё много всего.

Концепция живых стандартов оказалась настолько практичной, что была принята Консорциумом Всемирной паутины (W3C) в работе над новыми стандартами CSS. Итог — состоящий из множества блоков стандарт CSS3, в который входят: цвета, шрифты, селекторы, фон, границы, многоколоночный макет, правила отображения страниц в зависимости от устройства и так далее. У каждого из этих блоков свой, независимый от других, цикл обновления стандартов.

Вслед за W3C такой подход применила и ECMA International — во время разработки ECMA-262, очередного стандарта JavaScript. Они переформулировали свои амбициозные планы по глобальному обновлению языка с точки зрения «гармоничного» подхода. С тех пор функции просто добавлялись в стандарт по мере появления, поэтому с 2015 года мы ежегодно получаем набор новых возможностей JavaScript.

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

В то время новые функции HTML, CSS и JavaScript анонсировали ежемесячно. И наш аппетит разгорался всё сильнее — нам нравилось то, что мы слышали, и мы хотели получить это как можно скорее. Даже раньше, чем это могли реализовать разработчики браузеров. И снова всё стало сложно.

Чтобы обскакать конкурентов, мы начали использовать в кодовой базе обнаружение функций и полифиллы. Благодаря этому мы могли определить, какие функции поддерживаются браузером, а какие нужно «имитировать» с помощью альтернативных решений и «костылей». Так родилась философия прогрессивного улучшения: изменение уровня сложности кода в зависимости от ограничений браузера. Но этот подход был оправдан лишь в небольшом количестве задач.

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

И вот, после всех этих бурных лет, расцвет новых функций JavaScript сходит на нет. Регулярное появление новых «обязательных» возможностей, свидетелями которых мы стали, уже почти застопорилось. Ведь у нас уже есть современный мультипарадигменный язык с модулями, классами, итераторами, генераторами, стрелочными функциями, двоичными данными, функциями map и set, объектами promise, шаблонными литералами, деструктуризацией, async/await, res/spread и кучей всего остального.

Самый большой прирост производительности многим из нас обеспечил выход за пределы многочисленных вложенных замыканий. Благодаря нативным объектам promise и синтаксису async/await. JavaScript полностью поддерживает асинхронное программирование, и этот процедурный стиль довольно прост и приятен.

Сегодня транспилеры уже практически не нужны. Все функции языка, необходимые для написания чистого кода, доступны из коробки. И мы можем писать код, используя несколько парадигм: функциональное, объектно-ориентированное и императивное программирование — без всяких транспилеров.

Не удержусь и сделаю последнее замечание о транспилерах, прежде чем мы двинемся дальше. Если вы предпочитаете TypeScript, то удалить Babel из своего рабочего процесса можно. Но нужно не забывать про tsc, чтобы преобразовать исходный код в браузерно-совместимый JavaScript.

Эпоха модулей

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

Этот гордиев узел разрубили require и module.exports. Появилось несколько решений с открытым исходным кодом, самые популярные из них — RequireJS и Browserify. К сожалению, эти решения были несовместимы, поэтому разработчикам библиотек приходилось выбирать, какой синтаксис использовать для своей кодовой базы (AMD или CommonJS), а разработчики приложений должны были либо делать то же самое, либо отслеживать различия с помощью UMD (Universal Module Definition).

Когда на проблему обратил внимание Технический комитет ECMA (TC39), казалось, что всё наконец-то наладилось. Комитет глубоко вник в задачу и предложил новые ключевые слова для JavaScript. Они предложили использовать определения import и export в загрузчике модулей, который в итоге назвали ESNext.

Но оказалось, что загрузить модули было не так-то просто. Правильное управление зависимостями, работа с циклическими зависимостями и обработка асинхронной загрузки — всё это были нетривиальные проблемы. Одно дело — заставить загрузчик модулей работать в Node.js, и совсем другое — в браузере.

Но разработчики интерфейсов не могли ждать, пока создатели браузеров решат эти проблемы. Модули нам нужны были немедленно, прямо сейчас. К счастью, решение было легкодоступно — мы просто писали код с новым синтаксисом ESNext, а потом преобразовывали его в CommonJS с помощью того же Babel. Такой подход сработал.

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

Эпоха бандлеров

Как видно, набор инструментов с годами только усложнялся. Поэтому мы решили оптимизировать рабочий процесс и начали использовать средства автоматического запуска задач вроде Gulp и Grunt, а также сборщики — Browserify, Rollup и Webpack. Если их правильно настроить, они отслеживают изменения в файлах и автоматически запускают процесс преобразования:

  • Sass и Less предварительно переводятся в CSS.
  • Современный синтаксис JavaScript трансформируется в ES5.
  • Модули ESNext переупаковывают в модули CommonJS.
  • Линтеры проверяют код на типичные ошибки.
  • Комментарии и пробелы удаляются с помощью минификаторов.
  • Создаются исходные карты отладки, чтобы связать получившийся код с исходным.
  • Всё объединяется в бандлы для эффективной передачи HTTP/1.1.
  • Большие бандлы делятся на маленькие, чтобы оптимально кэшироваться в сети.

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

  • Препроцессоры можно забыть, если мы используем новейшие функции CSS.
  • Современный JavaScript поддерживается браузерами без транспиляции.
  • Модули ESNext можно использовать по умолчанию и без загрузчиков модулей.
  • Стандартное кэширование HTTP делает ненужным разбивку бандлов.
  • Передавать файлы по протоколу HTTP/2 гораздо быстрее, чем с помощью сборщиков модулей.

Правда, бандлы по-прежнему работают быстрее, чем несколько небольших файлов, если на вашем сервере используется HTTP/1.1. И чтобы извлечь максимальную пользу, надо переключиться на новый сервер с постоянными подключениями и кэшированием.

Теперь у нас остались только линтеры и минификаторы. Но их не нужно запускать во время тестирования каждого мелкого изменения, мы просто можем включить их в финальные сценарии развёртывания. А раз так, то уже можно избавиться и от сборщика пакетов.

Вуаля! Мы упростили рабочий процесс — нам нужны только редактор кода и браузер. Вносим изменения в код, нажимаем кнопку «Обновить», и вот он — наш новый код в действии. Ну разве не прелесть?

Эпоха фреймворков

По сути, новый подход к фронтенд-разработке — это просто возвращение к нашим корням: HTML, CSS, Javascript, философия разделения проблем. Но выдержит ли он проверку суровыми требованиями к современным сайтам? Это зависит от архитектуры вашего проекта.

Увлечение фреймворками делает такой минималистичный подход недоступным для многих команд. На тренды разработки облачных приложений сильно повлияли несколько известных фреймворков: Angular, React, Vue и Svelte — они де-факто стали стержнем многих интерфейсных проектов.

Например, React использует виртуальную модель DOM, пытаясь из процесса написания кода сделать упражнения в декларативном программировании. Программист уже не влияет напрямую на обработку событий, манипулирование атрибутами и взаимодействие с DOM — это делается с помощью фонового преобразования. Чтобы использовать React декларативно, большинство разработчиков пишут операторы на JSX — смеси JavaScript и XML. А поскольку браузеры ничего не знают о JSX, его нужно перевести в JavaScript с помощью нашего старого знакомого — Babel.

Можно сказать: «Есть же Angular, он не использует какие-то нестандартные штуки вроде JSX». Да, но в нём используются шаблоны литералов. В этих шаблонах задействованы HTML и специфические атрибуты, обёрнутые в фигурные скобки. Перед отправкой в ​​браузер шаблоны Angular приходится компилировать с помощью ng build в режиме командной строки в инкрементные операторы DOM.

Vue тоже использует литералы шаблонов, чтобы писать HTML со встроенными выражениями в фигурных скобках. Их, опять же, приходится компилировать во что-то понятное браузерам. Большинство проектов на Vue использует либо vue-template-compiler, либо её Webpack-оболочку — vue-loader.

Svelte использует шаблоны литералов, похожие на шаблоны Vue. Он тоже компилируется не в момент выполнения, а на этапе сборки, которую делают с помощью svelte.compil или её Webpack-оболочки svelte-loader.

Итог: проекты на React, Angular, Vue или Svelte не подходят для радикальной оптимизации рабочего процесса, когда используются только редактор кода и браузер.

Эпоха компонентов

А вот революция компонентов, которую начали WHATWG, позволит перейти на связку «редактор — браузер». Когда мы разрабатываем компоненты, опираясь на стандарты W3C, то получаем все преимущества минималистичного рабочего процесса.

Тем, кто заинтересован в таком подходе к веб-разработке, стоит изучить следующие технологии:

  • Пользовательские элементы (Custom elements);
  • Shadow DOM;
  • HTML-шаблоны.

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

А если вы ещё не верите, что этот подход работает, загляните на сайт Blue Fiddle и посмотрите, как его бэкенд работает с API сервера. Сайт сделан с помощью IDE, языка шаблонов BLUEPHRASE и Chrome DevTools.

И пока вы там, обязательно загляните под капот — вы увидите чистый и красивый код. Его легко читать, радостно писать и невозможно забыть.

Онлайн-школа для детей Skillbox Kids
Учим детей программированию, созданию игр, сайтов и дизайну. Первое занятие бесплатно! Подробности — по клику.
Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована