Проектирование и создание прогрессивного веб-приложения без фреймворка (часть 3)

Опубликовано: 2022-03-10
Краткое резюме ↬ Эта статья завершает серию из трех частей о испытаниях и невзгодах проектирования и написания простого веб-приложения с помощью ванильного JavaScript. В первой части мы рассмотрели почему, во второй части в основном было рассмотрено как, а эта часть завершается рассмотрением того, как проект подходил к завершению, и чему научился этот опыт.

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

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

В этой заключительной части мы рассмотрим превращение базового веб-приложения в прогрессивное веб-приложение (PWA) и «отгрузку» приложения, а затем рассмотрим наиболее ценные уроки, полученные при создании простого веб-приложения In/Out:

  • Огромное значение методов массива JavaScript;
  • Отладка;
  • Когда вы единственный разработчик, вы являетесь другим разработчиком;
  • Дизайн — это разработка;
  • Текущие проблемы с обслуживанием и безопасностью;
  • Работать над сторонними проектами, не теряя рассудка, мотивации или и того, и другого;
  • Доставка некоторых товаров лучше, чем доставка без товаров.

Итак, прежде чем рассматривать извлеченные уроки, давайте посмотрим, как превратить простое веб-приложение, написанное на HTML, CSS и JavaScript, в прогрессивное веб-приложение (PWA).

Что касается общего времени, затраченного на создание этого небольшого веб-приложения, я бы предположил, что оно составило около двух-трех недель. Однако, поскольку это делалось по вечерам отрезками по 30-60 минут, на самом деле прошло около года с момента первого коммита до того момента, когда я загрузил то, что я считаю версией «1.0» в августе 2018 года. Поскольку я получил приложение ' функция завершена», или, проще говоря, на этапе, которым я был доволен, я ожидал большого финального рывка. Видите ли, я ничего не сделал для превращения приложения в прогрессивное веб-приложение. Оказывается, это была самая легкая часть всего процесса.

Еще после прыжка! Продолжить чтение ниже ↓

Создание прогрессивного веб-приложения

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

Чтобы получить представление о том, как работает ваше веб-приложение, вашей первой остановкой, вероятно, должны быть инструменты Lighthouse в Google Chrome. Вы можете найти аудит Progressive Web App на вкладке «Аудит».

Это то, что сказал мне Маяк, когда я впервые пробежал через него In/Out.

Инструменты разработчика Chrome показывают результаты Progressive Web App 55/100
Первоначальные оценки Progressive Web App не были высокими. (Большой превью)

В начале In/Out получил всего 55100 баллов за прогрессивное веб-приложение. Тем не менее, я довел его до 100100 менее чем за час!

Целесообразность улучшения этого показателя была мало связана с моими способностями. Это было просто потому, что Маяк точно сказал мне, что нужно было сделать!

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

Создание нескольких изображений домашнего экрана, создание файла манифеста и добавление набора метатегов может показаться сложной задачей менее чем за час, но есть замечательные веб-приложения, которые помогут вам создавать веб-приложения. Как это приятно! Я использовал https://app-manifest.firebaseapp.com. Отправьте ему некоторые данные о вашем приложении и логотипе, нажмите «Отправить», и он предоставит вам zip-файл, содержащий все, что вам нужно! С этого момента это просто время копирования и вставки.

Вещи, которые я откладывал какое-то время из-за недостатка знаний, такие как Service Worker, также были добавлены довольно легко благодаря многочисленным сообщениям в блогах и сайтам, посвященным сервис-воркерам, таким как https://serviceworke.rs. Наличие работника службы означало, что приложение могло работать в автономном режиме, что является необходимой функцией прогрессивного веб-приложения.

Хотя это и не связано строго с созданием приложения как PWA, вкладка «Покрытие» в Chrome Dev Tools также оказалась очень полезной. После стольких спорадических итераций по дизайну и коду в течение нескольких месяцев было полезно получить четкое представление о том, где был избыточный код. Я нашел несколько старых функций, разбросанных по кодовой базе, о которых я просто забыл!

Вкратце, проработав рекомендации аудита Lighthouse, я почувствовал себя любимчиком учителя:

Получение 100/100 по аудиту Lighthouse Progressive Web App
Lighthouse позволяет легко получить хорошие оценки, сообщая вам, что именно нужно изменить. (Большой превью)

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

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

Ретроспектива

Прошли месяцы с момента остановки разработки моего маленького веб-приложения.

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

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

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

Дизайн — это разработка

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

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

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

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

Это, как и понятие «гениального» программиста, является мифом. Если вы новичок в дизайне, но пробуете свои силы, я бы посоветовал вам не зацикливаться на первой идее, которая вас взволновала. Пробовать вариации так дешево, так что используйте эту возможность. Ничего из того, что мне нравится в дизайне In/Out, не было в первых проектах.

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

Вы другой разработчик в своем проекте

Я не уверен, относится ли это к проектам, над которыми работают время от времени, но я сделал следующее безрассудное предположение:

«Мне не нужно ничего документировать, потому что это всего лишь я, и, очевидно, я пойму это, потому что я это написал».

Нет ничего более далекого от правды!

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

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

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

Отладка

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

Оказывается, это произошло из-за ошибки в Safari, которую еще предстоит исправить. Оказывается, в Safari, если у вас есть:

 * { user-select: none; }

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

 * { user-select: none; } input[type] { user-select: text; }

Именно такой подход я использую в своем сбросе CSS «App Reset». Тем не менее, действительно разочаровывающая часть этого заключалась в том, что я уже выучил это и впоследствии забыл. Когда я, наконец, добрался до проверки отслеживания ошибок WebKit во время устранения проблемы, я обнаружил, что написал обходной путь в ветке отчетов об ошибках более года назад вместе с сокращением!

Хотите строить с данными? Изучите методы массива JavaScript

Возможно, самым большим достижением в моих навыках JavaScript стало знакомство с методами JavaScript Array. Теперь я использую их ежедневно для всех моих итераций и манипуляций с данными. Я не могу не подчеркнуть, насколько полезными являются такие методы, как map() , filter() , every() , findIndex() , find() и reduce() . С ними можно решить практически любую проблему с данными. Если в вашем арсенале их еще нет, добавьте https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array в закладки и приступайте к изучению, как только сможете. Мой собственный список моих любимых методов массива задокументирован здесь.

ES6 представил другие средства экономии времени для манипулирования массивами, такие как Set , Rest и Spread . Побалуйте меня, пока я поделюсь одним примером; раньше было куча фаффа, если вы хотели удалить дубликаты даже из простого плоского массива. Уже нет.

Рассмотрим этот простой пример массива с повторяющейся записью «Mr Pink»:

 let myArray = [ "Mr Orange", "Mr Pink", "Mr Brown", "Mr White", "Mr Blue", "Mr Pink" ];

Чтобы избавиться от дубликатов с помощью ES6 JavaScript, теперь вы можете просто сделать:

 let deDuped = [...new Set(myArray)]; // deDuped logs ["Mr Orange", "Mr Pink", "Mr Brown", "Mr White", "Mr Blue"]

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

Обслуживание и безопасность

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

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

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

Несколько месяцев мой package.json выглядел так:

 { "dependencies": { "gulp": "^3.9.1", "postcss": "^6.0.22", "postcss-assets": "^5.0.0" }, "name": "In Out", "version": "1.0.0", "description": "simple utility to see who's in and who's out", "main": "index.js", "author": "Ben Frain", "license": "MIT", "devDependencies": { "autoprefixer": "^8.5.1", "browser-sync": "^2.24.6", "cssnano": "^4.0.4", "del": "^3.0.0", "gulp-htmlmin": "^4.0.0", "gulp-postcss": "^7.0.1", "gulp-sourcemaps": "^2.6.4", "gulp-typescript": "^4.0.2", "gulp-uglify": "^3.0.1", "postcss-color-function": "^4.0.1", "postcss-import": "^11.1.0", "postcss-mixins": "^6.2.0", "postcss-nested": "^3.0.0", "postcss-simple-vars": "^4.1.0", "typescript": "^2.8.3" } }

И к июню 2019 года я получил следующие предупреждения от GitHub:

Интерфейс GitHub, подчеркивающий проблемы безопасности с зависимостями инструментов сборки
Хранение зависимостей в списке на GitHub означает нечастые предупреждения безопасности. (Большой превью)

Ни один из них не был связан с плагинами, которые я использовал напрямую, все они были зависимостями инструментов сборки, которые я использовал. Таков обоюдоострый меч пакетов JavaScript. Что касается самого приложения, проблем с вводом/выводом не было; который не использовал ни одну из зависимостей проекта. Но поскольку код был на GitHub, я чувствовал себя обязанным попытаться все исправить.

Пакеты можно обновлять вручную, внеся несколько изменений в package.json. Однако и Yarn, и NPM имеют свои собственные команды обновления. Я решил запустить yarn upgrade-interactive , что дает вам простой способ обновлять вещи из терминала.

Интерфейс командной строки для обновления пакетов с помощью Yarn
Yarn делает обновление зависимостей проекта немного более предсказуемым. (Большой превью)

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

Вы можете добавить флаг --latest для обновления до самой последней основной версии зависимостей, а не только до последней исправленной версии. За копейки…

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

Ошибка сборки gulp
Ошибка сборки Gulp (большой предварительный просмотр)

Таким образом, я откатил свой файл package.json и повторил попытку, на этот раз без флага --latest . Это решило мои проблемы с безопасностью. Не самый веселый вечер понедельника, хотя, честно говоря.

Это затрагивает важную часть любого стороннего проекта. Будьте реалистичны в своих ожиданиях.

Сторонние проекты

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

Было бы ложью сказать, что создание этого крошечного приложения в свободное время было увлекательным. Были случаи, когда я жалею, что никому об этом не говорил. Но теперь это сделано, я на 100% убежден, что это стоило потраченного времени.

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

Простая постановка целей

Вам не нужен причудливый процесс для постановки целей. Но это может помочь разбить все на маленькие/короткие задачи. Такие простые вещи, как «написать CSS для выпадающего меню», вполне достижимы за ограниченное время. В то время как «исследование и внедрение шаблона проектирования для управления состоянием», вероятно, не является. Сломай вещи. Затем, как и в Lego, крошечные детали собираются вместе.

Думая об этом процессе как о решении более крупной проблемы, я вспоминаю известную цитату Билла Гейтса:

«Большинство людей переоценивают то, что они могут сделать за один год, и недооценивают то, что они могут сделать за десять лет».

Это от человека, который помогает искоренить полиомиелит. Билл знает свое дело. Слушайте Билла все.

Доставка чего-либо лучше, чем доставка ничего

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

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

За месяцы, прошедшие с тех пор, я понял, что эти недостатки на самом деле не имеют значения. Не совсем.

Я фанат этой цитаты Гельмута фон Мольтке.

«Ни один план операций не выходит за рамки первого контакта с главными силами противника».

Это было перефразировано как:

«Ни один план не выдерживает первого контакта с противником».

Возможно, мы можем свести это к минимуму и просто сказать «дерьмо случается»?

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

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

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

В частности, с точки зрения разработки я хотел изучить основы построения веб-приложения. С точки зрения дизайна, я хотел попробовать решить некоторые (хотя и простые) дизайнерские проблемы для себя. Создание этого небольшого приложения позволило решить эти проблемы, а затем и некоторые другие. JavaScript для всего приложения весил всего 5 КБ (сжатый gzip). Небольшой размер файла, с которым мне было бы трудно справиться с любой структурой. За исключением, может быть, Свелте.

Если вы ставите перед собой задачу такого рода и ожидаете, что в какой-то момент что-то «отгрузите», запишите с самого начала, почему вы это делаете. Держите эти причины в центре внимания и руководствуйтесь ими. Все в конечном счете является своего рода компромиссом. Не позволяйте высоким идеалам парализовать вас от завершения того, что вы намеревались сделать.

Резюме

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

Вещи, о которых я сожалел

Как уже упоминалось, я был разочарован тем, что не остановился на том, что считал более элегантным методом изменения состояния приложения и рендеринга его в DOM. Шаблон наблюдателя, как обсуждалось во второй части этой серии статей, который предсказуемым образом решал так много проблем, в конечном итоге был отброшен в сторону, поскольку «отгрузка» проекта стала приоритетом.

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

Улучшение входа/выхода

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

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

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

Возможности

Использование localStorage работало для моих упрощенных нужд, но было бы неплохо иметь «правильное» хранилище данных, чтобы не нужно было беспокоиться о резервном копировании данных. Добавление возможности входа в систему также откроет возможность совместного использования организации игры с другим человеком. Или, может быть, каждый игрок мог просто отметить, играет ли он сам? Удивительно, как много возможностей для исследования вы можете предусмотреть, исходя из таких простых и скромных начинаний.

SwiftUI для разработки приложений iOS также интригует. Для человека, который когда-либо работал только с веб-языками, на первый взгляд SwiftUI выглядит как то, что я осмеливаюсь попробовать. Скорее всего, я бы попробовал перестроить In/Out с помощью SwiftUI — просто чтобы было что-то конкретное для сборки и сравнения опыта разработки и результатов.

Итак, пришло время подвести итоги и дать вам версию всего этого TL;DR.

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

Дизайн повторяющийся, примите этот процесс.

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

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