Статьи

Как я разработал и построил полный стек JavaScript Trello Clone

Несколько недель назад я столкнулся с разработчиком, делящим один из его побочных проектов на GitHub: клон Trello. Созданный с использованием React, Redux, Express и MongoDB, проект, казалось, имел много возможностей для работы с навыками полного стека JS.

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

Нильсон Жак, редактор


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

Прежде чем перейти к подходу, я уделю некоторое время обсуждению того, как:

  • Я определил свои цели перед началом проекта.
  • Я решил использовать технический стек.
  • Я установил приложение.

Имейте в виду, что, поскольку весь проект находится на GitHub ( madClones ), я сосредоточусь на дизайне и архитектуре, а не на реальном коде. Вы можете проверить живую демонстрацию текущего кода: вы можете войти с учетными данными Test / Test.

Скриншот полноценного клона Trello

Если вы хотите поднять свои навыки работы с JavaScript на новый уровень, зарегистрируйтесь в SitePoint Premium и ознакомьтесь с нашей последней книгой « Современный JavaScript»

Определение целей

Я начал с того, что занимал пару часов в день, чтобы подумать о своих целях и о том, чего я хотел достичь, создав приложение. Список дел был исключен, потому что он не был достаточно сложным. Я хотел посвятить себя хотя бы 4 месяцам серьезной работы (прошло уже 8 месяцев). После недели размышлений у меня возникла идея клонировать приложения, которые я люблю использовать ежедневно. Так клон Trello стал побочным проектом.

В итоге я хотел:

  • Создайте полноценное JavaScript-приложение. Выйдите из моей зоны комфорта и используйте другую серверную технологию.
  • Расширьте свои возможности по проектированию, проектированию, разработке, развертыванию и поддержке приложений с нуля.
  • Практикуйте TDD (развитие через тестирование) и BDD (развитие через поведение). TDD — это программная практика, которая требует от разработчика написания теста, отслеживания его неудач, а затем написания минимального кода для прохождения теста и рефакторинга (красный, зеленый, рефакторинг). BDD, с другой стороны, делает упор на разработку с использованием функций и сценариев. Его главная цель — быть ближе к бизнесу и написать язык, который они могут легко понять.
  • Узнайте последние и самые горячие фреймворки. На своей работе я использую angular 1.4 и node 0.10.32 (что очень печально, я знаю), поэтому мне нужно было быть ближе к горячим вещам.
  • Напишите код, который следует принципу 3R: читаемость, рефакторируемость и возможность повторного использования.
  • Веселиться. Это самый важный. Я хотел повеселиться и много экспериментировать, так как я был (и остаюсь) ответственным за проект.

Выбор стека

Я хотел построить сервер Node.js с Express и использовать базу данных Mongo. Каждое представление должно быть представлено документом, чтобы за один запрос можно было получить все необходимые данные. Основная битва была за выбор технологий переднего плана, потому что я много колебался между Angular и React.

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

Я начал с двух проверок концепции (POC): один в Angular 2, а другой в React. Независимо от того, рассматриваете ли вы одну как библиотеку, а другую — как основу, не имеет значения, конечная цель одна и та же: создать приложение. Дело не в том, кто они, а в том, что они делают. У меня было огромное предпочтение React, поэтому я решил двигаться дальше.

Начиная

Я начинаю с создания главной папки для приложения с именем TrelloClone. Затем я создаю папку на сервере, которая будет содержать мое приложение Express. Для приложения React я загружаю его с помощью приложения Create React .

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

  • src : код для работы приложения
  • src / config : все, что связано с конфигурацией (база данных, URL, приложение)
  • src / utils : служебные модули, которые помогают мне выполнять конкретные задачи. Промежуточное программное обеспечение, например
  • test : конфигурация, которую я хочу только при тестировании
  • src / static : содержит изображения, например
  • index.js : точка входа в приложение

Настройка клиента

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

Вот как я структурирую приложение:

  • Вид / компонент представлен папкой.
  • Компоненты, используемые для создания этого представления, живут внутри папки компонентов.
  • Маршруты определяют различные параметры маршрута, которые пользователь имеет, когда он / она находится в представлении.
  • Модули ( структура уток ) — это функциональные возможности моего взгляда и / или компонентов.

Настройка сервера

Вот как я структурирую приложение с папкой для домена, представленной:

  • Маршруты на основе HTTP-запроса
  • Промежуточное ПО для проверки, проверяющее параметры запроса
  • Контроллер, который получает запрос и возвращает результат в конце

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

Выбор зависимостей

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

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

клиент

Вот список зависимостей, которые я всегда устанавливаю в любом приложении React:

пакет Описание
перевождь Предсказуемый государственный контейнер.
реагируют-перевождь Связывает Rreact и Redux вместе.
перевождь-преобразователь Промежуточное программное обеспечение, которое позволяет вам написать действие, которое возвращает функцию.
перевождь-регистратор Библиотека логгеров для Redux.
реагируют-маршрутизатор Библиотека маршрутизации
lodash Сервисная библиотека
чай (дев) BDD, библиотека утверждений TDD для узла.
sinon (dev) Автономные тестовые шпионы, окурки и издевательства.
энзим (dev) Утилита тестирования для React.
nock (dev) Библиотека HTTP-макетов и ожиданий для Node.js.
редукс-макет-магазин (dev) Поддельный магазин для тестирования ваших создателей асинхронных действий Redux и промежуточного программного обеспечения.

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

сервер

Вот список зависимостей, которые я всегда устанавливаю в любом приложении Express:

пакет Описание
lodash
дзёи Язык описания схемы объекта и валидатор для объектов JavaScript.
экспресс-valiation Промежуточное программное обеспечение, которое проверяет тело, параметры, запрос, заголовки и файлы cookie запроса.
бум HTTP-дружественные объекты ошибок.
печенье-анализатор Разбор заголовка Cookie и заполнение req.cookies.
Winston Библиотека асинхронного журналирования.
мокко (дев) Тестовый фреймворк для Node.js и браузера
чай (дев)
chai-http (dev) HTTP ответные утверждения.
sinon (dev)
nodemon (dev) Наблюдает и автоматически перезапускает приложение.
Стамбул (Дев) Кодовое покрытие.

Сборка приложения

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

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

Пример: домашний экран

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

Сначала я записываю описание функции и добавляю к ней несколько сценариев. Вот пример для целей статьи:

Feature: In the home view, I should see my name in the header and a list of my boards.

Scenario: I can see my name in the header

Given I am on the home
Then I should see my user name in the header

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

Сторона клиента

Использование методологии компонентно-ориентированной разработки (CDD) в сочетании с BDD помогает разделить представления на небольшие компоненты, обеспечивая их разделение и возможность повторного использования.

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

Во-вторых, я проверяю это:

  • Компонент отображается правильно
  • Логика реквизита обрабатывается правильно
  • Слушатели событий (если есть) запускаются и вызывают соответствующие методы
  • Компонент получает состояние из хранилища

Наконец, я создаю компонент Header User и контейнер и реорганизую данные, которые я высмеивал ранее в исходном состоянии модуля Redux.

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

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

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

Серверный

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

CRUD (создание, чтение, обновление, удаление) — это базовый набор операций, которые нужны любому приложению, но я не добавляю их вслепую ко всем моим маршрутам. Сейчас мне нужно получить данные, поэтому я просто использую read. Затем я могу написать запрос Mongo, который добавит пользователя в мою базу данных позже.

Вывод

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

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

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

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

Какие у меня планы на будущее?

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

  • Переместить мой монолитный проект в репо с сервером, основанным на микросервисах. Я принял решение, работая над клоном HipChat. Я заметил, что я дублировал много кода для одной и той же логики аутентификации: микроуслуги были очевидным выбором. Ctrl-C, Ctrl-V не ваш друг в программировании.
  • Развернуть микро сервисы в Куберне.
  • Переместите клон HipChat в моно репо и создайте приложение с помощью Vue.js.
  • Начните изучать Electron и React Native.
  • Добавьте непрерывную интеграцию (CI) и развертывание с Travis.
  • Изучите TypeScript.

Как мне удается идти в ногу?

У меня очень строгая рутина:

  • С понедельника по четверг: попрактикуйтесь в алгоритмах на HackerRank и GeeksforGeeks , напишите документацию для работы в выходные дни, выучите новые языки, прочитайте технические книги и прослушайте подкасты.
  • С пятницы по воскресенье: работайте над новыми функциями и / или исправляйте ошибки в моих приложениях

Я не трачу все свое свободное время на работу над этим. В будние дни достаточно 1-2 часа в день. Выходные, хотя я не ограничиваю себя. Пока у меня есть время, я буду работать над проектом: я мог бы писать код, экспериментировать с инструментом или просто читать документацию.

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

Читать далее : Анатомия современного JavaScript-приложения