# РЕДАКТИРОВАТЬ - Май 2018 г. - Я закрыл ReddReader, но надеюсь, что вы все же сможете кое-что узнать из процесса, который я подробно описал ниже!

Перед тем, как мы начнем

Чтобы сэкономить время некоторым людям, есть несколько вещей, которые я (и не буду) освещать в этой статье:

  • Это не учебное пособие от начала до конца - это углубленное изучение процесса, который я прошел при создании Reddreader; веб-приложение, которое очищает Reddit на предмет упоминания книг и каждую неделю отображает их на основе категорий субреддита. Надеюсь, вы извлечете уроки из моих процессов и ошибок, но это не упражнение по копированию и вставке.
  • Я поделюсь некоторым кодом / методами, которые использовал, но основное репо пока не является публичным. Package.json находится в конце этой статьи, если вы хотите знать точные версии каждой зависимости.
  • Основной используемый стек технологий - это MEAN с Angular 4.4 (универсальный), так что это все на JavaScript!

Кто я?

Я Джейк (https://www.reddit.com/user/jacobedawson/), фронтенд-разработчик из Сиднея для Studio 3T в Берлине, Германия. Я программировал 4 года, и я самоучка (без диплома по CS или формального обучения). По шкале от 1 до Вес Бос я может около 3, так что прислушивайтесь к любым советам, которыми я поделюсь с недоверием :)

Да, это ограбление HackerNewsBooks!

Несколько месяцев назад на сайте I ndieHackers появилась популярная публикация о веб-сайте под названием HackerNewsBooks, где инженер-программист Иван Делчев объяснил, как он создал приложение, которое извлекает из Hacker News ссылки на книги и в результате зарабатывает около 300 долларов в месяц. дохода - недостаточного, чтобы наверняка уйти на пенсию, но все же довольно неплохой кусок пассивных карманных денег. Поскольку я находился между проектами и всегда стремлюсь улучшить свои навыки программирования, создавая вещи, которые немного выходят за рамки моих возможностей, я подумал, что это отличная возможность применить эту концепцию к Reddit, так как я провожу кучу времени на сайте и люблю самородки рекомендательного золота, которые появляются каждый день.

Копия, копия, копия…

Видимо, я не первый, кто пытается сделать скребок для книг на Reddit :) На самом деле я рад, что когда я впервые решил создать этот проект, я не искал другие похожие сайты, иначе я, вероятно, оказался бы деморализованы и переходят к чему-то другому. Я не заметил другие сайты до тех пор, пока пару недель спустя, и к тому моменту я уже был вложен в завершение проекта. Я понял, что когда вы решаете что-то построить и обнаруживаете, что кто-то уже сделал что-то подобное, вы можете в конечном итоге подумать: «Какой в ​​этом смысл?». Что ж, если проект гигантский, тогда стоит искать конкурентов заранее, но если это всего лишь побочный проект, вам лучше просто придерживаться цели независимо от аналогичных продуктов. Когда вы закончите, вы можете осмотреться и увидеть, как другие люди реализовали ту же концепцию.

Вот пара ссылок на эти другие проекты, если вам интересно увидеть различные варианты парсера для книг Reddit:



Http://reddittopbooks.com

Почему я решил сделать это

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

Планируем проект, выбираем технику

Первое, что я сделал после прочтения этой статьи, это обрисовал в общих чертах подход, который, как я думал, потребуется для достижения этого в моем текущем стеке (MEAN), и посетил веб-сайт HackerNewsBooks (HNB), чтобы попытаться получить более глубокое понимание. Я также обрисовал в общих чертах, что, по моему мнению, будет основными проблемами, включая этот список:

  • Поиск субреддитов с достаточным количеством поданных книг
  • Разбор / поиск текста
  • Создание подходящей структуры БД
  • Установка критериев того, годна ли книга для включения в список
  • Дедупликация результатов
  • Убедитесь, что ссылка относится к настоящей книге (а не к другому продукту).

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

В дополнение к этим задачам я также составил список требований:

  • Сайт с обновленными списками
  • Еженедельная рассылка новостей
  • Партнерские ссылки
  • Сервер
  • Базовый маркетинг
  • Гугл Аналитика
  • Удобство для мобильных

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

Очистка Reddit (вид)

Хотя Иван использовал Python для создания HNB, первое, что мне нужно было сделать, это решить, как собирать данные из Reddit с помощью JS. Здесь я мог пойти двумя путями - использовать комбинацию вроде Cheerio & Request для запроса страниц и последующего синтаксического анализа HTML на сервере, или использовать Reddit API для извлечения более структурированных данных, а затем их очистки. Хотя есть действительно отличная оболочка Python для Reddit API с именем Praw, я не был уверен, есть ли что-то похожее по качеству для JS. К счастью, я нашел Snoowrap, JS-оболочку, которая предлагает чистый перехватчик Reddit API и отличную документацию. Хотя получение данных через Snoowrap технически не может квалифицироваться как полный веб-скрейпинг, каждый блок данных публикации все равно нужно было очистить и проанализировать на наличие ссылок, так что это моя история, и я придерживаюсь ее.

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

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

«Сначала заставьте это работать, затем исправьте и, наконец, сделайте это быстро».

Чтобы проанализировать результаты для ссылок Amazon, я просто использую простой RegEx, который включает варианты smile.amazon и amzn, а затем очищаю эти ссылки от случайных символов, которые появлялись:

Партнерская программа Amazon / API для рекламы продуктов

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

Поскольку проект работает на Node, я поискал JS-оболочку для Amazon Product Advertising API и нашел хорошую: https://github.com/t3chnoboy/amazon-product-api

Благодаря этому я могу найти продукт с идентификатором элемента (который я разбираю по ссылкам Amazon в «успешных» сообщениях), а затем вернуть результаты, содержащие ISBN, чтобы убедиться, что Reddreader не заполняется. со ссылками на кроссовки с флагом США и светящиеся в темноте презервативы или наоборот.

Процесс проектирования и вдохновение

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

Для создания макетов дизайна я обычно сначала набрасываю что-то на бумаге, а затем либо кодирую макет прямо в браузере, либо создаю очень простой каркас в чем-то вроде Balsamiq. Что касается Reddreader, я впервые попробовал MarvelApp, и на самом деле он оказался довольно простым в использовании и очень чистым. Другие варианты включают InVision, Zeplin и Sketch, хотя, к сожалению, пользователи Windows не могут использовать Sketch.

Наличие макета - будь то на бумаге или в Интернете - может действительно ускорить процесс создания макета, поскольку вы можете «разбить» свой дизайн на части, которые в основном сообщают вам, какие компоненты будут необходимы, и дадут вам общее представление о правила / методы CSS, которые вы будете использовать для каждого сегмента.

Несмотря на то, что я всегда создаю какие-то макеты, я никогда не создаю полную версию макета в Photoshop и компании. Мне нравится кодировать дизайн прямо в браузере, так как я сразу получаю отзывы о том, что увидит пользователь, вплоть до точных размеров и разрешения. Chrome Dev Tools отлично подходит для этого, поскольку вы можете использовать адаптивные представления и представления устройства, а также различные соотношения пикселей устройства. Одна вещь, которую я также узнал, - это как можно быстрее собрать основные строительные блоки, прежде чем настраивать их. Ниже вы можете увидеть очень грубый ранний макет, созданный на основе Bootstrap 4:

Инструмент, который мне также очень нравится, - это расширение Chrome под названием Pesticide. Пестициды накладываются на сетку поверх вашего веб-сайта, позволяя вам увидеть, как создается каждый блок и как он сочетается друг с другом. В сочетании с адаптивным макетом Dev Tools это похоже на использование рентгеновских очков при тестировании закодированных дизайнов.

Создание приложения Angular

Я использую Angular в течение последнего года, сразу после того, как вышла вторая версия. Сейчас мы почти подошли к версии 5, и, хотя иногда бывает сложно найти свежую документацию, в сочетании с Angular CLI разработка в целом идет довольно гладко. Angular CLI абстрагирует большую часть проводки, которая раньше выполнялась вручную, например, импорт компонентов в модули и написание стандартного кода. Как только вы начнете использовать интерфейс командной строки для разработки, я не могу себе представить, чтобы кто-то захотел вернуться к написанию всего этого установочного кода вручную. Я также сохраняю настройку Webpack по умолчанию, так как я не дотянул до уровня, требующего очень специфического процесса сборки, помимо стандартного конвейера SCSS для CSS / минификации / префикса. Тем не менее, стоит отметить, что конфигурацию Webpack можно« выбросить » для тех из вас, кто хочет запачкать руки.

С Angular писать компоненты очень просто, и хорошо, что все, связанное со стилем, имеет область видимости. Я пишу несколько глобальных стилей и переменных в папке Sass, создаю некоторые компоненты для таких вещей, как карточки и кнопки, а для всего остального, связанного со стилями, я записываю их в файл .scss компонента (который позже компилируется в обычный CSS).

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

Экспресс-сервер / API

Когда я начал планировать Reddreader, я знал, что мне понадобится какой-то API, и сначала я думал об использовании GraphQL, но когда я начал записывать требования, я понял, что мне нужно всего около 3 отдельных вызовов API, и поскольку у меня есть опыт работы с Express / Express Router Я решил придерживаться этого, оставив GraphQL для другого проекта, где я смогу вникнуть в него немного глубже.

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

Reddreader на самом деле не требует слишком многого "под капотом": около трех вызовов API, некоторые модели Mongoose и логика синтаксического анализа Reddit / Amazon. Все включено, я думаю, что код на стороне сервера составляет ~ 600 loc.

Подключение к услугам

Во внешнем интерфейсе я использую пару сервисов Angular для взаимодействия с API. Мне действительно нравится разделение задач при использовании сервисов, а также это обеспечивает простоту внутрикомпонентного взаимодействия. Хотя я использовал EventEmitter для пары простых задач, основная архитектура включает в себя компонент Home (основной контейнер), взаимодействующий с одной службой Post, которая использует HttpClient для запроса данных с сервера через вызовы API:

Cron Jobs для автоматизированных серверных задач

К этому моменту функции, которые вызывали Reddit API, запускались вручную, что хорошо для тестирования и настройки, но не собиралось работать в дальнейшем. Самое замечательное в кодировании - это возможность назначать компьютеру рутинные, повторяемые задания, и это именно то, для чего нужна cron job. Раньше я фактически не работал с задачами cron в NodeJS, но после быстрого поиска в Google я нашел хороший пакет под названием node-cron (https://github.com/kelektiv/node-cron), который использует стандартный cron. синтаксис в сочетании со стандартными функциями обратного вызова Node:

var CronJob = require('cron').CronJob;
var job = new CronJob('00 30 11 * * 1-5', function() {
  /*
   * Runs every weekday (Monday through Friday)
   * at 11:30:00 AM. It does not run on Saturday
   * or Sunday.
   */
  }, function () {
    /* This function is executed when the job stops */
  },
  true, /* Start the job right now */
  timeZone /* Time zone of this job. */
);

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

 ┌───────────── minute (0 - 59)
 │ ┌───────────── hour (0 - 23)
 │ │ ┌───────────── day of month (1 - 31)
 │ │ │ ┌───────────── month (1 - 12)
 │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
 │ │ │ │ │                                       
 (7 is also Sunday on some systems)
 │ │ │ │ │
 │ │ │ │ │
 * * * * *  command to execute

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

Давайте жить!

Большое спасибо Джейсону Ленгсдорфу и его фантастическому руководству по настройке Let's Encrypt на сервере Digital Ocean. Честно говоря, это руководство мне очень помогло, сделав установку бесплатного сертификата SSL сносной и на самом деле довольно забавной. Следуя руководству, вы пройдете через настройку сервера с использованием Ubuntu, создание привилегированных пользователей в Linux, добавление ключей SSH, усиление защиты сервера, настройку NGINX и Let's Encrypt и многое другое. Я не могу сказать достаточно хороших слов об этом сообщении в блоге, это спасение жизни.

Для базы данных MongoDB я решил попробовать Атлас MongoDB - у них есть бесплатная песочница на 500 МБ, которая предлагает сегментированные кластеры и несколько хороших панелей мониторинга. Я подключился к удаленной базе данных через Studio 3T, так как это лучшая среда разработки MongoDB на рынке. И они платят мне, потому что я работаю на них # предвзято

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

Вернуться к доске для рисования

Ну, это длилось пару дней. Мне не потребовалось много времени, чтобы понять, что Reddreader нельзя сканировать для целей SEO, и что структура, которую я выбрал для базы данных, на самом деле не очень гибкая. На самом деле я полностью упустил из виду добавление рендеринга на стороне сервера, а также понял, что структура URL / API не собирается сокращать его в дальнейшем, поскольку я очищал Reddit каждую неделю, а также надеялся очищать его каждый день. Мне нужно было переписать базу данных и преобразовать приложение в Angular Universal.

Переход на Angular Universal для SSR

Что ж, таково состояние JS в 2017 году. Мы перешли от кода, отрисованного на стороне сервера, к клиентским SPA, а теперь появилось какое-то странное детище, которое влечет за собой рендеринг на стороне сервера, чтобы успокоить бога Google и рендеринг на стороне клиента SPA. для всего после начальной загрузки страницы. Вот техническая схема текущей ситуации:

Хотя иногда Google может сканировать SPA, это не означает, что предварительный просмотр Twitter или Facebook будет работать, и я слышал множество историй о веб-сайтах, которые просто отображаются как «… загрузка» в результатах поиска. Существуют такие службы, как Prerender.io, которые предлагают обрабатывать ваши страницы и предоставлять их Google, но это платная услуга (выше порогового значения) и оставляет вас в долгу перед еще одной третьей стороной, поэтому я решил включить SSR сам.

Текущее решение для реализации отрисованных на стороне сервера веб-сайтов с полной поддержкой SEO в экосистеме Angular - это Angular Universal. Это работает, и я думаю, это только начало, но, по сути, мы добавляем кучу дополнительных обходных путей поверх нашего SPA, чтобы заставить его работать ... вроде как веб-сайт из 2007 года. Вдобавок ко всему, как и я в настоящее время мне обычно нравится разрабатывать с Angular, документация не совсем лучшая в своем классе, особенно документы Angular Universal, которые (на момент написания) все еще ссылаются на Angular 2. Мне кажется странным, что такая большая компания У Google есть такая неутешительная документация для своего флагманского фреймворка, поэтому изучение того, как реализовать SSR, потребовало некоторого изучения Udemy и небольшого количества поисков.

От машинописного текста обратно к JS

Проблема, с которой я столкнулся сразу, заключалась в том, что я начал этот проект с идеей запустить полный стек Typescript и использовал это довольно крутое репо в качестве основы: https://github.com/DavideViolante/Angular-Full-Stack. Однако, когда я попытался реализовать SSR, я начал сталкиваться с ошибками, связанными с импортом модулей на стороне сервера. Я, наверное, что-то там пропустил, но никак не мог понять. В конце концов я оказался в тупике, поэтому мне пришлось де-TypeScript мой сервер, и в итоге он оказался ванильным JS на сервере.

В конце концов, добавление Angular Universal - не такая уж большая проблема. Вы можете пройти 95% пути практически с любым стандартным проектом Angular 4 / CLI, следуя этому руководству: https://github.com/angular/angular-cli/wiki/stories-universal-rendering. Они проводят вас через процесс пошагово, и по сути вы разделяете свое приложение на 2 модуля, а затем говорите серверу обслуживать один при начальной загрузке страницы со всем предварительно обработанным HTML перед переходом к рендерингу на стороне клиента. при последующих загрузках страницы.

Поскольку вы создаете две версии своего приложения, вы в конечном итоге объединяете две версии - обычно одну в стандартную папку / dist, а другую в папку / dist-server. Вы должны указать серверу (в моем случае Express) обслуживать пакет по имени, что является своего рода проблемой, потому что каждый раз, когда вы создаете свой пакет, он имеет другое хеш-имя. Юк. Один из удобных приемов, с которыми я столкнулся в Интернете, рекомендовал, как этого избежать, удалив выходное хеширование из пакета сервера, удалив хеш-имя. Вот пример того, как я удалил его в моей команде сборки package.json:

Вы отказываетесь от SEO?

Когда дело доходит до SEO, подготовка и запуск рендеринга на стороне сервера - это только начало. Следующими шагами были добавление Google Analytics (через Диспетчер тегов Google), добавление файла sitemap.xml на сайт и создание настраиваемых заголовков и описаний для каждой страницы, что можно было сделать программно с помощью сервисов Angular Meta & Title через модуль браузера платформы. Чтобы не победить дохлую лошадь, но, опять же, документация по Angular иногда бывает настолько скудной, что нелегко найти канонический способ достижения определенных результатов, особенно когда вы добавляете SSR в микс.

Раньше я работал в области SEO, и теперь это скучная, но необходимая уборка, которую нужно сделать, чтобы ваш сайт был презентабельным для пауков поисковых систем (и был обнаружен при поиске в Интернете). Вдобавок к этому вы можете (и, вероятно, должны) добавить данные Open Graph для крупных игроков в социальных сетях, включая Twitter, Facebook и Google.

Дубликаты, дубликаты и чертовы дубликаты

Вот кое-что, над чем можно посмеяться, если ужасные, ужасные кошмары, связанные с программированием, заставят вас смеяться. В MongoDB обнаружена серьезная ошибка, связанная с предотвращением дублирования на основе уникальных индексов в одном и том же родительском документе, зарегистрированном на 7 лет и более g:

Хотя утверждалось, что это не ошибка, а именно то, как работает MongoDB, эта проблема вызвала у меня несколько часов поиска в Google, StackOverflow и ругани, прежде чем я укусил пулю и реорганизовал свою базу данных. Хорошие времена. Я получал дублирующиеся сообщения по всему суставу, и это убивало меня.

Главный вывод здесь заключается в том, что MongoDB хорош в определенных вещах, таких как хранение неструктурированных документов, и не очень хорош в выполнении других вещей, которые люди обычно связывают с базами данных, таких как, например, объединение таблиц. MongoDB значительно улучшился, и есть методы, которые могут моделировать эти вещи (например, Populate или Aggregation Framework), но это приводит к тому, что, как мне кажется, я пренебрегал вначале - знайте, почему вы используете определенную технологию и что его ограничения есть. Это включает в себя просто знание того, в чем что-то хорошо, а не того, что можно сделать только с дополнительной головной болью. Я узнал еще кое-что о том, как работает MongoDB, но я также собираюсь потратить больше времени на выбор базы данных в следующий раз, в зависимости от того, чего я хочу достичь в проекте, вместо того, чтобы просто выбирать MongoDB по умолчанию.

После попытки заставить MongoDB распознавать уникальные индексы для поддокументов в пределах одного родителя, я отказался и переместил каждое сообщение в его собственную коллекцию, ссылаясь на каждую через ObjectID в списке с помощью атрибута «ref» и имитируя соединение с помощью метода Populate:

Этот подход на самом деле оказался довольно удачным, поскольку я могу применять уникальные ObjectIds в каждой коллекции и даже составные индексы, такие как (Subreddit + Week + Year), чтобы избежать дублирования контента. По-прежнему иногда возникает проблема, связанная с тем, что несколько сообщений в одном субреддите ссылаются на одну и ту же книгу, но на самом деле это естественный результат, поэтому я не пытаюсь удалить их в данный момент.

Вот как в итоге была устроена иерархия документов:

  • Каждую неделю создается единый Каталог, содержащий массив списков, например. результаты для / r / Fantasy.
  • Каждый список содержит массив сообщений для этого субреддита.
  • Наконец, каждое сообщение содержит встроенный массив ссылок, например. единый результат книги, включая ISBN, ссылку на Amazon, миниатюру книги, автора и название.

Ниже представлены 3 отдельные коллекции в моей базе данных MongoDB; Каталог ›Списки› Записи:

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

Реальный! Часть 2.

После реструктуризации базы данных и добавления SSR с помощью Angular Universal сайт снова был готов к работе. На этот раз все прошло хорошо, и сайт работал без ошибок. Тем не мение…

Случайные ошибки и странное браузерное дерьмо

Я больше не ожидаю, что какой-либо проект будет работать на 100% идеально с первого раза. Моя невинность была утеряна много лет назад, когда мой недавно собранный в домашних условиях ПК стоимостью 2000 долларов сгорел в забвении при первом запуске, потому что ... я почему-то не добавил 6 маленьких винтиков стоимостью 4 цента, чтобы отделить материнскую плату от корпуса . К счастью, в наши дни большинство ошибок менее опасно для жизни и их довольно легко исправить.

Хотя TDD определенно является умной игрой, в мире интерфейсов есть некоторые ошибки, которые вы можете найти только в природе. Возьмем, к примеру, указанную выше ошибку. После некоторого поиска в Google выясняется, что Safari, в частности, требуется полифил из-за неподдерживаемого решения для интернационализации Angular. Вы не можете сделать это дерьмо.

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

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

Настройка информационного бюллетеня Mailchimp

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

Я решил, что на этом этапе я буду использовать SendGrid или Mailchimp для сбора писем, и в итоге остановился на MailChimp. Используя API MailChimp (https://www.npmjs.com/package/mailchimp-api-v3), я подключил интерфейс через службу информационных бюллетеней для отправки ввода электронной почты на сервер, а затем отправил его на список рассылки Reddreader, который я создал на панели инструментов Mailchimp.

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

Следующие шаги

  • Есть еще некоторая очистка кода, а также несколько несоответствий, которые я хотел бы улучшить на сайте, поэтому следующие шаги - рефакторинг и оптимизация, добавление некоторых изюминок, таких как анимация и дополнительные страницы книг, и продолжение поиска субреддиты, у которых есть хороший запас рекомендаций по книгам.
  • Я хочу начать синтаксический анализ Goodreads и других ссылок.
  • Мне все еще нужно работать над динамическим обновлением описаний страниц на основе выбранного субреддита / недели.
  • Добавьте кнопку прокрутки вверх, которая отлично работает с SSR.
  • Я хотел бы добавить дополнительную информацию для каждой книги, например обзоры с GoodReads и аналогичных веб-сайтов с обзорами книг.
  • На продвинутом уровне можно найти все упоминания о книгах, независимо от того, связаны они или нет, но сейчас это намного выше моих возможностей. Я немного подумал о том, как это можно сделать - вы, вероятно, создадите коллекцию фраз, которые, как правило, предшествуют или следуют за авторами книг или названиями книг, например «написано» или «была хорошей книгой», а затем возьмите блок текста вокруг этой фразы. После этого вы, вероятно, могли бы запустить блок текста в базе данных или API названий книг или авторов, пока не найдете совпадение, а затем искать в Amazon API книги, соответствующие результатам. Я не уверен, что это вообще правильный подход.

Спасибо за чтение!

При создании Reddreader меня убедительно убедили в том, насколько сообщество программистов полагается на бесплатный обмен знаниями. Заставить код делать то, что работает, возможно только с помощью других, а также между StackOverflow, Reddit и фантастическими сообщениями в блогах, такими как руководство Ленгсдорфа Digital Ocean / Let's Encrypt или Простые английские объяснения Джоша Бима для MongoDB's Populate. понимание того, как заставить эти разрозненные технологии хорошо работать. Если вы начинающий программист или даже начинающий профессионал, все еще пытающийся разобраться в этой безумной экосистеме, я настоятельно рекомендую вам поделиться извлеченными уроками, когда придет время.

Спасибо, что нашли время и позволили мне поделиться своим опытом. Надеюсь, вы смогли чему-то научиться - будь то что делать или чего не делать!

Ваше здоровье,

Джейк

/ * ===== Дополнительные материалы ===== * /

Reddreader Package.json

Другие инструменты и расширения, которые я использовал

Wunderlist - плавный и простой список дел. Я использую Wunderlist каждый день.

Строгий рабочий процесс - таймер Помидора + отвлекающий блокировщик сайтов

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

Инструменты разработчика Chrome - нажмите F12 для совершенства

BrowserStack - Тестирование нескольких устройств и ОС онлайн

Стильный - индивидуальные темы для любого сайта. Сверните свой собственный. Темное все для полуночных программистов.

ColorZilla - Advanced Eyedropper, Color Picker, Gradient Generator и другие красочные вкусности.

Vimium - Просматривайте веб-страницы только с помощью клавиатуры. НАСТОЛЬКО полезно, когда вы к этому привыкнете.

Toggl - Мой тайм-трекер, для фриланса и сайд-проектов

Github - Убедитесь, что вы используете контроль версий, дети, не заканчивайте этим парнем.

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

MarvelApp - превращайте эскизы, макеты и дизайны в прототипы приложений для Интернета, iPhone, iOS, Android и Apple Watch.

Dribbble - Show & Tell для дизайнеров

Mailchimp - Автоматизация рассылки новостей

ConEmu - приятный Windows-терминал, который предлагает несколько интеграций (Powershell, GitBash и т. Д.) И просмотр с вкладками.

Visual Studio Code - бесплатный, фантастический и супер-расширяемый редактор кода. После того, как я попробовал Webstorm, Sublime & Atom, VSC покорил мое сердце.

MDN - Очень полная документация по веб-технологиям.

Социальные ссылки и проекты

"Подпишись на меня в Твиттере"

Проверьте мой Github

Тролли меня на Reddit

Практические технические интервью на Jumpjet

Найдите книги на Reddreader