Проектирование и создание прогрессивного веб-приложения без фреймворка (часть 3)
Опубликовано: 2022-03-10Еще в первой части этой серии мы объяснили, почему появился этот проект. А именно желание узнать, как можно сделать небольшое веб-приложение на ванильном JavaScript, и заставить разработчика, не занимающегося дизайном, немного поработать над своими дизайнерскими отбивными.
Во второй части мы взяли несколько базовых первоначальных проектов и запустили их, выбрав инструменты и технологии. Мы рассмотрели, как и почему изменились части дизайна, а также последствия этих изменений.
В этой заключительной части мы рассмотрим превращение базового веб-приложения в прогрессивное веб-приложение (PWA) и «отгрузку» приложения, а затем рассмотрим наиболее ценные уроки, полученные при создании простого веб-приложения In/Out:
- Огромное значение методов массива JavaScript;
- Отладка;
- Когда вы единственный разработчик, вы являетесь другим разработчиком;
- Дизайн — это разработка;
- Текущие проблемы с обслуживанием и безопасностью;
- Работать над сторонними проектами, не теряя рассудка, мотивации или и того, и другого;
- Доставка некоторых товаров лучше, чем доставка без товаров.
Итак, прежде чем рассматривать извлеченные уроки, давайте посмотрим, как превратить простое веб-приложение, написанное на HTML, CSS и JavaScript, в прогрессивное веб-приложение (PWA).
Что касается общего времени, затраченного на создание этого небольшого веб-приложения, я бы предположил, что оно составило около двух-трех недель. Однако, поскольку это делалось по вечерам отрезками по 30-60 минут, на самом деле прошло около года с момента первого коммита до того момента, когда я загрузил то, что я считаю версией «1.0» в августе 2018 года. Поскольку я получил приложение ' функция завершена», или, проще говоря, на этапе, которым я был доволен, я ожидал большого финального рывка. Видите ли, я ничего не сделал для превращения приложения в прогрессивное веб-приложение. Оказывается, это была самая легкая часть всего процесса.
Создание прогрессивного веб-приложения
Хорошая новость заключается в том, что когда дело доходит до превращения небольшого приложения на основе JavaScript в «прогрессивное веб-приложение», существует множество инструментов, облегчающих жизнь. Если вы вернетесь к первой части этой серии, вы помните, что быть прогрессивным веб-приложением означает соответствовать набору критериев.
Чтобы получить представление о том, как работает ваше веб-приложение, вашей первой остановкой, вероятно, должны быть инструменты Lighthouse в Google Chrome. Вы можете найти аудит Progressive Web App на вкладке «Аудит».
Это то, что сказал мне Маяк, когда я впервые пробежал через него In/Out.
В начале In/Out получил всего 55 ⁄ 100 баллов за прогрессивное веб-приложение. Тем не менее, я довел его до 100 ⁄ 100 менее чем за час!
Целесообразность улучшения этого показателя была мало связана с моими способностями. Это было просто потому, что Маяк точно сказал мне, что нужно было сделать!
Некоторые примеры необходимых шагов: включите файл manifest.json
(по сути, файл JSON, содержащий метаданные о приложении), добавьте целый ряд метатегов в заголовок, замените изображения, которые были встроены в CSS, на стандартные изображения со ссылкой на URL, и добавьте кучу изображений домашнего экрана.
Создание нескольких изображений домашнего экрана, создание файла манифеста и добавление набора метатегов может показаться сложной задачей менее чем за час, но есть замечательные веб-приложения, которые помогут вам создавать веб-приложения. Как это приятно! Я использовал https://app-manifest.firebaseapp.com. Отправьте ему некоторые данные о вашем приложении и логотипе, нажмите «Отправить», и он предоставит вам zip-файл, содержащий все, что вам нужно! С этого момента это просто время копирования и вставки.
Вещи, которые я откладывал какое-то время из-за недостатка знаний, такие как Service Worker, также были добавлены довольно легко благодаря многочисленным сообщениям в блогах и сайтам, посвященным сервис-воркерам, таким как https://serviceworke.rs. Наличие работника службы означало, что приложение могло работать в автономном режиме, что является необходимой функцией прогрессивного веб-приложения.
Хотя это и не связано строго с созданием приложения как PWA, вкладка «Покрытие» в Chrome Dev Tools также оказалась очень полезной. После стольких спорадических итераций по дизайну и коду в течение нескольких месяцев было полезно получить четкое представление о том, где был избыточный код. Я нашел несколько старых функций, разбросанных по кодовой базе, о которых я просто забыл!
Вкратце, проработав рекомендации аудита 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:
Ни один из них не был связан с плагинами, которые я использовал напрямую, все они были зависимостями инструментов сборки, которые я использовал. Таков обоюдоострый меч пакетов JavaScript. Что касается самого приложения, проблем с вводом/выводом не было; который не использовал ни одну из зависимостей проекта. Но поскольку код был на GitHub, я чувствовал себя обязанным попытаться все исправить.
Пакеты можно обновлять вручную, внеся несколько изменений в package.json. Однако и Yarn, и NPM имеют свои собственные команды обновления. Я решил запустить yarn upgrade-interactive
, что дает вам простой способ обновлять вещи из терминала.
Кажется достаточно простым, есть даже небольшая цветная клавиша, чтобы указать, какие обновления являются наиболее важными.
Вы можете добавить флаг --latest
для обновления до самой последней основной версии зависимостей, а не только до последней исправленной версии. За копейки…
Проблема в том, что в мире пакетов JavaScript все происходит быстро, поэтому обновление нескольких пакетов до последней версии, а затем попытка сборки привели к следующему:
Таким образом, я откатил свой файл 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 минут в день, можно добиться результатов. Этот факт верен, какую бы форму ни принимали ваши поиски.