Как стать full stack разработчиком, зная back-end. Пошаговая инструкция
Всем привет, меня зовут Влад, и я уже более семи лет занимаюсь коммерческой разработкой. Ранее я писал, как найти первую работу, как готовиться к собеседованиям и как учить .NET.
Сейчас я работаю в компании DataArt. Мой основной стек технологий — экосистема .NET, но почти во всех проектах я занимался также и front-end частью. В этой статье я попытаюсь сформировать общее понимание современной front-end экосистемы для людей, уже имеющих опыт в разработке, неважно, на каких back-end технологиях. И дам базовые рекомендации тем, кто хотел бы расширить свою область компетенций.
Зачем это нужно
Сейчас на рынке есть некий тренд на full stack специалистов, способных реализовывать все части проекта, а не только какую-то одну. Этому есть множество объяснений:
- Синхронизация между front-end и back-end командами требует времени и некоторых технических средств (swagger, версирование API). Чем больше людей нужно синхронизировать, тем выше вероятность ошибки из-за человеческого фактора. Очень часто люди сталкиваются с проблемой, что кто-то забыл обновить эндпоинты либо отправляет данные в неправильном формате. Это все решаемо, но выяснение причин и устранение таких ошибок требует времени.
- Очень часто в промышленной разработке клиент не имеет до конца сформированных требований либо требования изменяются, что приводит процесс разработки к небольшим итерациям и изменениям «на ходу». Если в таких условиях сложно разделять задачи, договариваться о «контрактах» между частями приложения, то это будет значительная потеря времени и производительности.
В общем, если сравнить pros & cons разделения ответственности, я пришел к такому сравнению:
Разделение разработки между front-end и back-end командами/людьми | Full stack |
Минусы:
| Минусы:
|
Плюсы:
| Плюсы:
|
Следует также учесть непрямые затраты на людей: чем больше людей работает, тем сложнее управлять ими, тем больше нужно фасилитации и менеджерского внимания.
Первые шаги
Если вы все-таки решились, будьте готовы к тому, что современная front-end экосистема очень изменчива, постоянно выходят новые версии фреймворков, ломая обратную совместимость. То, что вчера было стандартом, сегодня уже устарело. Это имеет свою логику: сам веб развивается достаточно быстро вместе с самими браузерами, меняются и требования к разработке. Также вы сразу же столкнетесь со шквалом непонятных ошибок — на всех уровнях. Будьте готовы много гуглить или спрашивать у коллег. Не зря front-end комьюнити самое активное в плане конференций и контрибуции open source, иначе просто не выжить.
Например, вот таблица поддержки разными версиями и производителями браузеров разных версий JavaScript. О том, как преодолевается такая неразбериха, — далее в статье.
Немного о том, что такое современная front-end-разработка. Если вы писали на JQuery, это не совсем то, это скорее веб-мастеринг, добавляющий динамику страницам. Если вам нужно добавить простые эффекты на landing page либо реализовать несложную логику всплывающих окон, это верный путь, но если вы пишите полноценное одностраничное веб-приложение (Single Page Application), то это явно путь в никуда. Можете оставить свой предыдущий опыт с JQuery и обучаться заново, иначе разработка произведет огромный технический долг, который поглотит ваш проект, и каждое следующее изменение будет почти невозможным без переписывания значительной части.
Также немного о базовых понятиях. Правильное название JavaScript — ECMAScript (ES), JS — это маркетинговое название. Второй важный момент: Angular и AngularJS — это разные фреймворки. AngularJS — это все, что до версии 2.0, Angular — это все, что после второй версии. Это абсолютно разные параллельные ветки. Angular версий 2 и 7 отличаются не так сильно, просто политика версирования. Говоря «front-end-фреймворк», мы также для простоты имеем в виду библиотеки вроде React.js и Vue.js вместе с их экосистемой.
Общая структура знаний и технологий
Следующая иллюстрация показывает, по моему мнению, постепенный подход к изучению front-end инфраструктуры. Освоив нижние уровни на базовом уровне, можете двигаться дальше.
В целом это универсальное представление, но если говорить о конкретике, то чаще используется какой-то один фреймворк, а остальная экосистема строится вокруг него. Пройдемся по каждому уровню с уточнениями и раскрытием содержания.
Инфраструктура и сборка проекта
Пакетный менеджер
По аналогии с любой другой средой разработки — gems в Ruby либо packages из Nuget — в .NET для front-end есть системы управления пакетами:
NPM (Node Package Manager) — наверное, самая популярная система управления пакетами. Ее основная задача — вычитать имена и версии пакетов из package.json и разворачивать их вместе с зависимостями в папку node_modules. Имеет глобальный кеш пакетов (по аналогии с GAC.NET). Пакеты могут быть служебными (devDependencies) и обычными, включаемыми в production-сборку. Ссылка на официальный репозиторий пакетов.
Yarn — устанавливается с помощью NPM, что позволяет ускорить процесс установки, а также обеспечить другие полезные функции, недоступные в NPM, по умолчанию смотреть на зеркало npmjs от Facebook.
Bower — уже неактуальный менеджер пакетов, смысла разбираться с ним нет. Устанавливается с помощью NPM, но имеет свою базу пакетов. Ранее имел фичи, не реализованные в NPM, однако уже устарел, на сайте Bower есть рекомендация переходить на Yarn или NPM.
CLI
Каждый фреймворк имеет свой Command Line Interface (CLI) для выполнения разной черновой работы: скаффолдинга проектов с заранее заданными настройками, добавления компонентов, запуска тестов, деплоя, анализа производительности.
Angular — Angular CLI
React — Create React App
Vue — Vue CLI
Модульная архитектура проекта
Для того чтобы система сборки модулей могла эти самые модули собрать, они должны понимать, кто кого импортирует и на каких условиях. Существует несколько видов модульной организации:
- ES-модули — самый популярный стандарт, тот самый import {classname} from.
- CommonJS — встроенная в NodeJS система организации модулей.
- AMD (asynchronous module definition) — стандарт, который реализован в системе RequireJS, считается устаревшим.
Более подробно можно почитать тут.
Система сборки модулей и таск-раннеры
По сути, это тот же NPM-пакет, который запускается инфраструктурным кодом для превращения ваших исходников в веб-приложение, готовое к запуску. Самые популярные системы сборки:
- Webpack, Browserify — системы сборки со множеством фич из коробки. Для большинства случаев вполне приемлемо использовать Webpack.
- Gulp, Grunt — являются, по сути, таск-раннерами, имеют экосистемы из большого количества плагинов. С их помощью можно воссоздать ту же цепочку обработки и сборки и даже запустить Webpack как отдельную задачу.
- NPM scripts — альтернатива Gulp/Grunt. Предлагается делать эту же работу чисто на менеджере пакетов NPM с его возможностью подключать зависимости для разработки, добавлять сложные команды в раздел scripts у package.json.
Однозначно сказать, какой подход лучше, нельзя. Таск-раннеры дают больше гибкости, но имеют большее время конфигурирования. Webpack дает нам веб-сервер из коробки плюс готовую инфраструктуру для сборки приложения.
Если взять, к примеру, Webpack, то придется немного повозиться, чтобы настроить все необходимые параметры и пакеты с нуля, для сборки/минификации скриптов, транспайлинга/полифила, сборки и преобразования CSS, HOT loading (обновления вашего приложения после сохранения без необходимости обновлять страницу).
Для этого имеет смысл воспользоваться CLI для скаффолдинга (генерации основы приложения/модулей) готовых настроек и пакетов для файла webpack.config.js.
Транспайлеры/полифилы
Как я писал ранее, существует целый зоопарк совместимостей между браузерами и версиями языка ECMAScript. Чтобы иметь возможность написать наш код на самой последней версии языка, но исполнить его на любой платформе, необходимо имитировать недостающие фичи на уже реализованных.
Тут нам на помощь приходят:
- транспайлеры — специальные служебные пакеты, которые транслируют фичи более высоких версий ES в более низкие;
- полифилы — добавляют старым браузерам новое API, имплементированное на JS, как эмуляцию стандартного.
Например, самый популярный пакет Babel является и транспайлером, и полифилом. Поддерживает ES6/TypeScript, JSX, Flow, переводя код, написанный на этих языках, в ES5, понятный всем браузерам.
Транспайлеры/полифилы — обычно одни из шагов обработки исходного кода с помощью сборщиков/таск-раннеров.
Линтеры
Статические анализаторы кода, которые помогают находить и устранять проблемы форматирования, делать выводы о потенциально опасных местах без компиляции. Самый часто используемый линтер — ES Lint.
Форматеры кода
Prettier — дело личного вкуса, использовать такие средства или нет, но они помогают выдерживать единый стиль оформления кода при коллективной работе.
Unit/UI-тесты
Аналогично с back-end время от времени существует необходимость в написании тестов. Но виды тестов немного отличаются.
- Тесты в BDD подходе / Unit тесты— это три в одном: и тесты, и документация, и примеры использования. Тут вам помогут Jasmine/Mocha.
- Интеграционные тесты — проверяются отдельные элементы верстки на корректность и работоспособность.
- End-to-end-тестирование — через обертку над Selenium Web Driver, например, реализуется в Mocha. Проверяется весь флоу взаимодействия, где покрываются только позитивные сценарии.
- Визуальное тестирование — тестирование на соответствие верстки заданному виду, например: PhantomCSS, Wraith, более продвинутые средства, вроде Applitools.
Понимать, что это такое, для общего развития стоит, но не думаю, что вам следует сильно углубляться в эту тему: чаще тесты пишут профильные front-end разработчики.
Разработка
Для разработки можно использовать как более тяжеловесные IDE вроде NetBeans/Visual Studio, так и более легковесные. Не столь важно, какую IDE или текстовый редактор вы будете использовать, сколько то, какие плагины вы поставите туда. Все эти IDE/редакторы имеют встроенную систему установки плагинов для навигации/отладки/подсветки синтаксиса и генерации кода. Разница между IDE и текстовым редактором заключается в том, что текстовый редактор более свободен от лишней функциональности, и только вам решать, какие плагины туда поставить. Со временем его сложность может стать не меньше, чем у IDE.
- WebStorm — достаточно популярная и мощная, но платная IDE.
- Visual Studio Code — больше текстовый редактор, чем IDE.
- Sublime Text — чем-то похож на VS Code.
Что использовать вам — дело вкуса, лично я использую Visual Studio Code, но многие профессиональные front-end разработчики хвалят WebStorm. Full stack разработчики часто любят использовать ту же IDE, где они пишут и back-end. Например, в ASP.NET Core есть мидлвар для запуска front-end части синхронно с back-end.
Также необходимо освоить Chrome DevTools (F12 Tools) — очень мощное средство отладки и диагностики. В самых тяжелых случаях вам может понадобится Fiddler — сниффер трафика, позволяющий производить дебаг вашего взаимодействия с сервером.
Понимание клиент-серверной и сетевой архитектуры
Для начала выясните базовые вещи на уровне концепций протоколов транспортного уровня модели OSI.
- Как работает DNS-сервер.
- Что такое доменное имя.
- Как, как и почему выделяется IP-адрес.
- Что такое протоколы TCP/IP, UDP.
Далее возьмитесь за базовое понимание протокола HTTP. Сам по себе HTTP или его наследник HTTP/2 с сетевой точки зрения — это протокол прикладного уровня. По сути, это передача текста по протоколу TCP/IP. HTTP реализован на бумаге, в виде некоторой спецификации-рекомендации, как веб-сервер должен реагировать на определенное сочетание поступающего к нему текста. Мы можем послать, к примеру, в GET-запросе данные тела запроса, как в POST, но сервер их просто проигнорирует.
И в каком виде веб-сервер должен отдавать ответ браузеру? Разные веб-серверы (IIS, Nginx, Apache) могут по-разному реагировать на HTTP-запросы, однако тут отклонения от рекомендаций и различия очень незначительны.
Особое внимание следует уделить следующим разделам:
- HTTP-статусы, основные.
- HTTP-заголовки и реакция браузера на них.
- Методы HTTP-запросов GET/POST/PUT/DELETE и другие, хотя на практике часто обходятся GET и POST.
- Что такое Cookies, JWT/Bearer-токены.
- Local storage — браузерное хранилище, как с ним работать и зачем.
- Виды взаимодействия браузера и сервера — технические и логические техники:
- AJAX/Polling;
- Long polling;
- Comet;
- SSE;
- WebSocket.
Более подробно можно почитать (посты
После того как браузеры стали поддерживать WebSocket нативно, необходимость в других техниках стала отпадать, но тем не менее есть случаи, когда, например, использование SSE более уместно.
Например, обмен сообщениями в реальном времени в ASP.NET реализован в виде фреймворка SignalR. Он сам выбирает транспортный уровень в зависимости от совместимости, тем самым скрывая эти подробности от вас. При использовании front-end фреймворков вам всего лишь нужно установить пакет для работы с SignalR.
- XSS, CSRF — самые популярные уязвимости и методы борьбы с ними.
- CORS — политика межсайтовых запросов, как сделать так, чтобы с одного домена можно было слать запрос на ресурс в другом домене.
- JSON — самый популярный формат передачи данных в сети.
Язык
Сейчас самый популярный язык для front-end — это ECMAScript 6 / TypeScript. Если рассмотреть возможности языков с точки зрения множеств, то выйдет так:
ES5.1 — фактически стандарт, поддерживаемый почти на 100% всеми современными браузерами одинаково. О нем есть замечательная книга с носорогом под названием «Подробное руководство», которую я вам не советую читать: очень уж там много воды. Базовые вещи достаточно глубоко разобраны тут: javascript.ru/tutorial, learn.javascript.ru.
Критические вещи для понимания самого языка:
- Области видимости переменных var.
- Типы данных, включая функциональные.
- Механика работы объектов и прототипов — достаточно общего понимания, при написании кода на ES6/TS вы вряд ли с этим столкнетесь.
- Механика работы замыканий.
- Приведение типов (без фанатизма!).
- Работа с объектами браузера — window, document, HTML element.
- Всплытие событий, работа с событиями.
- Манипулирование DOM и селекторы.
- Как работает асинхронность в V8.
Если вы знакомы с ООП-языками, то JavaScript — язык тоже объектно-ориентированный, со специфичной механикой наследования через прототипы. Тем не менее я думаю, что JS вполне себе разделяет концепции ООП:
- Инкапсуляция — мы в праве хранить переменную, захватив ее в замыкании, сделав недоступной вовне.
- Наследование — мы можем строить цепочки прототипов, расширяя их.
- Полиморфизм — мы можем интерпретировать функцию как объект, все есть объект.
Быть профессионалом в ES5 необязательно, но базовое понимание не помешает.
ES6 — является расширением ES6, отличная справка по нововведениям по нему тут. В нем появляется много синтаксического сахара, более предсказуемые области видимости, классы, модули. Эту спецификацию нужно знать очень хорошо.
TypeScript — является расширением ES6 и языком по умолчанию в инфраструктуре Angular. Рекомендую читать официальную справку. Тут появляются интерфейсы, generic, строгая типизация, ошибки времени компиляции. TS больше всего похож на C# и, пожалуй, является самым понятным подмножеством JS для back-end разработчиков.
Остальные языки экосистемы JavaScript:
- NativeScript — является языком написания гибридных мобильных приложений.
- CoffeeScript — диалект, отличается своей лаконичностью и читаемостью, однако не имеет большой популярности сейчас.
- ELM — функциональный язык, имеет ограниченную сферу применения.
- Dart — не совсем язык экосистемы JS, скорее, отдельный язык со своим интерпретатором, который встроен в Google Chrome.
Они совсем не обязательны к рассмотрению, сейчас смысла в них по факту нет. Конечно, есть, например узкая ниша, где, возможно, написать на ELM будет лаконичнее. Но я считаю, что, используя настолько редкие технологии, рискуешь остаться без специалистов, способных это поддерживать.
Фреймворк и библиотеки
Angular / AngularJS
Я уже упоминал, Angular — это все, что после второй версии, а AngularJS — все, что до нее. Архитектурный паттерн, предлагаемый Angular, — это MV*/MVVM. Единого мнения нет, но в целом архитектура очень похожа на ASP.NET Web Forms — есть компоненты с вложенными компонентами и сквозной функциональностью — встроенный IoC-контейнер для инъекций сервисов в компоненты, управление scope. Обработка асинхронных операций обычно пишется на RxJS. Однако возможно использовать Angular совместно с контейнером состояний Redux.
Для освоения базовых вещей я рекомендую курс «Angular 7 (formerly Angular 2) — The Complete Guide». Также неплохой гайд для старта.
Работая с front-end, нужно понимать природу задач, решаемых программно. Взаимодействие с браузером можно представить в виде потока событий и реакции на них, а также синхронизации разных цепочек событий и их преобразования. Для решения таких задач применяют парадигмы реактивного программирования. Эти парадигмы реализованы в библиотеках Reactive Extensions для множества языков программирования. Для JS это RxJS. Справка по RxJS. По RxJS могу посоветовать доклад моего коллеги.
С точки зрения движка шаблонизации, Angular вполне напоминает тот же Silverlight с привязками данных.
Angular является фреймворком — это значит, что под его маркой идет полный набор средств разработки. Это делает его хорошим выбором для сфер, где недопустимы пакеты, не прошедшие проверку, — например медицина со специфичными требованиями к legal или финтех.
React.js
Менее привычный подход для back-end разработчиков, с ориентацией на верстку и событийный поток. React.js, по сути, является библиотекой/template-движком, на котором вполне можно разрабатывать без дополнительных средств, однако это не настолько удобно при росте проекта и его сложности.
Говоря «React», мы подразумеваем React + React DOM для веб-разработки. Если взять React и React Native, мы сможем в похожем синтаксисе разрабатывать кросс-платформенные мобильные приложения. Для упрощения такой подход называют React Native. Подробнее тут.
Таким образом, сформировалась целая экосистема React:
- Axios — для HTTP-запросов.
- React Router — для поддержки более удобного роутинга.
- Redux — для централизованного управления состояниями.
- React Router Redux — для связи роутера и контейнера состояний.
- Redux-Thunk / Redux-Saga / MobX — разные подходы для синхронизации асинхронных операций.
Самый популярный архитектурный паттерн в React.js — это Redux, эволюция идеи Flux. По сути, идея Flux — это тот самый знакомый CQRS для back-end-разработчиков.
Идея в том, чтобы централизовать логику изменения всего состояния приложения в одном месте — в редюсере. Таким образом мы избегаем неточностей и двузначностей, не зная какой стейт установится первым и почему. Компоненты же просто отрисовывают наш стейт.
Подход к разработке в React.js противоречит «классическому» — отделению кода от разметки. React имеет свой движок шаблонизации — JSX, который упрощает смешивание верстки и кода. Верстка вставляется прямо в код.
Из первых вопросов, которые стоит разобрать, я выделил такие:
- JSX;
- Components, lifecycle;
- State/props;
- Virtual DOM;
- Synthetic events;
- Unidirectional data flow;
- HOC/Pure components;
- Flux/Redux.
В качестве учебника вполне подойдет официальная справка.
Vue.js
Еще один популярный движок шаблонизации, построенный на архитектуре MVVM (с использованием VueX — это Flux). Он имеет несколько вариантов организации шаблонов:
- Single File Components — концепция, в которой шаблон, логика и стили инкапсулируются внутри единого файла.
- JSX — смесь верстки и кода, то же, что и в React.js.
Сам по себе Vue.js похож на React в том, что это лишь движок для шаблонизации, имеющий свою экосистему:
- Axios — HTTP-запросы;
- Vue Router — роутинг;
- VueX — контейнер состояний.
Субъективно, Vue.js гораздо проще для старта, чем Angular или React. Он имеет отличную справку-руководство, в том числе русскоязычную.
Кратко о концепции потока данных в VueX:
Идея похожа на тот же CQRS:
- Код из нашей верстки диспатчит Action.
- Action делает асинхронный запрос на сервер.
- После получения ответа вызывается Mutation, которая решает, как ей менять State.
- Изменение State делает повторный рендер верстки.
Awesome Vue — тут вы найдете исчерпывающий список всего, что относится к экосистеме Vue.js: пакеты, гайды, UI-библиотеки, статьи.
Другие фреймворки и библиотеки
Backbone/Marionette, Ember, Knockout, MeteorJS, ExtJS, Aurelia — есть еще очень много различных фреймворков/библиотек, но:
- Они не пользуются таким спросом, как раньше, хотя могут быть вполне подходящими для решения задач, возложенных на них. Я знаю людей, которые до сих пор хвалят Ember/Backbone+Marionette и будут использовать их в новых проектах ввиду хорошего их знания.
- Их подход устарел.
- Они имеют некоторую избыточность по сравнению с тройкой лидеров.
Отдельно следует отметить следующие библиотеки:
- InfernoJS — очень похож на React.js, может использовать JSX, но дает экстремальную скорость работы, когда это необходимо.
- Preact — клон React.js для веба, имеющий размер бандла всего лишь 3 КБ (!), реализует основной API React.
На них вполне можно строить адекватный front-end, но поддержка комьюнити не будет такой сильной.
Добавлю, что развитие SPA породило другую проблему: у краулера Google при индексации сайтов, возможно, не получится нормально проиндексировать сайт, который строится динамически, либо же нам нужна повышенная производительность. Для этого используют Server Side Rendering (SSR), но это тема для отдельной статьи.
Имплементация аспектов — лучшие практики и паттерны
После того как вы решили, какой фреймворк будете изучать, реализуйте на нем базовые вещи:
- Стандартные вещи вроде роутинга/разбиения на модули.
- Авторизация и аутентификация.
- Формы, валидация форм.
- Всплывающие окна.
- Загрузка файлов.
- Дебаунсинг ввода и событий.
- Асинхронность приложения.
- Производительность нагруженных страниц.
Список реально решаемых задач может быть куда шире, это я написал для примера. На первый взгляд это кажется простым, но по пути вы столкнетесь с десятками проблем, решение которых и будет давать понимание того, что и как реально работает.
Верстка
Это одна из главных тем в front-end-разработке. За последние
Более продвинутый уровень:
- Адаптивность и кросс-браузерность.
- Методологии верстки типа БЭМ.
- Основы SEO и как правильно разрабатывать веб-страницу для корректной индексации поисковыми движками.
Но замечу, что даже front-end разработчики редко делают сложную верстку. Обычно версткой занимаются специальные люди либо внешние подрядчики. Сейчас хорошая верстка — это достаточно непросто, и она требует специальной подготовки и опыта.
UI kits/libs
Очень часто используются готовые решения для построения приложений. Нет смысла разрабатывать то, что уже разработали и протестировали.
CSS-фреймворки
Позволяют решить самые частые проблемы в верстке и сделать ее максимально быстрой и правильной с точки зрения пропорций, валидности, адаптивности и кросс-браузерности: Bootstrap, Bulma. Если поискать, существует много WYSIWYG-конструкторов для Bootstrap.
Паки UI-компонентов
Каждый год выходят новые версии и паки, достаточно просто найти информацию о них в интернете в похожих статьях по запросам вроде Best React UI Component Libraries. Например, Material реализован для Angular и других фреймворков/библиотек.
UI-библиотеки
Обычно платные, более продвинутый уровень UI-компонентов. Имеют интеграцию друг с другом и решают практически все возможные задачи промышленной разработки, интегрированы с самыми популярными front-end фреймворками: DevExtreme, KendoUI, ExtJs.
Преимущество использования таких библиотек в том, что, заплатив 1000 долларов за пользователя в год, мы получаем быстрое решение всех возможных задач, связанных с типичным промышленным UI: таблицы любой сложности, модальные окна, формы, экспорт и загрузка данных и многое другое.
Заключение
Не бойтесь разнообразия front-end технологий. Для начала определитесь, с каким именно стеком хотите работать, затем изучите его инструментарий на базовом уровне. Выберете среду разработки под себя, а так же спрашивайте своих коллег. Тут без общения не обойтись.
Если вы имеете какие-то вопросы/пожелания, пишите мне на Facebook. Также для разработчиков с опытом: если хотите сменить работу, могу посоветовать лучшие вакансии, помочь с составлением резюме и подготовкой к интервью.