Разработка фронтенд-приложений
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  Разработка фронтенд-приложений

 


 

Антон Кузьмин

Разработка фронтенд-приложений. — СПб.: Питер, 2025.

 

ISBN 978-5-4461-4272-9

© ООО Издательство "Питер", 2025

 

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

 

Введение

Что вам даст эта книга

Вы научитесь проектировать и реализовывать фронтенд-приложения 3RApp, вести совместную работу по код-ревью, изучать существующие приложения. Разберетесь с библиотеками React, React Router и Redux Toolkit. По-новому взглянете на React и научитесь разрабатывать с бо́льшей легкостью. Познакомитесь с основной идеей браузера. Узнаете, как располагать компоненты приложения в файлах и папках и почему именно так. А еще — как использовать нейросети для ускорения разработки.

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

Наверняка вы не доверяете всем подряд — и правильно делаете. Тогда почему вы должны доверять автору книги? Конечно, за годы становления IT-сферы ей посвятило время множество людей, имена которых сегодня были бы неизвестны, если бы не их открытия и публикации. Кто-то сформулировал принципы, кто-то ввел повторяющиеся способы решения задач, кто-то создал целые области и направления. Без практического применения знаний подобное немыслимо. Поэтому данная книга полностью построена на практике. Это не скомпилированный1 и не перефразированный материал, а итог реальных достижений. Автор — действующий лидер команды разработчиков в одной из известных организаций.

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

Для кого написана эта книга

Книга написана для тех, кто уже знаком с языком программирования JavaScript (JS) и хотел бы войти во фронтенд-разработку, а также подтянуть свои знания в этой области.

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

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

Кратко о главах книги

Глава 1 «Фронтенд-разработка» представляет собой ознакомительное введение в разработку фронтенд-приложений. Вы узнаете, из каких элементов она состоит на уровне предприятия. В англоязычной среде это называется enterprise.

Глава 2 «С чем имеет дело фронтенд-разработчик» вобрала в себя разрозненные темы, являющиеся базовыми составляющими разработки. Начнем с того, что можно создать на JavaScript. Затем рассмотрим, какую функциональность дает конкретная платформа, подробно изучим браузер и асинхронное написание программы. Здесь же будет раскрыт принцип работы UI-библиотек.

Глава 3 «Основы проектирования и разработки» раскрывает основы, на которых строится создание приложений: как появляется продукт в организациях, как применять графы для моделирования и свободно понимать составляющие приложений. Кроме того, дан обзор проектирования и разработки, включающей в себя не только написание кода.

Глава 4 «Состояние» знакомит с базовыми принципами работы библиотек Redux и Redux Toolkit, а также с их составляющими и правилами применения библиотек в коде приложения.

Глава 5 «UI» знакомит с основными элементами библиотеки React и правилами ее использования в коде приложения. Компоненты рассмотрены не только как статические единицы, но и во взаимодействии. Другие составляющие библиотеки раскрыты детально. А в конце главы, в разделе «Новый взгляд на React», собрана по-настоящему важная информация. С этой главы начинает формироваться профессиональный взгляд на приложение.

Глава 6 «Управление рендерингом компонентов с помощью изменяющегося URL» описывает ключевые этапы работы библиотеки React-Router-Dom (React Router), ее составляющие и правила ее применения в коде приложения. Эта глава учит создавать приложения любой сложности и задавать в коде компоненты, зависящие от пути в URL любой длины.

Глава 7 «Файлы приложения» учит организовывать файлы приложения. Здесь раскрыт способ расположения элементов приложения в файлах и папках, который позволяет быстро понять, с чем имеет дело тот или иной элемент приложения. Будет очень кстати знание материалов из предыдущих глав.

Глава 8 «Разработка фронтенд-приложения» полностью строится на информации предыдущих глав и раскрывает, как осуществить проектирование для 3RApp, а также какие области к этому относятся. Она знакомит с процедурой проектирования 3RApp (кстати, впервые описанной именно в литературе по фронтенд-разработке) и процедурой реализации. В ней впервые представлена последовательность создания компонентов и напоследок — основы использования нейросетей для ускорения разработки. Ведь эта книга о современной фронтенд-разработке.

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

Глоссарий — это список терминов, используемых в книге.

Последовательность чтения глав

Знакомство с каждой темой, относящейся к фронтенд-разработке, может проходить по-разному. Глубина погружения в ту или иную тему тоже у каждого своя. Например, с DOM связано множество объектов и методов. У всех разный опыт работы с ним, а также чтения информации по нему. Один разработчик мог ничего не читать о DOM, но взаимодействовать с объектами и методами в коде. Другой только читал. Третий и читал, и взаимодействовал. Трудно предсказать, какой у читателя уровень владения темами, изложенными в книге. Поэтому каждая тема описывается как незнакомая или малознакомая.

Я разделил читателей на группы в зависимости от имеющегося опыта и уровня подготовки и могу дать следующие рекомендации.

Всем читателям. Начав читать главу, просмотрите ее разделы. Если тема конкретного раздела вам знакома, пропускайте его и переходите к следующему. Однако если вы не уверены в своих знаниях, пробегитесь по разделу — возможно, есть что-то, с чем вам еще не приходилось сталкиваться.

Начинающим фронтенд-разработчикам. Рекомендую последовательно изучать главы книги.

Практикующим фронтенд-разработчикам. Я рекомендую более сложную последовательность действий.

• Главы 1 и 2 — просмотреть и, если найдется что-то, с чем не сталкивались, ознакомиться.

• Глава 3 — ознакомиться, особенно если разделы 3.2–3.4 вызывают вопросы.

• Главы 4, 5 и 6 — просмотреть названия разделов. Вероятно, возникнет желание в чем-то лучше разобраться. Обязательно изучить раздел 5.19, где представлена абсолютно новая информация. И скорее всего — полностью главу 6.

• Глава 7 — обязательно ознакомиться.

• Глава 8 — обязательно ознакомиться. Подобный материал для фронтенд-разработки публикуется впервые.

• Глава 9 — желательно ознакомиться.

• К глоссарию можно обращаться периодически за разъяснением того или иного слова.

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

TypeScript

Разработка уровня энтерпрайз2 ведется на языке TypeScript, но в книге для целей обучения используется JavaScript. Это сделано намеренно. TypeScript включает в себя типы и дополнительные элементы языка, без знания которых трудно читать код примеров и тем более самостоятельно писать код. Может получиться такая картина: вы полны энтузиазма написать код задания, но сталкиваетесь с банальной проблемой языка TypeScript и вместо того, чтобы решать задачу, начинаете разбираться с ней. В итоге вы зря тратите время, злитесь и через пару примеров все бросаете. Использование же JavaScript исключает борьбу с неожиданными и неизвестными проблемами.

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

Как читать эту книгу

Пытайтесь вникать в идеи. Если что-то не поняли сразу, разберитесь. Разобраться — значит понять все составляющие.

Точно не нужно запоминать. Если поймете прочитанное, то вам будет легко этим пользоваться. Самый правильный способ изучения таков: прочитать, понять и сразу попробовать использовать. У вас будет достаточно упражнений и практических заданий.

Упражнения ориентированы на тренировку нового — вы повторяете только что изученное в коде. Через них я, автор книги, веду вас к усвоению материала. Практические задания подразумевают самостоятельную работу и нахождение решения, когда нужно создать код или что-то смоделировать в виде изображения, а главное — применить пройденный материал. Они составлены так, что их нельзя выполнить бездумно. Это сделано намеренно — чтобы определить, понят материал или нет. Если вы не можете выполнить упражнение, значит, есть момент, в котором не разобрались. Либо необходимо повторить попытку. В любом случае если вам не удается сделать практическое задание сейчас, то в будущем наверняка возникнут аналогичные сложности с этой темой — пока вы не разберетесь по-настоящему.

В книгах по IT-технологиям используются разные подходы. Я предлагаю такой. Одна область разработки — это глава. Глава делится на разделы. Раздел — отдельная тема. Например, глава «UI» рассказывает о React, а «Формы» и «Эффекты» — разделы, где описываются конкретные вещи.

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

1. Вы изучаете один раздел.

2. Открываете упражнения, приведенные после раздела, и тренируете конкретные моменты.

3. Выполнив упражнения, открываете практические задания и выполняете их.

Поскольку у разных разработчиков не бывает одинаковых решений, к практическим заданиям я предлагаю свои решения. Все честно: вы получаете не только (и не всегда) трудную задачу, но и вариант ее решения.

Скачать материалы можно из следующих репозиториев GitVerse:

• упражнения: https://github.com/3RApp/drills;

• практические задания: https://github.com/3RApp/problems;

• ответы к практическим заданиям: https://github.com/3RApp/answers;

• код, иллюстрируемый в книге: https://github.com/3RApp/code.

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

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

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

Что делать, если не удается приступить к выполнению упражнения или практического задания? Вам нужно еще раз посмотреть материал раздела, а именно — то место, на разработку которого направлено упражнение или практическое задание. Раз возникает трудность в применении, есть что-то, что вы не до конца усвоили. Однако если вы чувствуете, что понимаете и можете делать задание, пусть медленно, то просто продолжайте — медлительность появляется из-за слабого владения темой. Упражнения и практические задания как раз помогут ускориться. Иногда ускорение происходит прямо в момент выполнения задания, поскольку приходит понимание.

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

Цель этой книги — дать людям возможность понять фронтенд-приложения и научить легко ориентироваться в их создании с нуля или доработке уже существующих. Для этого даются базовые знания, в том числе о современных библио­теках и подходах. Я не стремлюсь сделать так, чтобы вы запомнили, как писать код с использованием библиотек, а хочу, чтобы в России фронтенд-разработчики подходили к созданию приложений с бо́льшим пониманием. Удалось мне это или нет, судить вам — читателям.

Почему упражнения и практические задания отделены от изучаемого материала

Почему выбрана такая последовательность действий:

1) знакомство (чтение материала);

2) упражнение в применении;

3) практическое задание?

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

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

Переход к упражнениям важен тем, что после изучения материала у вас появляется возможность соотнести собственные мысли с тем, как реализовать (выразить) понимание в виде текста программы. Иногда, пока он не написан, картина не складывается и понимание не приходит. Без чтения вы тоже не смогли бы найти решение.

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


1 Компилировать — делать компиляцию (в информатике это слово имеет другое значение, здесь приведено обычное, литературное). Компиляция (от лат. compilatio, букв. — «ограб­ление») — составление сочинений на основе чужих исследований или чужих произведений (литературная компиляция) без самостоятельной обработки источников; работа, составленная таким методом.

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

Разработка уровня энтерпрайз2 ведется на языке TypeScript, но в книге для целей обучения используется JavaScript. Это сделано намеренно. TypeScript включает в себя типы и дополнительные элементы языка, без знания которых трудно читать код примеров и тем более самостоятельно писать код. Может получиться такая картина: вы полны энтузиазма написать код задания, но сталкиваетесь с банальной проблемой языка TypeScript и вместо того, чтобы решать задачу, начинаете разбираться с ней. В итоге вы зря тратите время, злитесь и через пару примеров все бросаете. Использование же JavaScript исключает борьбу с неожиданными и неизвестными проблемами.

Компилировать — делать компиляцию (в информатике это слово имеет другое значение, здесь приведено обычное, литературное). Компиляция (от лат. compilatio, букв. — «ограб­ление») — составление сочинений на основе чужих исследований или чужих произведений (литературная компиляция) без самостоятельной обработки источников; работа, составленная таким методом.

Наверняка вы не доверяете всем подряд — и правильно делаете. Тогда почему вы должны доверять автору книги? Конечно, за годы становления IT-сферы ей посвятило время множество людей, имена которых сегодня были бы неизвестны, если бы не их открытия и публикации. Кто-то сформулировал принципы, кто-то ввел повторяющиеся способы решения задач, кто-то создал целые области и направления. Без практического применения знаний подобное немыслимо. Поэтому данная книга полностью построена на практике. Это не скомпилированный1 и не перефразированный материал, а итог реальных достижений. Автор — действующий лидер команды разработчиков в одной из известных организаций.

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

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (­издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

Глава 1. Фронтенд-разработка

1.1. С чего начиналась фронтенд-разработка

1.1.1. Осознание способов решения проблем

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

На заре становления интернета не существовало понятия «фронтенд-приложение». Был термин, вошедший в лексикон, — «клиент-серверное3 приложение». Чуть позже, когда мы рассмотрим исторические стадии развития функциональности, станет понятно, что такое фронтенд-приложение. Инструменты для его разработки тоже появились со временем.

В эволюции приложений можно выделить три крупных этапа:

• приложения на основе веб-страниц;

• приложения на основе AJAX и библиотек;

• приложения, создаваемые с помощью инструментов и декларативных биб­лиотек.

1.1.2. Приложения на основе страниц

Самые первые приложения — это клиент-серверные приложения, которые назывались сайтами4. По сравнению со страницами в браузере они были настолько простыми, что скорее представляли собой электронные книги и каталоги. Да, они были функциональными, но функциональность обеспечивалась не за счет задействования языка JavaScript и работы с DOM5, а за счет приложения, которое функционировало на сервере. DOM в том виде, в каком мы знаем ее сегодня, появилась в результате постепенного развития. Движение с одной страницы сайта на другую осуществлялось путем перехода по ссылке. Предыдущая страница выгружалась из браузера, а новая загружалась. То есть происходила полная перезагрузка страниц. Да, использовалась оптимизация запрашиваемых ресурсов —некоторые из них загружались из кэша, но то была оптимизация трафика для сервера. На клиенте все время происходила перезагрузка. В то время клиент-серверное приложение в виде сайта старались разукрасить или сделать как можно более функциональным за счет серверного приложения.

1.1.3. Приложения на основе AJAX и библиотек

AJAX не конкретная технология, а набор технологий, каждая из которых развивается сама по себе.

Чтобы не перечислять все, что предлагалось для использования в AJAX, и не превращать объяснение в доклад о технологиях прошлого, я дам простое определение. Можно сказать, что AJAX подразумевает использование JavaScript в браузере, чтобы обмениваться с сервером данными в формате XML с помощью объекта браузера XMLHttpRequest.

Название AJAX — это первые буквы слов в словосочетании Asynchronous JavaScript And XML, что переводится как «асинхронный JavaScript и XML».

Авторы некоторых книг по JavaScript негодуют из-за присутствия XML и в названии XMLHttpRequest, и в AJAX. Однако появление именно XML вполне оправданно. Какой еще способ представления данных можно было выбрать в начале 2000-х годов? Напомню, что формат JSON Дуглас Крокфорд, можно сказать, «придумал» в 2002 году.

Приложения, которые задействовали подход AJAX, уже не перегружались при каждом взаимодействии пользователя со страницей. Это создавало положительный пользовательский опыт и в целом увеличивало скорость работы клиент-серверного приложения за счет уменьшения трафика6. Однако с точки зрения фронтенд-приложения сами приложения, за редким исключением, были основаны на прямой работе с DOM и CSS. DOM браузеров на заре становления интернета не была реализована по единым стандартам, как мы можем видеть это сегодня. И даже сегодня наблюдаются расхождения со стандартом W3C7. А в 2006 году появление библиотеки jQuery осуществило прорыв в скорости создания веб-приложений. Библиотека предлагала множество методов для работы с DOM и AJAX, но главное — разработчикам больше не надо было беспокоиться о разности в реализации DOM в браузерах.

Чуть раньше, в 2005 году, появилась библиотека Prototype.js, которая, пусть и в гораздо меньшей степени, предлагала функции для работы с AJAX и DOM. Начало активному развитию веб-приложений положили 2005–2006 годы, развитие библиотек и инструментов началось чуть позднее. Нас в первую очередь интересуют приложения на стороне фронта. Они в тот момент напрямую манипулировали DOM, CSS и данными. То есть фронтенд-приложение представляло собой реакцию на события, а также прямую манипуляцию DOM и данными. Можно сказать, что после накопления опыта создания таких фронтенд-приложений разработка перешла на новый уровень.

1.1.4. Фронтенд-приложения

Эпоха8, которую я обозначил как «фронтенд-приложения», началась в 2013 году с появления библиотеки React.js и длится по сей день. Уже есть первые признаки ее завершения. Свое ви́дение данного процесса я изложил в следующем подразделе, а пока вернемся к началу эпохи.

Факторов9, повлиявших на переход к новой эпохе, четыре. Первый — технологии и подходы, второй — инструменты, третий — библиотеки, четвертый — пользовательский опыт и обратная связь. Каждый из них внес свой вклад в определенный промежуток. В качестве точки отсчета, начала эпохи я выбрал момент появления библиотеки React.js. Взгляните на рис. 1.1.

На инструменты (точнее, на увеличение их количества) сильно повлияло возникновение Node.js. Инструменты позволяют ускорять разработку фронт-приложений плюс дают удобство. Сегодня мы используем их повсеместно. Чуть позже появился репозиторий npm, ускоривший разработку в разы за счет того, что теперь устанавливать зависимости можно одной командой в консоли.

Развитие технологий тоже началось с Node.js. На рис. 1.1 видно, что с 2009 по 2015 год произошел их бурный рост. Эти технологии используются до сих пор и продолжают развиваться. Стоит отметить: несмотря на то что JavaScript уже существовал, в 2015 году стандарт ECMAScript был пересмотрен и произошло качественное изменение языка. В него добавили новые элементы, например, для асинхронного написания программ, а именно — Promise.

Рис. 1.1. Эпохи разработки, технологий, инструментов и библиотек

Тогда же появились новые библиотеки и стали очевидны недостатки в производительности прямой работы с DOM-моделью. Для лендинга нормально манипулировать DOM и данными напрямую, но не для высоконагруженных сервисов. Компания Facebook10 к 2013 году разработала библиотеку React.js, которая отличалась от существовавших на тот момент тем, что отделяла создание интерфейса от его воплощения в DOM браузера. Такой подход значительно повысил производительность приложения. Одновременно разработчики выделили среди других компонентов строительный элемент приложения, ускорив саму разработку. Самое интересное, что теперь приложение, работающее в браузере, действительно можно было назвать приложением. Извиняюсь за тавтологию11, но именно с этой библиотеки, по моему мнению, начался рост веб-приложений как явления. Отныне приложение не манипулировало DOM напрямую. Разработчик описывал, как должен выглядеть интерфейс, с помощью данных и компонентов, а библиотека React в совокупности с библиотекой ReactDOM вычисляла посредством виртуальной DOM12, что нужно изменить в реальной DOM, чтобы получить предписываемое компонентами. То есть разработчику больше не требовалось манипулировать DOM (императивный подход), достаточно описать состояния и внешний вид (декларативный подход).

Конечно, на рынок стали выходить конкуренты, например Vue.js, Angular. Сообщество, использовавшее React, накопило соответствующий опыт, и стало очевидно, что управлять состоянием всего приложения нужно иным образом, нежели с применением пропсов и стейтов. Так появились библиотеки Redux и Mobx, которые можно использовать совместно с React. Чуть позднее в React (версия 16.3 от 2018 года) появился Context, позволявший не передавать данные вручную в явном виде, через все дерево компонентов от родителя к нужному дочернему компоненту.

Для более предсказуемого управления целыми поддеревьями компонентов была разработана библиотека React-Router-Dom.

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

Теперь посмотрим, что нас ждет в ближайшем будущем.

1.1.5. Эпоха искусственного интеллекта14 и виртуальной реальности

На рис. 1.1 я поставил знак вопроса, чтобы вы озадачились тем, что нас действительно ждет. Развитие идет по нескольким направлениям:

• технологии;

• инструменты;

• библиотеки.

Инструменты и библиотеки упрощают использование технологий и вводят дополнительные абстракции для более легкого моделирования работы с данными. В технологиях это также платформы, для которых разрабатываются приложения. На языке информатики это исполнитель: изменится платформа — изменятся и инструмент, и библиотека, и подход к разработке, а также появится другая технология, которую надо будет изучить и использовать. Сейчас активно распространяется браузер. Данная тенденция сохранится на какое-то время, пока не появится другое приложение, вероятно, в совокупности с новым типом девайса15. Все тот же, правда уже вчерашний, Facebook, а сегодня — Meta продвигает идею метавселенной, и ведутся диалоги о создании единого стандарта для метавселенных, что правильно. Ведь есть опыт по разработке браузеров, каждый из которых идет своим путем. Единый стандарт позволит сэкономить время и быстрее развиваться.

А как насчет искусственного интеллекта (ИИ)? Что он нам даст? Все просто — ИИ ускорит разработку. Уже сегодня доступны инструменты, позволяющие на основе промпта16 получить готовый код. Таковыми являются GigaChat17 и GigaCode18 от «Сбера». В ближайшее время можно ожидать появления других инструментов, значительно ускоряющих написание кода и, вероятно, даже создающих полное приложение на основе небольшого количества входных данных. Позволить себе такие крупные разработки может или крупная корпорация, такая как «Сбер», Google, Microsoft, Oracle, SAS и т.п., или группа увлеченных энтузиастов, придумавшая какую-то идею и на основе open source — решений, каковыми являются языковые модели GPT, RuGPT19, выпустившая продукт, покрывающий потребность в автоматизации, которая ранее была доступна только специалистам. Пока браузеры не будут сдавать свои позиции в силу распространенности, но создание приложений значительно ускорится, а вслед за этим изменится инфраструктура, на которой они работают. Браузеров станет недостаточно. Посудите сами. У вас в руках — инструменты, работающие на основе нейросетей и способные написать типовой код, включая внесение необходимых изменений. В качестве «железа» есть компьютер с огромными ресурсами, а вы по-прежнему пользуетесь браузером, способным разве что воспроизводить картинки и видео. Конечно, нет! Возможно, браузер — как идея, а не как программа — перейдет в девайсы для виртуальной реальности и станет 3D с тактильным интерфейсом.

От чего зависит появление новых технологий? Только от нас с вами — чем больше вы вкладываетесь в разработку новых технологий, тем быстрее они приходят на рынок. Действует прямая закономерность: если вы направляете внимание лишь на изучение библиотек и технологий, то и получаете знания библиотек и технологий, а еще можете создавать продукты на их основе. Если же вы ориентируетесь на разработку и придумывание чего-то нового, что до вас никто не делал, ну разве что высказывал идеи, то и получаете то, что может стать «новым стандартом», как это было с jQuery, React, Redux, React Router, с языком TypeScript. Поэтому надо действовать не только в использовании имеющегося, но и в придумывании нового.

Стоит ли переживать по поводу того, что сегодня из каждого утюга кричат про языковые модели, искусственный интеллект и т.п.? Нет. Приложения не состоят из одного текста и никогда только из него состоять не будут. Они состоят из гипертекста и медиа. Приложения должны иметь структуру, в них воплощаются замыслы людей, а не машин. Без фронтенд-разработчиков это неосуществимо. ИИ ускорит вашу работу. Однако запросов от населения и бизнеса относительно приложений меньше не станет, их количество будет увеличиваться. Растет население, растет осознание и качество жизни, растет потребность. Сами посудите, как бы вы сегодня работали на прошловековых технологиях создания приложений без интернета? Да никак! И работы все прибавляется. Ровно то же самое вас ждет в текущий момент времени. Так что давайте погружаться в область фронтенд-разработки.

1.2. Разработка фронтенд-приложения

1.2.1. Окружение разработки

Знание JavaScript открывает возможность для изучения фронтенд-разработки, где он активно задействуется. Однако написание кода, состоящего из функций и UI-компонентов, не единственное обязательное действие. Разработка приложения включает в себя несколько этапов и шагов в них, состоит из индивидуальной и групповой работы. Конечно, если вы работаете одни, то группового этапа нет. В любом случае вы ведете поиск готовых решений, конструируете компоненты и функции, пишете тесты, проверяете работоспособность и синтаксическую корректность кода. Если приходите в готовый проект, а так происходит чаще всего, вы, кроме того, знакомитесь с кодом. При этом подавляющее большинство проектов осуществляется в группе, поэтому необходимо делать код-ревью изменений, которые вносят в репозиторий другие разработчики. Если вы создаете приложение с нуля, то необходимо его спроектировать и, прежде чем начать писать код, сделать настройки для сборки приложения и проверки корректности синтаксиса.

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

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

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

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

Рис. 1.2. Области, которые нужно контролировать фронтенд-разработчику

Начнем с обзора каждой области. Инструменты, за исключением системы контроля версий и сервисов для код-ревью, работают на node.js. Системы контроля версий работают непосредственно в операционной системе, а сервисы для код-ревью и хранения репозитория20 приложения доступны в интернете.

1.2.2. Управление зависимостями

Зависимость — это модуль21, обычно называемый пакетом, содержащий выражения на языках JavaScript, TypeScript и импортируемый для использования в программе. Зависимость может быть любого размера и выполнять одну и более функций или вычислений. Такой модуль, в свою очередь, тоже может иметь зависимости. Поясне­ния даны на рис. 1.3.

Чтобы не запутаться в словах, надо понимать разницу между реестром и репозиторием. Реестр — просто список чего-либо. Репозиторий — место, где что-либо хранится. Применительно к npm реестр содержит оформленные модули; нам, как пользователям, доступен список всех хранящихся там модулей. Когда пишем код и с помощью системы контроля версий размещаем его в месте хранения (репозитории), у нас нет специального списка модулей, как в npm, и мы не оформляем каждый JavaScript-модуль как npm-модуль.

Рис. 1.3. Зависимости приложения

Для управления зависимостями используются программы npm, yarn и др.; это — инструмент. Стоит отметить, что он предназначен для работы с внешними зависимостями — это видно на рис. 1.3.

1.2.3. Язык и кодирование. Трансляция

Под трансляцией понимается два вида процессов. Первый — процесс преобразования исходного кода программы непосредственно в машинный код плюс некоторые другие процессы, что позволяет запускаться программе на компьютере. Например, вы написали программу на алгоритмическом языке С и, используя компилятор gcc, создали исполняемый файл. Второй — процесс перевода программы, написанной на одном языке, в код программы на другом языке. Также ко второму процессу относится перевод программы, написанной на одной версии языка, в код программы, написанный на другой версии того же языка. Самое популярное действие — перевод последней версии языка JavaScript, например версию JavaSript 2024 в версию JavaScript 5.1.

1.2.4. Сборка приложения

Сборка приложения, или упаковывание, — это подготовка кода приложения для его выполнения в браузере и подготовка ресурсов для использования в приложении. Под ресурсами понимаются изображения (PNG, JPEG, GIF и др.), CSS-файлы, аудио и видео (если они располагаются у вас и не управляются особым образом).

Для данной процедуры используется инструмент под названием «сборщик», например webpack.

1.2.5. Поиск проблем в коде

Поиск проблем в коде означает, что существует некое «идеальное положение дел», то, как должен быть написан код, и происходит сравнение кода вашего приложения с идеальным. Несоответствия называют «проблемой». Для поиска проблем используют инструменты, называемые линтерами (linter).

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

Линтер ESLint разработал Николас Закас, инженер из Google. Линтер JSLint — Дуглас Крокфорд, писатель, лектор и программист, известный по разработанному им формату JSON.

1.2.6. Оформление кода

Оформление кода — это то, как выглядит (форматирование) написанный код JavaScript, CSS, JSON и др. Для такой работы используют специальный инструмент, например prettier.

1.2.7. Тестирование

Тестирование — область, по величине сравнимая с разработкой, поэтому рассматривать ее мы не будем. Коснемся данной темы в настройках, в разделе 8.2 «Реализация 3RApp. Настройки».

1.2.8. Контроль версий и обмен кодом

Контроль версий — это управление исходными текстами и документами, используемыми при разработке приложений. Обмен кодом — это размещение сделанных изменений согласно определенной процедуре в репозитории, из которого другие разработчики могут эти изменения получить. Так достигается более быстрая синхронизация кода приложения до самой последней версии изменений. Одной из популярнейших сегодня систем является Git. Широко распространенные ресурсы для размещения кода — github.com, bitbucket.org. И недавно появившийся российский — gitverse.ru.

1.2.9. Код-ревью

Код-ревью (code review) — это процесс, когда другой разработчик (чаще разработчики) смотрит код, написанный вами в качестве решения задачи, с целью определить его соответствие:

• поставленной задаче;

• правилам, принятым в группе (code style, по-русски — «код-стайл»).

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

Мы рассмотрим, как проводить код-ревью и быстро погружаться в код в новой команде.

1.2.10. Заключение

Все инструменты, которые несколько лет назад приходилось настраивать вручную, сегодня автоматизированы. Если вы фронтенд-разработчик и разрабатываете приложение, нужно использовать инструмент CRA (create-react-app). Как создавать приложения, в том числе в ходе совместной работы, вы узнаете из этой книги.


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

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

5 DOM (Document Object Model) — объектная модель документа. Есть целый раздел, посвященный этой модели, где она рассматривается подробно. Сейчас дам общее представление: объектная модель документа — это модель, взаимодействие с которой позволяет менять содержимое документа, отображаемого в браузере. Браузер дает API для изменений, а чтобы разработчики понимали, что менять, документ представляется моделью в виде структуры дерева, чьими элементами являются объекты, созданные на основе тегов из запрошенного с сервера HTML-кода. Таким образом, воздействуя на модель через API, разработчик влияет на то, что отображается в браузере.

6 Трафик — перемещение, поток данных в передающей среде, например поток сообщений (пакетов передаваемых данных) в Глобальной сети. Также это означает загруженность сети (по аналогии с автотранспортом на дорогах). Трафик состоит из передаваемых данных и служебной информации, необходимой для организации их прохождения.  

7 W3C — World Wide Web Concorcium. Слово «консорциум» означает объединение компаний и частных лиц на основе общего соглашения для осуществления какого-либо мероприятия. Консорциум W3C — это международное сообщество, где члены-организации, постоянные сотрудники и другие люди, участвующие в деятельности, вместе разрабатывают стандарты веба. Директором консорциума является Тим Бернерс Ли.

8 Эпоха — продолжительный период времени, имеющий какие-либо характерные особенности.

9 Фактор — существенное обстоятельство, способствующее какому-либо процессу, явлению.

10 Компания Meta, которой принадлежит Facebook, признана экстремистской, и ее деятельность запрещена на территории Российской Федерации.

11 Тавтология — повторение того же самого другими словами без уточнения смысла.

12 Виртуальная DOM — это структура данных в виде дерева, содержащая точно такие же связи между узлами, как те, что должны быть в реальной DOM в самом браузере. Каждый узел в виртуальной DOM содержит данные, используемые в узлах реальной DOM. Следует отметить, что реальные DOM, выстраиваемые браузером, имеют гораздо больше свойств в каждом узле, чем виртуальные. Главные данные одного узла виртуальной DOM — это связи с другими узлами (отношения «родительский — дочерний»); данные, которые должны быть отображены в виде текста на странице, и данные о стилях.

13 SPA (Single Page Application) — приложение, исключающее загрузку страниц при переходе по ссылке. SPA загружается в браузер один раз, а в дальнейшем взаимодействие пользователя обрабатывается так, что хоть и создается видимость смены внешнего вида страниц, но все происходит без загрузки новой HTML-страницы.

14 Искусственный интеллект — синтетическая система, демонстрирующая «умное» поведение. Определение взято из книги: Харбанс Р. Грокаем алгоритмы искусственного интеллекта. — СПб.: Питер, 2023.

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

16 Промпт — запрос к языковой модели, на который предполагается ответ, имеющий смысл для человека.

17 GigaChat — диалоговая ИИ-модель, которая отвечает на вопросы, сочиняет тексты, пишет код и рисует картинки. Говорит на русском и понимает английский.

18 GigaCode — ИИ-ассистент, который позволяет генерировать код на разных языках с применением ИИ, выполнять автозаполнение и создавать запросы.

19 GPT (Generative Pretrained Transformer) — генеративный, предварительно обученный трансформер. Трансформер — это нейронная сеть, обрабатывающая всю последовательность текста сразу, одновременно выявляя взаимосвязи между словами, а не слово за словом. Нейронная сеть представляет собой модель, которая, по мнению исследователей моделей и мира, лежит в основе разума (речь о мыслительной деятельности, которая будто бы происходит в мозгу, состоящем из нейронов) человека и которую можно перенести в сферу обработки данных. Таким образом, создается впечатление, что программа, использующая нейронную сеть, обладает знаниями и способна к разумным ответам. Сеть — это элементы, содержащие связи с другими элементами, по которым могут передаваться данные.

20 Репозиторий — место хранения кода в файлах, откуда его можно получить или где можно разместить, а также дополнить или удалить.

21 Модуль (в программировании) — оформленный специальным образом функционально законченный и самостоятельный (в том числе по отношению к компиляции или загрузке) блок кода, взаимодействие с которым осуществляется через его внешний интерфейс. Раздельная трансляция (separate compilation) модулей важна при создании больших систем. кроме того, каждый отдельный модуль может повторно использоваться в других проектах. Разбиение программы на модули, модульность (modularity), существенно облегчает ее понимание, разработку, документирование, отладку, модификацию и сопровождение. В зависимости от контекста синонимами этого термина являются unit, programm unit и package. Источник: Пройдаков Э.М., Теплицкий Л.А. Большой англо-­русский толковый словарь по вычислительной технике и информационным технологиям. — М.: РТСофт, 2015.

Искусственный интеллект — синтетическая система, демонстрирующая «умное» поведение. Определение взято из книги: Харбанс Р. Грокаем алгоритмы искусственного интеллекта. — СПб.: Питер, 2023.

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

Промпт — запрос к языковой модели, на который предполагается ответ, имеющий смысл для человека.

GigaChat — диалоговая ИИ-модель, которая отвечает на вопросы, сочиняет тексты, пишет код и рисует картинки. Говорит на русском и понимает английский.

GigaCode — ИИ-ассистент, который позволяет генерировать код на разных языках с применением ИИ, выполнять автозаполнение и создавать запросы.

Эпоха — продолжительный период времени, имеющий какие-либо характерные особенности.

Фактор — существенное обстоятельство, способствующее какому-либо процессу, явлению.

Компания Meta, которой принадлежит Facebook, признана экстремистской, и ее деятельность запрещена на территории Российской Федерации.

Тавтология — повторение того же самого другими словами без уточнения смысла.

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

SPA (Single Page Application) — приложение, исключающее загрузку страниц при переходе по ссылке. SPA загружается в браузер один раз, а в дальнейшем взаимодействие пользователя обрабатывается так, что хоть и создается видимость смены внешнего вида страниц, но все происходит без загрузки новой HTML-страницы.

20

GPT (Generative Pretrained Transformer) — генеративный, предварительно обученный трансформер. Трансформер — это нейронная сеть, обрабатывающая всю последовательность текста сразу, одновременно выявляя взаимосвязи между словами, а не слово за словом. Нейронная сеть представляет собой модель, которая, по мнению исследователей моделей и мира, лежит в основе разума (речь о мыслительной деятельности, которая будто бы происходит в мозгу, состоящем из нейронов) человека и которую можно перенести в сферу обработки данных. Таким образом, создается впечатление, что программа, использующая нейронную сеть, обладает знаниями и способна к разумным ответам. Сеть — это элементы, содержащие связи с другими элементами, по которым могут передаваться данные.

Репозиторий — место хранения кода в файлах, откуда его можно получить или где можно разместить, а также дополнить или удалить.

Модуль (в программировании) — оформленный специальным образом функционально законченный и самостоятельный (в том числе по отношению к компиляции или загрузке) блок кода, взаимодействие с которым осуществляется через его внешний интерфейс. Раздельная трансляция (separate compilation) модулей важна при создании больших систем. кроме того, каждый отдельный модуль может повторно использоваться в других проектах. Разбиение программы на модули, модульность (modularity), существенно облегчает ее понимание, разработку, документирование, отладку, модификацию и сопровождение. В зависимости от контекста синонимами этого термина являются unit, programm unit и package. Источник: Пройдаков Э.М., Теплицкий Л.А. Большой англо-­русский толковый словарь по вычислительной технике и информационным технологиям. — М.: РТСофт, 2015.

12
18

Самые первые приложения — это клиент-серверные приложения, которые назывались сайтами4. По сравнению со страницами в браузере они были настолько простыми, что скорее представляли собой электронные книги и каталоги. Да, они были функциональными, но функциональность обеспечивалась не за счет задействования языка JavaScript и работы с DOM5, а за счет приложения, которое функционировало на сервере. DOM в том виде, в каком мы знаем ее сегодня, появилась в результате постепенного развития. Движение с одной страницы сайта на другую осуществлялось путем перехода по ссылке. Предыдущая страница выгружалась из браузера, а новая загружалась. То есть происходила полная перезагрузка страниц. Да, использовалась оптимизация запрашиваемых ресурсов —некоторые из них загружались из кэша, но то была оптимизация трафика для сервера. На клиенте все время происходила перезагрузка. В то время клиент-серверное приложение в виде сайта старались разукрасить или сделать как можно более функциональным за счет серверного приложения.

10
13

Факторов9, повлиявших на переход к новой эпохе, четыре. Первый — технологии и подходы, второй — инструменты, третий — библиотеки, четвертый — пользовательский опыт и обратная связь. Каждый из них внес свой вклад в определенный промежуток. В качестве точки отсчета, начала эпохи я выбрал момент появления библиотеки React.js. Взгляните на рис. 1.1.

На заре становления интернета не существовало понятия «фронтенд-приложение». Был термин, вошедший в лексикон, — «клиент-серверное3 приложение». Чуть позже, когда мы рассмотрим исторические стадии развития функциональности, станет понятно, что такое фронтенд-приложение. Инструменты для его разработки тоже появились со временем.

Приложения, которые задействовали подход AJAX, уже не перегружались при каждом взаимодействии пользователя со страницей. Это создавало положительный пользовательский опыт и в целом увеличивало скорость работы клиент-серверного приложения за счет уменьшения трафика6. Однако с точки зрения фронтенд-приложения сами приложения, за редким исключением, были основаны на прямой работе с DOM и CSS. DOM браузеров на заре становления интернета не была реализована по единым стандартам, как мы можем видеть это сегодня. И даже сегодня наблюдаются расхождения со стандартом W3C7. А в 2006 году появление библиотеки jQuery осуществило прорыв в скорости создания веб-приложений. Библиотека предлагала множество методов для работы с DOM и AJAX, но главное — разработчикам больше не надо было беспокоиться о разности в реализации DOM в браузерах.

15

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

DOM (Document Object Model) — объектная модель документа. Есть целый раздел, посвященный этой модели, где она рассматривается подробно. Сейчас дам общее представление: объектная модель документа — это модель, взаимодействие с которой позволяет менять содержимое документа, отображаемого в браузере. Браузер дает API для изменений, а чтобы разработчики понимали, что менять, документ представляется моделью в виде структуры дерева, чьими элементами являются объекты, созданные на основе тегов из запрошенного с сервера HTML-кода. Таким образом, воздействуя на модель через API, разработчик влияет на то, что отображается в браузере.

Трафик — перемещение, поток данных в передающей среде, например поток сообщений (пакетов передаваемых данных) в Глобальной сети. Также это означает загруженность сети (по аналогии с автотранспортом на дорогах). Трафик состоит из передаваемых данных и служебной информации, необходимой для организации их прохождения.  

W3C — World Wide Web Concorcium. Слово «консорциум» означает объединение компаний и частных лиц на основе общего соглашения для осуществления какого-либо мероприятия. Консорциум W3C — это международное сообщество, где члены-организации, постоянные сотрудники и другие люди, участвующие в деятельности, вместе разрабатывают стандарты веба. Директором консорциума является Тим Бернерс Ли.

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

11
19
14
21
16
17

Приложения, которые задействовали подход AJAX, уже не перегружались при каждом взаимодействии пользователя со страницей. Это создавало положительный пользовательский опыт и в целом увеличивало скорость работы клиент-серверного приложения за счет уменьшения трафика6. Однако с точки зрения фронтенд-приложения сами приложения, за редким исключением, были основаны на прямой работе с DOM и CSS. DOM браузеров на заре становления интернета не была реализована по единым стандартам, как мы можем видеть это сегодня. И даже сегодня наблюдаются расхождения со стандартом W3C7. А в 2006 году появление библиотеки jQuery осуществило прорыв в скорости создания веб-приложений. Библиотека предлагала множество методов для работы с DOM и AJAX, но главное — разработчикам больше не надо было беспокоиться о разности в реализации DOM в браузерах.

Эпоха8, которую я обозначил как «фронтенд-приложения», началась в 2013 году с появления библиотеки React.js и длится по сей день. Уже есть первые признаки ее завершения. Свое ви́дение данного процесса я изложил в следующем подразделе, а пока вернемся к началу эпохи.

Самые первые приложения — это клиент-серверные приложения, которые назывались сайтами4. По сравнению со страницами в браузере они были настолько простыми, что скорее представляли собой электронные книги и каталоги. Да, они были функциональными, но функциональность обеспечивалась не за счет задействования языка JavaScript и работы с DOM5, а за счет приложения, которое функционировало на сервере. DOM в том виде, в каком мы знаем ее сегодня, появилась в результате постепенного развития. Движение с одной страницы сайта на другую осуществлялось путем перехода по ссылке. Предыдущая страница выгружалась из браузера, а новая загружалась. То есть происходила полная перезагрузка страниц. Да, использовалась оптимизация запрашиваемых ресурсов —некоторые из них загружались из кэша, но то была оптимизация трафика для сервера. На клиенте все время происходила перезагрузка. В то время клиент-серверное приложение в виде сайта старались разукрасить или сделать как можно более функциональным за счет серверного приложения.

Глава 2. С чем имеет дело фронтенд-разработчик

2.1. Возможности программ на JavaScript

2.1.1. С чем и как взаимодействует программа на JS

Любая функциональность доступна программе лишь благодаря «железу» компьютера. Под «железом» понимается как базовое оборудование — материнская плата, диск, так и расширяющее оборудование — сетевая, аудио- и видеокарты. Нет определенного «железа» — не будет доступна и функциональность. Простой пример с модулем Wi-Fi. Если в вашем компьютере его нет, к интернету придется подключаться с помощью сетевого кабеля. Или возьмем сетевую карту: нет карты — нет интернета. Эта, казалось бы, очевидная вещь говорит о том, что создаваемые нами программы в конечном итоге исполняются в «железе».

Программы взаимодействуют с «железом» через операционную систему. При этом язык программирования можно рассматривать с разных сторон. Одна из них — то, с чем может взаимодействовать программа, созданная на конкретном языке.

Например, если вы напишете программу на языках С/С++ и транслируете ее в исполняемый файл, то сможете запускать данную программу в операционной системе. Из нее можно взаимодействовать с памятью компьютера и каналами ввода/вывода разных устройств (монитор, сеть) или файловой системой. Реализуется это не напрямую, а через API операционной системы, для чего созданы встроенные в языки С и С++ стандартные библиотеки. Если в компьютере есть конкретное физическое устройство, то операционная система предоставит к нему доступ через обобщенный интерфейс. Программы на С/С++ транслируются в машинный код. После запуска они исполняются как процесс в операционной системе.

С языком JavaScript дело обстоит иначе. Написанная на нем программа способна взаимодействовать только с API, предоставленным платформой22, где она может исполняться.

Новые программные объекты, которые могут исполняться в операционной системе и взаимодействовать с «железом», JS не создает. Их предоставляет платформа, например браузер. Поэтому программа, написанная на JavaScript, не сможет обес­печить иной функциональности, кроме обработки данных. Однако если задействуются объекты платформы, то можно создавать сценарии, по функциональности не уступающие программам, созданным на Java, C++ или С. Примеры мы увидим далее. Так вот, программа, написанная на JavaScript, может использовать объекты функциональности платформы, получать от них данные и передавать им данные, управлять ими посредством API. Схематично разница программ на C/C++ и JavaScript показана на рис. 2.1.

Рис. 2.1. Разница программ на С/С++ и JavaScript

2.1.2. Работа с данными

Под работой с данными понимается несколько действий с ними:

• изменение значений, хранящихся в переменных или структурах данных;

• изменение структуры данных;

• генерация данных;

• вычисления на основе данных.

Рассмотрим примеры для всех четырех случаев работы с данными на JavaScript.

Изменение значений, хранящихся в переменных или структурах данных, хорошо иллюстрирует пример с массивом, где каждое число удваивается, как показано в листинге 2.1.

Листинг 2.1. Изменение значений чисел, хранящихся в массиве

const plainNumbers = [2, 3, 5, 7, 11, 13, 17, 19, 23];

const doubleNumber = (numbers) => numbers.map(number => number * 2);

const evenNumbers = doubleNumber(plainNumbers);

Переходим к изменению структуры данных. Допустим, у нас есть объект сотрудников, разделенных по половому признаку, но нам нужно объединить два массива в один с указанием полового признака. Это и будет изменением структуры данных. Как такое сделать, показано в листинге 2.2.

Листинг 2.2. Преобразование объекта с массивами в массив объектов

const workers = {

    man: [{ name: 'Александр', age: 32 }, { name: 'Федор', age: 36 },

        { name: 'Валентин', age: 31 }],

    woman: [{ name: 'Анжела', age: 28 }, { name: 'Ирина', age: 32 }],

};

 

const enhanceWorkers = (array, prop) => array.map(item => ({...item, ...prop}));

const man = enhanceWorkers(workers.man, { sex: 'man' });

const woman = enhanceWorkers(workers.woman, { sex: 'woman' });

const enhancedWorkers = [...man, ...woman];

Помимо преобразования данных или структур, их можно генерировать. Каким образом это происходит, показано в листинге 2.3.

Листинг 2.3. Генерация чисел от 0 до 10 000

// limit — это верхняя граница, определяющая максимальное

// псевдослучайное число, которое должно быть сгенерировано

function *generateNumbers(limit){

    while(true){

        yield Math.floor(Math.random() * limit);

    }

}

 

const generator = generateNumbers(10000);

generator.next();

generator.next();

// ...

generator.next();

В этом примере генератор создает итератор, у которого метод next можно вызывать бесконечное число раз, и он каждый раз будет возвращать число в пределах от 0 до 10 000.

Последний, четвертый, пример касается вычисления. Вычисление — это обработка числовой информации ручным или машинным способом; действия над числами для нахождения искомого. Это слово часто встречается: его используют для описания действия над выражениями в языках программирования, причем для любых типов данных, например const str = someStr.concat(otherStr), а также для описания последовательности действий в программе, например if (value) {…} else { for (let i = 0; }. Есть еще значение, связанное с догадками, но это относится к человеку, а не к компьютеру. В английском языке почти идентичные определения. Так почему значения в разговорном языке касаются чисел, а мы используем это слово и для порядка действий, и для нахождения итогового значения, например строки? Возможно, потому, что компьютер хранит данные в виде чисел, а информатика берет свое начало в математике. Ну а математика имеет дело с числами и операциями над ними.

Рассмотрим пример подсчета средней длины слов в предложении, показанный в листинге 2.4. С одной стороны, у нас будут строковые данные. С другой — мы произведем вычисление, а именно найдем среднее арифметическое длины слов в предложении.

Листинг 2.4. Средняя длина слов в предложении

const sentence = "Пушкин желал таковой участи нашей Отчизне";

 

const averageWordLength = sentence

    .split(/\s/)

    .reduce((average, word, index) =>

Math.floor((average + word.length) / (index === 0 ? 1 : 2)), 0);

Поясню, что в выражении wordLength производится не что иное, как вычисление. Ведь возвращается длина строки или количество входящих в нее символов. С вычислениями в JavaScript дела обстоят шикарно, но кое-чего все-таки не хватает. Например, привычно выводить результаты в консоль. А для этого нужно задействовать объекты платформы, в которой запускается программа на JS.

Приведенные примеры показывают, что вы можете сделать, не задействуя платформенную функциональность. Теперь вполне закономерно задействовать последнюю.

2.1.3. Платформенная функциональность

Воспользуемся REST-сервисом с общедоступного сервера, который предоставляет данные для осуществления запросов, и выведем их в консоль (листинг 2.5).

Листинг 2.5. Задействование функциональности, предоставляемой платформой

async function getComment(id = 1){

    const answer = await fetch(

   `https://jsonplaceholder.typicode.com/comments/${id}`);

    const json = await answer.json();

 

    return json;

}

 

getComment(3).then(comment => console.log(comment));

В листинге 2.5 задействовано сразу два платформенных программных компонента — объекты fetch и console. Первый осуществляет запросы по протоколам HTTP и HTTPS к URL, а второй содержит методы для вывода данных в консоль браузера.

Словосочетание «функциональность, предоставляемая платформой» звучит непривычно, но описывает суть. Под этим понимается вся совокупность объектов, предоставляющих свой API, которые можно использовать в программах на JavaScript. Это доступные глобально объекты (document, Navigator, location, history, Geolocation и др.) и методы (prompt, alert, parseInt, parseFloat и др.). «Глобально» значит «доступные в любом месте программы».

Другие платформы, такие как Node.js, имеют собственные объекты, предоставляющие функциональность. Поэтому важным моментом в становлении разработчика является изучение API тех объектов и методов, которые есть в платформе, для которой пишется приложение. Чем больше вы знаете, тем быстрее будете писать приложение. На самом деле некоторые объекты требуют гораздо больше знаний, чем может казаться на первый взгляд. Возьмем WebRTC. В данном случае для создания полноценного сервиса не только потребуется знание фронтенда, но и придется создать дополнительную инфраструктуру. Чуть проще document, который, кстати, почему-то часто называют «функциональностью, доступной в JavaScript», хотя это объект браузера и доступ к нему можно получить не только из JavaScript. Чтобы лучше познакомиться с возможностями этого объекта, нужно время, потому что он задействует дополнительную функциональность — события.

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

2.2. Платформы

2.2.1. Что представляют собой платформы и зачем они нужны

Платформа — это сервис, который может выполнить программу, написанную на JavaScript. Она обязательно предоставляет какую-либо, свойственную только ей функциональность. Сегодня существует три вида платформ. Первый — браузеры. Второй — серверные Deno и Node.js. Третий — облачные сервисы. Обращаю внимание на то, что признаком, по которому выделяют виды платформ, является уникальная функциональность. При этом для обработки программ всех трех видов может использоваться один и тот же механизм.

Рассмотрим функциональность, доступную на разных платформах.

2.2.2. Уникальность функциональности

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

В браузере можно манипулировать историей сессии, которая была осуще­ствлена во вкладке. Это делается с помощью идентификатора history. Вы, конечно, не сумеете переписать историю, но при посещении URL доступно добавление данных в объект и перемещение по посещенным URL. Изначально такая возможность не предусмотрена ни в Node.js, ни в облачном сервисе, о котором речь пойдет ниже.

В Node.js, в отличие от браузера, доступна работа с файловой системой. Поэтому в своей программе вы сможете выполнить с ней любую операцию. Кроме того, в Node.js доступ к идентификаторам осуществляется через предварительный импорт модуля, который присутствует в стандартном наборе модулей, поставляемом при инсталляции, или может быть дополнительно установлен. Модуль для работы с файловой системой называется node:fs.

В облачном сервисе, как правило, недоступна функциональность, которая есть в браузере или Node.js. Чаще предлагается собственная функциональность. Примером является AWS. Из российских разработок — облачная платформа (виртуальный ассистент) «Сбера» «Салют», для которой можно создать приложение, скажем, Chat App23 или Canvas App, доступные пользователям приложения «СберБанк Онлайн» и платформы «Салют».

2.2.3. Важные выводы

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

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

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

2.3. Браузер и его объекты функциональности

2.3.1. Где платформа, а где JavaScript

В интернете можно встретить разные вопросы. Например, как в JavaScript на странице браузера найти элемент с определенным идентификатором?

Ничего необычного, однако формулировка «как в JavaScript...» некорректная, потому что здесь задействуется API, а не объекты самого языка. Выражение в листинге 2.6 представляет собой обращение к объекту document, который присутствует в браузере и раскрывает свойства и методы для полного контроля содержимого, внешнего вида и поведения HTML-страницы на вкладке браузера.

Листинг 2.6. Присвоение переменной результата метода getElementById

const audio = document.getElementById('player');

Но как, не касаясь конкретных объектов браузера или языка, определить, что относится к браузеру, а что — к JavaScript? Это достаточно просто, если вы уже имели дело с разработкой и использовали API браузера. И совсем не так очевидно, если такого знакомства не было или, например, вы использовали библиотеки и подход «возьму готовое решение».

Попробую объяснить в двух словах. Если рассмотреть только классы языка JavaScript и объекты, то станет ясно, что вы можете создать лишь данные или структуры24 из данных. Если рассмотреть браузер, то он предоставит вам интерфейсы, классы и объекты, с помощью которых можно управлять содержимым веб-страниц и другими действиями браузера. Да, в нем также есть функции, создающие или обрабатывающие данные, но они специфичны и не нуждаются в языке.

Рассмотрим пример на рис. 2.2.

Рис. 2.2. Классы и объекты JavaScript. Интерфейсы, объекты и классы браузера

В JavaScript вы задаете данные и структуры данных. Больше нет ничего, чем вы могли бы оперировать. Однако этого более чем достаточно. Остальные элементы языка направлены на преобразование данных (операторы), управление ходом выполнения программы (условные инструкции и циклы) — синхронным и асинхронным (конструкторы Promise и async/await), а также на работу с модулями. Но еще раз повторюсь: сейчас мы рассматриваем только объекты и классы.

Сам язык, к сожалению, не предоставляет никаких средств ввода/вывода. А для полноценной работы нам требуется взаимодействие, нужно получать и отправлять данные. Я имею в виду разработчиков, реализующих замыслы, как свои, так и заказчиков в виде программ. Поэтому необходим исполнитель, или, если взглянуть по-другому, нужно, чтобы где-то исполнялась наша программа. Браузер — один из таких исполнителей, предоставляющий возможность запускать программу и множество интерфейсов для доступа к функциональности. Нет необходимости думать о ее реализации: все, что может понадобиться, уже реализовано, остается лишь задействовать созданное. Функциональность, предоставляемая браузером, доступна в виде объектов, классов и функций.

2.3.2. Браузер — платформа с набором программ, предоставляющих API

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

Посмотрим на браузер как на платформу, где есть много программ, с которыми можно взаимодействовать прямо сейчас. Взгляните еще раз на рис. 2.2 и воспринимайте каждое слово как название программы, предоставляющей API и используемой непосредственно из программы на JavaScript. Тот факт, что она написана для веб-приложения при задействовании лишь document, fetch, encodeURIComponent и т.п., вовсе не означает, что у нее ограниченные возможности. Единственное ограничение — это множество функциональных возможностей самого браузера, которое полезно знать.

По сути, браузер — это платформа с набором программ, к которым вы получаете доступ с помощью API.

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

Листинг 2.7. Функциональность, предоставляемая браузером

const h1 = document.createElement('h1');

const body = document.body;

const text = document.createTextNode('Привет, Мир!');

 

h1.appendChild(text);

body.innerHTML = '';

body.appendChild(h1);

Если данный код выполняется в консоли браузера на уже имеющейся странице, то он заменит все содержимое узла body страницы одним элементом h1 с текстом «Привет, Мир!». Это так же просто, как если бы вы в своей программе создали объект, задали методы и вызывали бы их. Ничего сверхъестественного и мистического.

С помощью компонентов браузера вы можете создать для пользователей любое визуальное представление, которое будет динамически меняться в зависимости от действий пользователя или временных интервалов (с помощью setTimeout, setInterval). А еще — настроить взаимодействие с удаленным сервером или выполнение работы параллельно, организовать очень быстрый чат, шифровать или кэшировать данные, управлять историей действий пользователя, работать с двоичными файлами. Кроме того, доступно улучшение производительности приложения с помощью WebAssembly.

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

2.3.3. Библиотеки

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

Библиотеки бывают общего назначения и на определенную тему. Например, lodash — JavaScript-библиотека общего назначения, привносящая удобные утилиты для обработки данных. Ramda содержит набор функций, которые предназначены для функционального программирования. Redux ориентирована на состояние приложения, но нет никакой разницы, где она работает, — это чисто JavaScript-библиотека. А такие библиотеки, как ReactDOM, Vue, jQuery, React Router, предназначены для платформы и конкретно для браузера. ReactDOM и Vue работают с DOM, это их основное назначение. Они используют API событий, API Document и др. React Router завязана на API History и API Location. Что касается библиотеки jQuery, то она шире общего назначения при работе с API браузера, так как охватывает многие объекты браузера для построения кросс-браузерных приложений25.

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

2.3.4. Библиотеки React и ReactDOM

Если вы используете React, то это будет одна из главных зависимостей в коде вместе с ReactDOM, которые определяют, как вы строите код. Помимо того что задействуются функции и объекты React, сама библиотека, правда с использованием других инструментов, привносит в разработку дополнительную синтаксическую конструкцию — JSX (рис. 2.3). Она позволяет заменить вызовы функций React.createElement кодом, подобным HTML-коду. Таким образом сокращается время на создание компонентов и очень сильно упрощается написание того, что их рендерит26.

Библиотека React привносит в разработку удобство, идеи, с помощью чего должно строиться приложение, работающее в браузере, и при этом избавляет от необходимости думать об оптимизации.

Рис. 2.3. React — посредник между браузером и приложением, предоставляющим свой API

2.3.5. Преимущество библиотек

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

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

Если бы вы придумывали функциональность сами, то ее было бы просто использовать. Однако не всегда можно додуматься до тех же самых идей, которые воплощены в сегодняшних библиотеках. Так происходит не в силу скудности мировоззрения, а из-за малого числа коммуникаций на данную тему и постановки задач перед собой, точнее, перед группой единомышленников. Если бы вы собрали группу разработчиков и сформулировали задачу, которую хотите решить, ваша группа сама бы придумала решения, которые сегодня воплотили инженеры компаний, разработавших React, Vue, Angular, ramda и т.д. В группе вероятность нахождения решения растет пропорционально входящему в нее количеству людей.

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

Упражнения и практические задания

Для данного раздела предусмотрены упражнения и практические задания.

• Откройте папку drills и в ней — подпапку 2.3. Выполните упражнения по порядку.

• Затем откройте папку problems и в ней — подпапку 2.3. Выполните практическое задание.

• После выполнения практического задания откройте папку answers, в ней — подпапку 2.3 и ознакомьтесь с моим решением.

2.4. Загрузка приложения

2.4.1. Как осуществляется загрузка

Когда адрес вашего приложения набран в браузере, прежде всего производится GET-запрос27 ресурса, расположенного по введенному URL. Сервер, обслуживающий запросы, отправляет в ответ текстовую строку, помечая тип содержимого — HTML-текст. Браузер, получив ответ и поняв, что содержимое нужно интерпретировать как HTML, приступает к следующему шагу — парсингу, когда рассматривается только содержимое тела ответа, а все прочее опускается.

2.4.2. Парсинг содержимого строки, помеченной как HTML

Слово «парсинг» переводится как «синтаксический анализ, разбор». В случае с браузером это разбор строки, которая пришла от сервера в ответ на запрос и содержимое которой помечено как HTML. Данный разбор сопровождается одновременным действием — созданием будущей страницы, которую увидит пользователь. Рас­смотрим пример. Допустим, строка ответа от сервера выглядит так, как в листинге  2.8.

Листинг 2.8. Строка ответа сервера

<html><head><meta charset="utf-8"><title>Приложение</title><script src="application.js"></script></head><body><h1>Привет, Мир!</h1></body></html>

На основе данной строки браузер начинает строить дерево объектов, именуемое DOM — Document Object Model, или по-русски «объектная модель документа». Под словом «документ» здесь подразумевается страница.

DOM мы детально изучим в следующем разделе. А пока достаточно знать, что это некая модель страницы, состоящая из объектов, с которой вы можете взаимодействовать в вашем коде.

В HTML-документе присутствуют разные виды тегов. Например, такие, как script, iframe и link, обрабатываются сразу. То есть если во время анализа встречается тег script, то выполняется GET-запрос для загрузки файла, расположенного по указанному абсолютному или относительному адресу в атрибуте src, и сразу осуществляется его исполнение. Если это JavaScript-код, то выполняется сценарий JavaScript, а если HTML-код, содержащийся в iframe, то происходит его парсинг. То же касается содержимого файлов стилей.

Когда содержимое файла, прикрепленного к странице, проанализировано, продолжается анализ со следующей строчки — и так до конца строки HTML.

А как обрабатываются, например, ресурсы с изображениями или видео? Точно так же, через GET-запрос, с той разницей, что загрузка осуществляется асинхронно (без ожидания ее завершения) и лишь затем анализируется следующая строчка. Синхронно загружается лишь JavaScript-код по умолчанию, и у вас есть возможность изменить данную установку.

2.4.3. Прослушивание событий

Когда анализатор доходит до конца HTML-строки, происходит событие DOMContentLoaded. С этого момента наступает второй этап работы — прослушивание событий. Браузер ждет ввод от пользователя. Скрипты (JavaScript) уже загружены, и они назначили обработчики событий для некоторых узлов дерева DOM. Загрузка такого содержимого, как изображения, шрифты, видео, продолжает осуществляться, а необходимое для этого время зависит от объема данных, которые в них содержатся. Браузер выводит на страницу загруженные ресурсы, но сама структура страницы уже загружена, поэтому пользователь имеет возможность с ней взаимодействовать — вводить данные в формы с клавиатуры, нажимать на кнопки или другие элементы, с которыми можно взаимодействовать.

Когда загрузятся все оставшиеся ресурсы, такие как видео и изображения, происходит событие load. Это отображается в виде переставшего крутиться колеса на вкладке браузера, возле крестика. В коде это событие, на которое вы потенциально можете отреагировать.

2.4.4. Жизнь приложения

Приложение живет таким образом. Вы запрашиваете его по адресу, и загружается строка HTML-кода. Браузер разбирает эту строку и строит на ее основе DOM, а также выполняет код указанных в ней скриптов; загружает стили и применяет их; далее загружает другие ресурсы, тоже указанные в строке HTML-кода. После события DOMContentLoaded он ждет ввода от пользователя. На него приложение реагирует выполнением функций, установленных разработчиком, в качестве обработчиков конкретных событий или выполняет действие, предусмотренное по умолчанию для элемента страницы и не переопределенное разработчиком, например нажатие на ссылку (элемент a). Приложение что-то выполняет, иначе оно не имеет смысла. В  конечном счете пользователь его закрывает. Это основной и общий сценарий, без погружения в детали какого-либо приложения.

2.4.5. Другой взгляд на HTML

Можно сказать, что HTML — это указания программе (браузеру), какие заранее известные программы (объекты) в какой последовательности и с какими настройками должны быть помещены в вывод документа (страница, отображаемая пользователю). Заранее известными программами или объектами являются, например, программа, отображающая видео, задаваемая тегом video, или программа воспроизведения аудио, задаваемая тегом audio. Кроме того, есть объекты, которые не являются программами и с которыми взаимодействует пользователь. Они отвечают за местоположение на экране, например выделение места, что определяется такими тегами, как div, section, header, footer и др. С помощью HTML мы через текст (с использованием тегов, понятных браузеру) управляем набором программ, который будет доступен пользователю и с которым он сможет взаимодействовать на странице.

2.5. DOM

2.5.1. Как все могло бы быть сложным

Представим мир, в котором Тим Бернерс Ли28 не создал бы гипертекст, и тогда у нас не было бы привычных HTML, CSS, JS. Вместо него другой ученый, например Ли Хуньсэ из Китая, захотел бы, чтобы люди имели возможность создавать рекламные объявления о своих компаниях, продуктах или просто размещать информацию о себе. При этом ученый имел бы исключительно коммерческие интересы и повел бы себя как предприниматель, не желающий бесплатно расставаться со своей идеей на пользу человечества, поэтому решил извлечь выгоду из каждого этапа ее использования.

Как бы действовал такой ученый-предприниматель? Скорее всего, он выбрал бы способ получения платы с тех, кто размещает информацию о своих товарах, то есть с рекламодателей. А, допустим, для читателей это было бы бесплатно, но потребовалось бы установить себе на компьютер программу «Коммуникатор-читалка» для чтения и просмотра. И вот у нас есть программа, позволяющая людям читать тексты, смотреть видео и даже общаться в чате с помощью голоса и видео.

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

Наверное, такой ученый-предприниматель постарался бы запутать все возможности «халявного» использования технологии, чтобы никто без его ведома не мог пользоваться новой технологией бесплатно. А раз так, пришлось бы изрядно потрудиться, чтобы защитить свое детище. Представим, что сервер отправлял бы на клиент не HTML (JS, CSS), а, скажем, набор двоичного кода, куда были бы включены и тексты, и изображения, и программы. Для чего? Ну, просто так решил наш ученый, чтобы усложнить нелицензионное использование.

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

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

2.5.2. Что такое модель

Модель — это объект (не в коде, а в физической Вселенной), который заменяет другой объект, но воспроизводит какие-то его свойства. Модель применяется, когда нет возможности либо необходимости использовать основной объект или это по какой-то причине затратно.

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

Главное преимущество работы с моделью в том, что она воспроизводит какое-либо свойство или несколько свойств основного объекта. По этой причине к нему не нужно обращаться напрямую, можно работать с моделью и по ней понять, как будет себя вести основной объект.

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

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

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

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

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

Как видите, в жизни мы постоянно используем модели.

2.5.3. Что такое документ

Этим словом обозначается два объекта.

Первый, всем знакомый, — название свойства объекта window, window.document. Он представляет вкладку браузера, содержащую вывод, который мы задаем с помощью HTML-кода, CSS и JavaScript (имеется в виду, что JS может принять участие в добавлении элементов, их изменении или удалении, а CSS — оказать дополнительное влияние на вывод).

Второй — графический вывод. Это то, что вы видите, когда заходите в браузер, открываете вкладку и, вбив адрес, наблюдаете выведенным на экран. Документ, для которого составляется модель. Для его создания в браузерах используется специальный механизм. Например, в браузере Chromium он называется Blink29 (рис. 2.4).

Рис. 2.4. Документ

2.5.4. Что такое Document Object Model (DOM)

Важное правило моделирования гласит: как только вы создали модель, можно забыть про первоначальный объект, для которого она создавалась, и работать исключительно с моделью. Используя модель, не нужно рассуждать так: «Если я найду элемент, а затем изменю свойство, то браузер преобразует в графику...» Вам достаточно знать, как работать с моделью30. Однако важно правильно понимать, для какого объекта составлена модель. В предыдущем подразделе сказано, что такое документ. В нашем случае именно для него создана DOM.

DOM — модель, создаваемая отдельно и независимо от языка программирования, который с ней взаимодействует. Документ на экране изображается механизмом рендеринга, встроенного в браузер. Мы управляем им с помощью объектной модели документа (DOM), а не напрямую.

Сама модель создана в виде структуры данных — дерева (рис. 2.5). Соответственно, работая с этим деревом (моделью), вы можете изменять документ.

Рис. 2.5. Типичное начало дерева DOM

В дереве объектной модели документа есть родительский узел — document. Существуют и промежуточные узлы, которые чаще всего являются элементами, представляющими теги HTML. Есть концевые узлы, называемые листьями. Как правило, это текст или элемент, представляющий HTML-тег.

Чтобы внести изменения в документ, необходимо изменить модель. Так как модель является структурой в виде дерева, то необходимые изменения вносятся в узел (-лы). Узел в модели управляет своими свойствами и связями со своими дочерними узлами, то есть структурой поддерева, родителем которой он является. Например, если у нас есть HTML-страница о турах в горы, то удаление заголовка h1 из модели документа отразится в виде изменения в самом документе: заголовок исчезнет со страницы. Здесь мы вносим изменение в узел body и меняем состав его дочерних элементов (удаляем h1). Рассмотрим пример. Допустим, у нас есть документ и его модель (рис. 2.6).

Рис. 2.6. Документ и модель до изменения

После удаления из модели узла, который представляет HTML (тег h1), в документе произойдут корректировки — пропадет надпись «Всем привет!». При этом изменится графический вывод, осуществляемый браузером (рис. 2.7).

Рис. 2.7. Модель и документ после изменения

DOM включает в себя API, через который вы можете взаимодействовать с моделью. Поэтому взаимодействие с DOM, или, другими словами, работа с моделью документа, представляет собой взаимодействие с помощью методов, имеющихся в API DOM. Это также получение значений из свойств, которыми располагают объекты модели, или задание им значений — напрямую либо через методы. Пример взаимодействия с объектной моделью документа с помощью API показан на рис. 2.8.

Рис. 2.8. Пример взаимодействия с моделью DOM

2.5.5. Свойство document и операции в DOM

Чтобы стать гуру веб-разработки, нужно изучить API DOM. И не только. Еще, как было сказано в предыдущих разделах, есть сама платформа — браузер, а в нем — объект window, где существует множество разных идентификаторов, представляющих интерфейсы, конструкторы или просто объекты, обеспечивающие доступ к готовой функциональности. Но вернемся к объектной модели документа.

Все API модели доступно через свойство document объекта window.

Поскольку модель документа представляет собой дерево, его объекты-узлы связаны между собой ссылками. Для взаимодействия с моделью доступен целый ряд операций. Изобразим их и опишем, далее каждой группе операций будет посвящен подраздел.

Первая группа — поиск узлов в дереве.

Вторая группа — обход узлов дерева.

Третья группа — создание и добавление узлов в дерево.

Четвертая группа — удаление узлов из дерева.

Пятая группа — изменение свойств и атрибутов узла.

2.5.6. Операции поиска узлов в дереве

Дерево узлов, которые представляют собой текст или тег, строит браузер на основе HTML-кода страницы, о чем шла речь в предыдущем разделе «Загрузка приложения». Соответственно, у вас есть готовая структура дерева, в которой можно осуществлять поиск узлов, отвечающих определенным критериям (рис. 2.9).

Рис. 2.9. Операции в DOM — поиск узлов

Поиск узлов реализуется через ряд методов, таких как querySelector, querySelectorAll, getElementById, getElementsByClassName, getElementsByName и getElementsByTagName. Детально методы мы изучим на практике, а здесь ограничимся списком (табл. 2.1).

Таблица 2.1. Методы поиска узлов в дереве DOM

Метод

Что делает

Реализуется интерфейсом

Возвращает

querySelector

Осуществляет поиск элемента по CSS-селектору, передаваемому аргументом

Element

Element | null

querySelectorAll

Осуществляет поиск элементов по CSS-селектору, передаваемому аргументом

Element

NodeList (статический)

getElementById

Осуществляет поиск элемента по идентификатору, передаваемому аргументом

Document

Element | null

getElementsByClassName

Осуществляет поиск элементов по имени класса, передаваемого аргументом

Element

HTMLCollection (живая)

getElementsByName

Осуществляет поиск элементов по значению атрибута name

Document

NodeList (живой)

getElementsByTagName

Осуществляет поиск элементов по имени тега

Element

HTMLCollection (живая)

2.5.7. Обход дерева DOM

API-модели документа включают в себя методы обхода узлов в разных направлениях (рис. 2.10). Независимо от того, с какого узла вы начали, это

...