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

Откуда мы пришли и где мы сейчас

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

Сначала веб-разработка была относительно простой. У нас были синхронные запросы к монолитным веб-приложениям, доставляющим шаблонный HTML пользователям в мире, где доминирует PHP. Статические файлы могут обслуживаться, и простой запрос GET будет выполняться каждый раз, когда мы меняем страницу. Одно репо. Проще простого.

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

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

Вот где появился шаблон проектирования flux, популяризированный Redux. Если React был структурным решением и решением для потока данных для приложений, Redux был ответом на управление и разделение этого большого объема данных на новый разрастающийся интерфейс без внесения несогласованности данных.

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

Это подводит нас к сегодняшнему дню, когда интерфейсы представляют собой собственные независимые приложения javascript, которые подключаются к API-интерфейсам, не зависящим от платформы. Хотя такое разделение ответственности внутри веб-приложения было следующим логическим шагом эволюции, в котором нуждался Интернет, этого было недостаточно. И это все еще не так.

Что дальше с приложениями

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

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

Несмотря на то, что сегодня мы выяснили, как масштабировать и управлять более крупными приложениями Javascript (React, Angular и т. Д.), А также как управлять потоком данных, чтобы сделать наши приложения более чистыми и эффективными с помощью таких фреймворков, как Redux, мы действительно не знали ' t действительно усовершенствовал контроль и управление фактическими данными, которые проходят через наше приложение.

Предложение для следующего поколения фронтенд-разработки

1.) У нас должны быть модели внешнего интерфейса и парсеры: Если вы не используете TypeScript и интерфейсы, в ваших собственных фреймворках Javascript нет «моделей внешнего интерфейса». Существуют базовые проверки типов данных с использованием Prop Types (в React), но этого не происходит в точке ввода данных в хранилище, и проверки могут быть ненадежными, и их сложно обеспечить при наличии ограниченной стандартизированной системы проверки.

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

2.) Наше глобальное хранилище должно основываться на наших определенных моделях. Сейчас данные отображаются в хранилище Redux путем определения базового структурного размещения через начальные состояния, но это слишком сложно, и большая часть процесса может быть автоматизированным. Если у нас есть наши объекты, определенные заранее (модели внешнего интерфейса и синтаксический анализатор, которые мы только что обсуждали), мы можем эффективно хранить глобальное хранилище нашего приложения в «коллекциях документов» на основе типа объекта (очень похожего на Meteor и Mongo) без необходимости определять структуру хранить за пределами определения моделей.

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

Это также означает, что определенные модели могут иметь внутренние действия. Например, если вы определили объект «Пользователь», вы также можете определить действие getCurrentUser для модели с конечной точкой и параметрами. Теперь действия на основе модели можно автоматически сопоставить с соответствующими хранилищами объектов.

3.) Подписка на глобальный магазин на уровне компонентов должна быть автоматизирована. Сейчас многие приложения React используют MapStateToProps для обработки обновлений на основе подписки из магазина. В этом нет необходимости.

Эффект: теперь у нас есть предопределенные «коллекции объектов» для нашего глобального хранилища, как мы обсуждали выше. Компоненты должны иметь возможность ссылаться на отдельные коллекции объектов хранилища (или отдельные объекты в коллекции динамически), а подписка может быть автоматизирована. Если конкретный документ был обновлен и компонент подписан на этот конкретный фрагмент данных в хранилище, то обновление будет распространяться на компонент. Эта автоматизация происходит потому, что теперь у нас есть предопределенная ожидаемая структура магазина.

4.) Более жесткий контроль данных означает меньшую передачу данных: приложения должны делать очень ограниченные запросы GET, и только дельты должны отправляться после выполнения начальных запросов GET.

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

  1. Текущий пользователь изменяет данные или
  2. Другой пользователь в другом месте обновляет данные

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

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

Вывод

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

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

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