Несколько недель назад я столкнулся с разработчиком, делящим один из его побочных проектов на GitHub: клон Trello. Созданный с использованием React, Redux, Express и MongoDB, проект, казалось, имел много возможностей для работы с навыками полного стека JS.
Я спросил разработчика, Мустафу Диуфа, будет ли он заинтересован в написании своего процесса выбора, проектирования и построения проекта, и, к счастью, он согласился. Я надеюсь, что вы найдете его таким же интересным, как и я, и что это вдохновляет вас работать над своими амбициозными проектами!
Нильсон Жак, редактор
В этой статье я расскажу вам о подходе, который я использую, в сочетании с парой рекомендаций, которые я использую для создания веб-приложений. Прелесть этих техник в том, что они могут применяться к любому языку программирования. Я лично использую их в работе над стеком Java / JavaScript, и это сделало меня очень продуктивным.
Прежде чем перейти к подходу, я уделю некоторое время обсуждению того, как:
- Я определил свои цели перед началом проекта.
- Я решил использовать технический стек.
- Я установил приложение.
Имейте в виду, что, поскольку весь проект находится на GitHub ( madClones ), я сосредоточусь на дизайне и архитектуре, а не на реальном коде. Вы можете проверить живую демонстрацию текущего кода: вы можете войти с учетными данными Test / Test.
Если вы хотите поднять свои навыки работы с 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-приложения