или сотая статья с жалобами на веб-разработку

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

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

Затем появился Google IO 2018, и я наткнулся на отличное видео Джеффа Посника на многостраничных PWA. Идея фактического использования возможностей потоковой передачи браузера и написания универсального JavaScript, чтобы вы могли одновременно генерировать HTML с сервера для начальной загрузки или в качестве запасного варианта, а затем также генерировать его из сервис-воркера, казалась действительно новой идеей, чтобы сделать ваш приложение быстро и доступно. И все это при использовании очень небольшого количества библиотек, инструментов командной строки или сложных шагов/конфигураций сборки.

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

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

Проект

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

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

Проблемы

Универсальный JavaScript

Как упоминалось выше, я хотел написать JavaScript, который работал бы как в Node.js, так и в браузере. Поскольку Node.js поддерживает модули в экспериментальном режиме (при условии, что вы используете расширение .mjs), а большинство браузеров сейчас поддерживают его наивно, мне было удобно писать JavaScript в модулях, не полагаясь на инструменты сборки. Любой браузер, который не поддерживает модули, просто получит более статичный интерфейс, чем пользователи с отключенным JavaScript.

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

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

DOMпарсер

Первым реальным шагом в этом проекте был анализ RSS-канала выбранного подкаста для получения информации об эпизоде. Браузеры имеют интерфейс DOMParser, упрощающий разбор XML. К сожалению, в стандартной библиотеке Node.js ничего нет. После поиска в некоторых библиотеках на NPM я нашел одну с тем же API, что и DOMParser. Итак, когда пользователь ищет подкаст, я получаю канал, анализирую его, генерирую HTML и передаю его пользователю. Здорово! Теперь мне просто нужно сделать это из сервисного работника.

Это казалось довольно простым. Когда сервис-воркер был установлен, когда пользователь делал запрос информации об эпизоде, я просто перехватывал этот запрос. Вытащите информацию о том, какой подкаст они хотели. Принеси этот фид. И, наконец, проанализируйте XML, сгенерируйте HTML и передайте его в созданный ответ. Все от сервисного работника.

Поскольку я писал универсальный JavaScript, я подумал, что не будет проблемой просто подключить мой серверный код. Но, и вы можете видеть, к чему все идет, вы не можете делать вещи, связанные с DOM, в сервис-воркере. Кроме того, похоже, что DOMParser не является потокобезопасным — это тоже проблема. Я немного искал внешнюю библиотеку для разбора XML, которая работала бы в сервис-воркере (та, которую я использовал на стороне сервера, похоже, не работала), но не смог найти ничего с тем же API. Возможно, я был слишком придирчив, но я решил просто сдаться на этом этапе, потому что, пока я занимался этим, постоянно возникала другая, более крупная проблема, из-за которой я чувствовал, что этот проект бесполезен.

КОРС

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

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

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

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

Вывод

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

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

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