Дилемма современной веб-разработки

внешний интерфейс
Дилемма современной веб-разработки

Управляемое чтение

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

Дилемма

Дилемма сотрудничества между дизайном и интерфейсом

В реальной веб-разработке работа с UI/UX и работа с интерфейсом на самом деле находятся в центре внимания.в двух совершенно разных средахНапример, пользовательский интерфейс завершит дизайн страниц и компонентов в Figma, а интерфейс будет воспроизводить диаграмму прототипа в среде кода в соответствии с разработанной диаграммой прототипа.Есть несколько проблем совместной работы. Я кратко резюмирую его в четыре вопроса:

  1. Должен ли я сначала проектировать, а затем разрабатывать, или я должен разрабатывать, а затем проектировать? (сначала разработка или сначала дизайн?)
  2. Если диаграмма прототипа проекта находится выше по течению разработки интерфейса, как интерфейс должен более эффективно получать обновление дизайна вверх по течению?
  3. В дизайн-чертеже скрыто много повторно используемых концепций и элементов, как правильно передать их во внешний интерфейс?
  4. Обязаны ли фронтенд-инженеры участвовать в разработке в чистом стиле? Теперь, когда пользовательский интерфейс был оформлен, почему внешний интерфейс все еще нуждается в повторной реализации?

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

Сначала разработка или дизайн?

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

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

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

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

Как клиентская часть должна более эффективно получать обновления дизайна вверх по течению?

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

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

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

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

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

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

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

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

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

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

Размер устройства, метод адаптивной верстки и дизайн этих уровней должны контролироваться UI/UX, но на самом деле они контролируются фронтенд-инженерами. аспекты дизайна.выполнить задание.

Как упоминалось выше, фундаментальная причина дилеммы совместной работы этих четырех UI/front-end заключается в том, чтоНесоответствие и дублирование функций, два типа работы тесно связаны и содержат друг друга, что можно обобщить на следующей диаграмме:

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

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

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

С точки зрения инструментов, текущими инструментами пользовательского интерфейса в основном являются Sketch и Figma. Все они являются относительно простыми в использовании программами для графического дизайна. Все они поддерживают дизайн компонентов и определенную логику повторного использования. Диаграммы прототипов часто видны непосредственно. элемента, кажется, фронтенд инженеру нужно только скопировать и вставить CSS без мозгов скопировать и вставить идентичную страницу, но реальная ситуация не так проста.С одной стороны, как было сказано выше, копирование и вставка вставлять напрямую CSS не может отражать логику повторного использования дизайна на уровне внешнего кода, а CSS диаграмм прототипов часто использует абсолютное позиционирование. Фактический CSS должен учитывать адаптивность, адаптацию к нескольким устройствам и другие проблемы и не может быть передан напрямую использовать, так что этот дорожный факт Это не работает.

Основная причинаUI Инженеры проектируют на досках, а не на реальных компонентах.

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

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

Подводя итог, я думаю, что будущее сотрудничества должно выглядеть так:

На приведенном выше рисунке и внешний интерфейс, и пользовательский интерфейс совместно используют реестр компонентов, которыйРеестр компонентов, с одной стороны, интерфейс кода предоставляется разработчикам переднего плана, а с другой стороны — дизайнерам панель дизайна.Центр компонентовЗдесь команда может делиться и просматривать все компоненты, что является единой платформой для совместной работы.

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

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

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

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

Эта совместная модель, которую я называюКомпонентно-ориентированная модель НИОКР, а в настоящее время что-то вродеbit.dev/Такие продукты уже реализуют эту идею, но они лишь предоставляют инженерам компонентно-ориентированную платформу НИОКР, а дизайнерам не предоставили платформу проектирования.Направление развития.

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

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

Дилемма взаимодействия с данными

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

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

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

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

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

Кроме того, реализация общего внутреннего интерфейса CRUD сама по себе очень проста, но из-за разделения фронтенда и бэкенда язык также может быть другим.Когда фронтенд сталкивается с проблемами интерфейса, он должен договоритесь с серверной частью, и серверная часть внесет изменения. , реальность таковаПозвольте внешнему интерфейсу изучить внутренний CRUD и внести изменения непосредственно в серверную часть, что более эффективно, чем переговоры между интерфейсом и серверной частью., фундаментальная причина заключается в гибкости самого Restful, а вторая заключается в том, что простой внутренний бизнес запросов глубоко связан с внешним бизнесом, эта часть работы должна быть сведена к одному типу работы, и учитывая, что традиционный внутренний код CRUD в значительной степени может быть сгенерирован автоматически, поэтому то, что нам нужно сделать дальше, можно резюмировать следующим образом:Объединяйте задачи, выполняемые обычным внутренним бизнесом, с внешними заданиями и используйте улучшенный API + SDK + P/F/SaaS делает обычный серверный бизнес максимально автоматизированным + сервисно-ориентированным, тем самым устраняя традиционную внутреннюю работу CRUD и повышая эффективность всей системы.

Оглядываясь назад, если бэкенд хочет предоставить внешнему интерфейсу безопасный интерфейс для манипулирования данными, способ использования HTTP Path + Method явно недостаточно силен Реляционная модель данных — это математическая теория о множествах, которая находится в математике. способ описать это использоватьреляционная алгебраОписанный таким языком, метод описания, основанный на древовидной связи (HTTP Path — древовидное пространство имен) + метод (Get Post Delete Put и т. д.), слишком слаб для поддержки реальных операций с данными, но напрямую использует язык SQL. , с одной стороны - проблема с безопасностью (решается прокси + какие-то методы проверки авторизации, не ключ к проблеме), с другой - режим языка SQL слишком отделен от локали фронтенда , а фронтенд вынужден выполнять склейку строк, в отличие от языка запросов MongoDB, который гораздо лучше стыкуется с языком javascript, чем с SQL, и фронтенд-программисты могут писать оператор запроса очень естественным образом.

В то же время, основанный на режиме Restful, многие внутренние коды стали очень простыми CRUD-кодами.Многие коды предназначены для преобразования restful-интерфейсов в операторы SQL, и на эти скучные вещи тратится много времени.Снижается эффективность разработки. , эти простые операции должны быть автоматизированы.

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

но только поGraphQLДо сих пор не решил эти две проблемы:

  1. Код CRUD в эпоху Restful был преобразован в код преобразователя GraphQL, Бэкэнд по-прежнему нужно писать вручную, или для генерации кода используется инструмент codegen, и он все еще не свободен от оков шаблонного кода.
  2. Управление состоянием внешних запросов на данные: повторяющиеся проблемы с запросами, проблемы с обновлением зависимостей данных. . .

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

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

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

Учитывая особенности Интернета, я разделяю привязку состояния наЧистая фронтальная привязкаа такжеФронтенд и бэкэнд привязка, привязка первого происходит только во внешнем интерфейсе, например, привязка переменной внутри js и значения , тогда как последний включает привязку внешнего и внутреннего состояния, такие как список комментариев и привязка данных внутренних комментариев. (Более того, последнее программист не понял как привязку, потому что текущий инструмент по-прежнему использовал этот процесс как активную команду FETCH, не предусмотрев простую декларативную привязку, как интерфейсный фреймворк. Это тоже недостатки разработки, я думаю привязка передней и задней частей в будущем также должна быть такой же простой, как и чистые привязки переднего конца, а явный код HTTP-запроса устранен.)

Представьте себе такой сценарий: под статьей есть список комментариев, вы добавляете комментарий в поле для комментариев, затем, логически говоря,внешний интерфейс UI Список и внутренние данные комментариев должны иметь двустороннюю связь., список комментариев должен быть обновлен немедленно, но подход программиста внешнего интерфейса в настоящее время, скорее всего, будет явно писать логику, когда новый комментарий создается, вручную повторно запрашивать комментарий API, а затем обновляться, этот подход очень похоже на использование собственного DOM Он обрабатывает отношения привязки между интерфейсным интерфейсом и данными с помощью js, поддерживает состояние вручную и вручную вызывает интерфейс DOM С этой точки зрения пути разработки двух привязок аналогичны, за исключением этоФронтенд и бэкэнд привязкаПоследние два или три инструмента появляются.

Фреймворки, которые имеют дело с внешними и внутренними привязками, обычноReact Query(позиция открыта в 2019 году) иApollo GraphQL Client(Открыт в 2016 году). Все проблемы, которые они решают, используют декларативный синтаксис, имеют дело с интерфейсными и внутренними сценариями привязки, и все они основаны на GraphQL. Их часто называют инструментами управления состоянием для уровня данных. Чтобы лучше понять цель этой статьи, я называю этоВнешние и внутренние инструменты привязки данных.

вышеДилемма сотрудничества между дизайном и интерфейсомКомпонент совместной работы на основе потока, только один компонент упомянутых сотрудниц, но композитное приложение требует, чтобы эти компоненты объединены, чтобы заполнить страницу, в соответствии с этим сценарием более двух проблем, которые необходимо решить:

  1. Проблемы связывания компонентов и серверных данных.
  2. Чистая фронтальная привязка.

Фронтенд и бэкэнд привязка

Возьмем самый простой пример, форму для заполнения личной информации.В традиционном веб-мышлении, если используется фреймворк, r внутри компонента и форма<input>изvalueПривязка атрибута, когда пользователь нажимает кнопку «Отправить», выполняетonSubmitметод, данные используются в качестве тела внутри метода, а запрос POST отправляет данные на серверную часть.

Это нормально, но это мешает нам понять проблему.Проблема становится очень простой, если понимать ее «ориентированным на привязку» способом., мы связываем внутренние данные личной информации с внутренним состоянием компонента. Когда пользователь нажимает кнопку «Отправить», привязка находится в состоянииout of syncстатус, нажмите «Отправить» для синхронизации, введитеsyncусловие. Таким образом, становится понятной и ясной проблема взаимодействия данных между фронтом и бэкендом.

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

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

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

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

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

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

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

Давайте обсудим первый вопрос выше, как решить проблему, что бэкенд-программистам все еще приходится писать много кода GraphQL Resovler и тратить много времени.Очевидно, что, начиная со схемы базы данных, может быть какой-то дефолтный код Rosovler генерируется, но его должны написать программисты. Причина в том, что в коде Resolver, сгенерированном по умолчанию, часто отсутствуют некоторые вещи, связанные с конкретным бизнесом. Исходя из этого, идея соглашения о конфигурации может быть использована для предоставления пользователям по умолчанию возможности Resolver и предоставлять пользователям настраиваемые интерфейсы Custom Resolver.HasuraНекоторые работы были сделаны. Они также начинают с базы данных и соответствуют стратегии проверки авторизации для автоматического создания ворот API Unified GraphQL для различных форм передних вызовов, что значительно упрощает традиционный код Crud:

Исходя из этого, я предполагаю, что в будущем при разработке веб-приложений может появиться много поставщиков источников данных, таких какOneGraph - Build Integrations 100x FasterВ , преобразуйте часто используемые общедоступные API-интерфейсы в унифицированный шлюз GraphQL API для вызова, эти источники данных будут похожи на рынок, компоненты имеют рынок компонентов, а источники данных также имеют рынок источников данных.

Что касается рынка источников данных, каждый может публиковать на нем источники данных, и они могут использовать стратегию Pay For Privacy, такую ​​​​как Github, и, как и компоненты, они могут потребляться другими, и многие программисты могут быстро использовать унифицированный рынок источников данных. и компоненты для создания полнофункционального современного веб-приложения:

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

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

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

Благодаря поддержке источника данных PaaS традиционная работа с CRUD может быть в значительной степени устранена, а некоторые оставшиеся задачи конвергентны к фронтенду (фактически это эквивалентно слиянию фронтенда и бэкенда CRUD, но поскольку большая часть работа с CRUD автоматизирована, поэтому давайте по-прежнему будем называть такую ​​работу с возможностями полнофункциональной разработки веб-приложений «front-end»)

Это идея. Кроме того, есть режим разработки, который объединяет серверный и клиентский код. Типичные примеры:Blitz, тоже следует той же идее.В коде нет явного http-вызова, а запрос к базе данных делается напрямую через вызовы функций.Преимущество этого в том, что фронт и бэкенд слиты, но минусы все же есть несколько очевидно: поскольку нет слоя GraphQL, преобразование может объявить слишком много функций запроса, что переносит ответственность за обработку повторного использования запроса на программиста, и источник данных не подходит для подключения к нескольким терминалам. Конец и внешний интерфейс слишком глубоки, и их нелегко извлечь Если мобильное приложение и веб-страница зависят от этого источника данных, непросто справиться с разделением внешнего и внутреннего интерфейса. Лично я думаю, что у этого метода высокая степень агрегации на фронте и бэкенде, и клиент только один (например, только Он больше подходит, когда нет мобильного приложения), и применимые сценарии узки.

Проблемный

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

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

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

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

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

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

На изображении выше веб-приложение зависит отForm Widgetа такжеSidebar Widget, которые, в свою очередь, зависят от болееButtonкомпоненты, и когдаButtonПосле обновления компонента, например версии из3.2.1мигрировал в3.2.2,В этот моментWeb AppСамо приложение естьне получит это уведомление, он должен один раз вручную перезапустить конвейер, чтобы получить обновленные зависимости.3.2.2Упакован в готовый продукт.

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

Метод выпуска и обновления npm на основе версий, хотя сама семантическая версия может играть базовый контроль над совместимостью пакетов и т. Д., Но по сути это джентльменское соглашение, и нет никакого способа, если пакет не соблюдает его. факт, о котором я упоминал выше. Было упомянуто, что современные веб-приложения, как правило, «Нет нумерации версий«Поскольку изменения исходного кода могут запускать обновления продукта с очень низкой стоимостью и с очень высокой скоростью, от схемы номеров версий можно отказаться. Если мы сможем легко отслеживать состояние любого компонента в любой момент времени в прошлом. , то Значение так называемого номера версии используется только для объявления узла, в котором происходят критические изменения.

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

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

Экология WebPack, Rollup и другие инструменты, состоит в том, чтобы позволить группе разработки наслаждаться преимуществами модуля, и может увеличить скорость загрузки и совместимость на одно файл боковой загрузки браузера, если мы больше не будем рассматривать модуль ES, приносит вопросы совместимости, Затем мы можем начать использовать и проверять использование и проверку ESM, а соответствующие инструменты появились, типичные примеры, такие какVite,Snowpackи т. д. Этот тип инструмента сборки можно назвать просто инструментом сборки без пакетов.

Но в настоящее время, взяв в качестве примера Vite, они включают только неупакованный режим в режиме разработки, а производственная среда по-прежнему использует упаковку.Причина в том, что в настоящее время используется esm в производственной среде, некоторые результаты тестов показывают, что это все еще будет влиять на производительность. Академия Хана попыталась выполнить полную миграцию esm, даже с благословением HTTP2 скорость загрузки все еще низкая:Отказаться от упаковки JS? Не так быстро (khanacademy.org)

Но есть также некоторые данные, которые показывают, что вполне нормально использовать esm в полном объеме, когда само приложение небольшое:Модули ES в производстве: мой опыт до сих пор | Bryan Braun - дизайнер / разработчик

В блоге Академии Хана упоминается, что снижение производительности полного esm в основном связано с некоторыми проблемами загрузки HTTP2 и увеличением накладных расходов на распаковку нескольких небольших файлов.Конечным результатом является то, что использование esm увеличивает загрузку ресурса. время от 0,6 с. По 1,7 с, окончательный вывод, что пакеты все еще рекомендуются для производства.

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

Потенциальные преимущества, которые может принести ЭСМ, следующие:

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

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

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

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

Статья 1. Глобальный кеш зависимостей означает, что существует множество пакетов, совместно используемых разными доменными именами и приложениями, напримерreact, после того, как эти пакеты будут загружены один раз, их не нужно загружать снова.По мере увеличения количества браузеров, используемых пользователями, локальный кеш будет становиться больше, и после посещения пользователями нового веб-сайта, новые зависимости, которые необходимо загрузить станет больше Предпосылкой этого является то, что эти веб-сайты используют один и тот же CDN, который должен быть оптимизирован для esm на стороне браузера и поддерживать новые протоколы, такие как HTTP2/3.Создание этого глобального кэша зависимостей еще больше сократит разрыв в производительности между esm и пакетом.

Первым, кто задумал эту идею, должен быть deno, изначально поддерживающий импорт по http и готовящийся к развитию импорта на основе cdn на стороне сервиса. ins., и CDN для модуля, для которого уже есть аналогичные продукты:Skypack: search millions of open source JavaScript packages.

Лично я смело предсказываю, что через пять лет веб-разработка, будь то разработка или производство, будь то сервер или клиент, примет модель CDN для импорта модуля + http, что принесет новый виток гибкой революции во внешнем интерфейсе. (Сейчас началось 😉)

Дилемма управления кодом

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

Делать это не очень интересно, да и принципиально проблему не решает. Мы ввели Monorepo, потому что хотим вносить изменения в некоторые пакеты одновременно, а потом выпускать обновления единообразно. Необходимо постоянно публиковать и обновлять использовать обновленные пакеты в других пакетах, но после введения Monorepo история коммитов смешивается с коммитами различных пакетов, что неудобно для отслеживания изменений определенного модуля, и соответствующий способ управления кодомGit — Подмодули (git-scm.com)В режиме репрезентативного подсклада родительский склад может зависеть от других подгит-складов, и коммит, сделанный на родительском складе, не попадет на дочерний склад.При этом при разработке родительского склада код дочерний склад можно модифицировать и даже коммитить, он хорошо сбалансированИмпортировано как зависимостьа такжехотите изменить в любое времяДва требования теста просты в использовании.

Жаль, что в такой экосистеме, как npm, выпущенные вещи и исходный код — это не одно и то же, а выпущенный пакет — это уже не Git-репозиторий, когда другие пакеты ссылаются на определенный пакет, говорить о том, есть разрешение на отправку определенного пакета. , сам по себе не может использоваться как субмодуль git. Даже если код будет помещен в репозиторий с исходным кодом, он не вызовет обновление пакета, и его необходимо выпустить вручную. Это связанный с методом управления зависимостями, основанным на репозитории git + реестре git на языке Go, Напротив, я лично считаю, что это также серьезный провал дизайна npm.

Я думаю, что новый режим управления пакетами должен быть привязан к репозиторию Git. Ссылаясь на язык Go, мы используем Git для управления кодом. Пакет, опубликованный в реестре, по-прежнему является репозиторием Git, просто удаленной историей. зависимость, он будет собран вместе с продуктом сборки (git clone --depth 1 извлекает последний снимок), и если вы хотите изменить пакет на лету и отправить обновление, вы можете использовать предоставленную новую команду: линейный инструмент git преобразует зависимость в режим подмодуля git.После преобразования он станет подмодулем git, и вы можете изменять пакет в режиме реального времени.

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

Поэтому я думаю, что центром управления пакетами будущего может быть:

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

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

Суммировать

Соберите упомянутые выше технические идеи в общую картину:

Я Ню Дай, инженер команды ByteDance Web Infra. Наша команда стремится изменить модель веб-разработки и возглавить модель веб-разработки в следующем десятилетии. Другие статьи о нашей команде:

Шаг в современную веб-разработку (полный текст выступления на GMTC 2021 «Современная практика веб-разработки Byte Beat») Настоящее и будущее современной веб-разработки (полный доклад JSDC 2019)

Домашняя страница команды:ByteDance Web Infra Teamwebinfra.org/

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

Лучший способ предсказать будущее — создать его!

Добро пожаловать, чтобы отправить свое резюме на мою электронную почту niudai.geek@bytedance.com Для подходящих студентов я буду использовать систему для продвиженияПроцесс инициирует собеседование, и студенты в направлении инженеров и менеджеров по продуктам могут оставить свои резюме ~ Вы также можете поговорить со мной в частном порядке для получения подробностей ~ **