О статике

2017-01-08

Веб меняется.

Web

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

Со стороны сервера эти самые HTML, CSS и JS являлись файлами. Прямо руками создавались файлы. Прямо в HTML или CSS разметке. И заливались через FTP на сервер. Это была исключительно статика.

Но конечно же очень скоро захотелось динамики. У нас же есть формы. А формы надо куда-то сохранять. И какие-нибудь результаты или даже отчёты надо отображать.

Динамика появилась сначала в виде CGI. Довольно быстро основным языком для написания CGI-скриптов стал Perl. А вскоре и PHP подоспел.

Быстро оказалось, что CGI — это не очень эффективно — плодить по процессу на каждый запрос. И самый популярный тогда веб сервер Apache быстренько обзавёлся модулями для интерпретации и Perl, и PHP, чтобы выполнять скрипты прямо в процессе веб сервера. Именно тогда появилась аббревиатура LAMP.

LAMP

CGI-скрипты были именно скриптами. По одному скрипту на каждый запрос. И такая структура была унаследована и в PHP. Бэкенд становился всё сложнее, требовались какие-то средства организации кода. В те времена PHP4 каждый пэхэпэшник рисовал свой фрэймворк, организующий .php файлы и загружающий только нужные.

Несколько организованней всё происходило в мире Java. Там с самого начала были сервлеты — отдельные классы для обработки запросов. И механизмы маппинга запросов на эти самые сервлеты. Можно было прилично всё организовать: классы бизнес-логики — на старой доброй Java, и всё это для веба слегка прикрыто сервлетами.

Правда, испугавшись популярности PHP, ребята запилили JSP. Все тогда пилили свои Server Pages, на которых можно было говнякать, как на PHP, смешивая в одних файлах и обращение к базе данных (о, я помню mysql-escape-string() и mysql-real-escape-string()), и бизнес-логику, и формирование HTML.

Важно, что вся эта динамика возвращалась с сервера в виде HTML. А так как на солидных порталах без динамики не может обойтись ни одна страница (имя залогиненного юзера в меню показывать), весь HTML генерировался бэкендом. Из статики остались только CSS и JS, ну и картинки, конечно.

Понятное дело, чтобы как-то организовать код на бэкенде, придумали много разных вещей. Например, MVC — Model-View-Controller, чтобы отделить то, что зависит от предметной области — модель, от того, что является спецификой веба — контроллер, и от того, что является исключительно представлением — вьюхой. Но вьюха по-прежнему создаёт HTML разметку.

MVC

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

Самый известный сейчас, пожалуй, — это Markdown. В нём можно писать так, что и текст в простом тексте (т.е. «исходники» маркдауна), и текст в «богатом» варианте (например, в HTML) выглядят одинаково читабельно и красиво. Вот только в Markdown можно представить только простую разметку, для текста, даже на таблицы стандарта нет.

А недавно я познакомился с Pug, он же PugJS, ранее известный как Jade. Дурацкое название, что новое, что старое, гуглить приходится «pug/jade». Вот это уже полноценный язык шаблонов для иерархических структур, типа HTML или XML. Вложенность тегов изображаем вложенностью элементов. Да, Pug — это ещё один язык (разметки), чувствительный к отступам. Сразу предупреждаю.

Потом появился Node.js. Внезапно оказалось, что те, кто писал свистелки и перделки на JavaScript, могут сами для себя и сервер написать. Но с его приходом пока что мало что поменялось. Express — это, в чистом виде, такая же низкоуровневая штука, как сервлеты. Вот вам запросы, обрабатывайте их как хотите. Можно и HTML по шаблонам генерить.

Серьёзное изменение произошло с появлением AJAX, задолго до всяких Ноджээс. Оказалось, что не обязательно серверу возвращать всю динамику в виде целой HTML страницы. Сначала оказалось, что кусочки этой страницы можно подгружать отдельными запросами. Потом оказалось, что не обязательно возвращать HTML. Пусть приходит какой-нибудь JSON, а мы уж тут, в JavaScript, прямо в браузере, разберёмся, куда эти данные запихнуть в DOM дерево.

AJAX

И если раньше веб-разработчик занимался всем: и схему БД делал, и бизнес-логику писал, и HTML верстал, и CSS стили натягивал, и JS рисовал (как попало, до появления jQuery). То теперь между фронтендом и бэкендом пролегла чёткая граница.

Бэкенду осталась персистентность, работа с БД, и API для доступа к данным. Фронтенду досталась вся красота, видимая пользователям. Веб стал веб-приложениями, запускаемыми в браузере и общающимися с API.

Примечательно, что это API может быть использовано не только веб-приложениями, но и мобильными приложениями, десктоп приложениями (которые тоже всё чаще становятся внутри веб), и даже сторонними сервисами.

Также примечательно, что подразумевается чаще всего RESTful API. Происходит это от сосредоточенности на данных, ведь REST — это доступ к данным. Причём данным предметной области. Этим RESTом всё настолько пропитано, что инструменты документирования API, вроде Swagger, даже не подозревают, что через HTTP можно просто пересылать JSON или XML документы, без привязки типа документа к пути в URL.

REST

На самом деле, для веба, мобилки и десктопа в общем случае нужны разные API. Как минимум потому, что на одном экране мобилки помещается меньше данных, чем на одной веб-странице. В идеале хочется, чтобы на одну страницу был бы один запрос на сервер, который бы вернул все данные, необходимые для отображения данной страницы. А раз данные разные для мобилки и веба, то и запросы, и API должны быть разными. И REST тут тоже будет только мешать, ведь мы хотим в один запрос вместить совершенно разнообразные данные. Это должна быть просто пересылка сообщений через HTTP.

Так вот, у нас получается один сервер исключительно для динамики, для API. Но веб-приложение — это HTML, CSS и JavaScript. Это — статика. В том смысле, что для браузера это статичные файлы, пусть и создающие динамическое веб-приложение. Нужен ещё один сервер для раздачи статики.

Ну и саму эту статику, фронтенд веб-приложения, никто уже не пишет на голом HTML, CSS и JS. Для HTML есть шаблоны, тот же Pug или JSX. Для CSS есть всяческие препроцессоры и постпроцессоры: SASS и LESS — по сути отдельные языки (более удобные?) для описания стилей. Для JS тоже есть альтернативные представления, вроде TypeScript или CoffeeScript. К тому же стало модно транслировать популярные языки программирования общего назначения в JS представление, чтобы кодить и под веб.

Само собой, появились и фреймворки. Весьма мощные. Вы их знаете: Angular и React (упомянутый выше JSX есть часть ReactJS).

Angular vs. React

Настолько всё изменилось в мире фронтенда, что это дело понадобилось собирать. Тут, внезапно, снова пригодился Node.js. Всякие прелести стали паковать в NPM модули, даже CSS. Появился свой собственный инструмент сборки, работающий в Node. Да сильно не один: Grunt, Gulp, Webpack... Тысячи их. Хипстотометр зашкаливает.

В общем, статика рулит вебом. Никому не интересны эти ваши бэкенды и API. API можно и заглушкой заделать, или в Firebase мышкой натыкать. А вот на чём мы будем фронт делать? И чем это дело будем собирать?

С другой стороны, есть у меня сайт на PHP. Где из всех конструкций PHP используется только include. Зачем ему быть динамичным, если это всё статичный HTML? Ведь можно взять все эти шаблоны, генераторы, билдеры и сгенерировать статику. Нефиг руки HTML тегами марать.

Есть ещё сайты, в которых нет ни одной формы, одно только содержание. Вот я и побаловался. Ради снижения уровня хипстоты нарисовал генераторы страничек на Python. Pug для шаблонов (как ни странно, через Mako). Markdown для контента. Получилось. Даёшь генерацию статичных сайтов!