9 лучших практик, которые я узнал из React / Node в 2019 году

Огромная часть написания хорошего кода - это сделать его практичным, понятным и доступным для совместного использования. Кто никогда не копался в старом стеке кода и не думал: «Это написала обезьяна?».

Спойлер, ты была той обезьяной!

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

После того, как вы много прочитали и протестировали различные методы, вот личный список лучших практик, которые вы должны использовать при кодировании с помощью React / Node в 2019 году.

1. Соблюдайте правила именования

Это, наверное, самая обсуждаемая тема среди разработчиков программного обеспечения. Так что я не буду об этом говорить. Повсюду доступно множество замечательных материалов для чтения (средний уровень, Интернет, книги…), которые являются первоклассными.

Вот небольшой сувенир:

  • Используйте заглавные буквы для классов / компонентов. Пример: MyComponent
  • Используйте глаголы для функций. Пример: doSomething или handleClick
  • Избегайте подчеркивания. Хорошо, это может быть предпочтение, но я считаю, что заглавные буквы более читабельны. Плюс так написан собственный Javascript.
  • Избегайте однобуквенных переменных. Да, это тебе for(let i = 1; i < 100; i++)
  • Не слишком короткий и не слишком длинный. Не пишите бессмысленные функции update () или mightUpdateAndRefreshAllUsersEvery10min ().

2. Не используйте index.js.

Звучит странно, не правда ли? Вероятно, вы помещаете код в файлы index.js, скажем, в MyComponent / index.js, а затем выполняете импорт с использованием import MyComponent from ‘./MyComponent'. Основная проблема в том, что использовать index.js в таком виде - глупость. Райан Даль, создатель Node, на недавней конференции упомянул, что index.js - одно из своих самых больших сожалений. Https://www.youtube.com/watch?v=M3BM9TB-8yA

Райан Даль объясняет, что index.js имитирует соглашение index.html (поскольку Node - это серверная версия языка браузера). Проблема в том, что у вас повсюду будут файлы index.js! Разобраться в этом лабиринте файлов index.js станет болезненно. Какой файл index.js не прошел модульное тестирование, был зафиксирован или открыт в вашем редакторе? Хуже того: если у вас есть другие файлы в папке с компонентами, то какой из них является точкой входа?

Итак, используйте index.js только для прямого экспорта функций из других файлов, вот и все! Только не помещайте никакой логики в файл index.js. Это мерзко.

3. Иметь модульную файловую структуру.

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

Это противоречит философии React, основанной на компонентах. Вы создали сумасшедшую сеть файлов, все они нужны друг другу, и каждый раз, когда вы перемещаете один; вы должны исправить импорт везде.

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

Что насчет компонентов, инструментов или функций пользовательского интерфейса, которые могут вам понадобиться? Ничего страшного, я чувствую, что вы… Вы поместите их на корневой уровень!

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

Вот как должна выглядеть ваша файловая структура:

/src
  /components
    /Button 
      Button.js 
      Button.test.js
    Form.js
  /scenes
    /SignIn
      SignIn.js 
      GET_USER_STATUS.graphql     
      /components
        /LoginForm
          LoginForm.js 
          LoginForm.test.js
          schema.js
          handlers.js
  /services
    apollo.js 
    router.js 
  index.js

В этом примере LoginForm.js разрешено импортировать только schema.js, handler.js локально или любой файл в / services или / components.

Подробнее: https://medium.com/@alexmngn/how-to-better-organize-your-react-applications-2fd3ea1920f1

4. Используйте преобразователь для вашего каталога / src.

Одним из недостатков моего предыдущего предложения является то, что вы в конечном итоге будете использовать import Button from '../../../../Button/Button' в своем файле LoginForm.js. Ой. Довольно уродливо, правда?

Решение состоит в том, чтобы настроить webpack, eslint и т. Д., Чтобы иметь возможность делать import Button from 'components/Button' так же, как если бы ваш каталог компонентов был пакетом npm (который точно должен имитировать).

Вот как выглядит мой webpack.config.js:

const path = require('path');
module.exports = (config) => ({
  ...config,
  resolve: {
    modules: [
      path.resolve(__dirname, 'node_modules'),
      path.resolve(__dirname, './src/'),
    ],
  },
});

И мой .eslintrc.json (с использованием eslint-import-resolver-webpack):

{
  "extends": "airbnb",
  "env": { "jest": true, "browser": true },
  "settings": {
    "import/resolver": "webpack"
  }
}

Вуаля!

5. Используйте управление версиями, линтеры, модульные тесты и непрерывную интеграцию.

Это просто, но обязательно используйте эти инструменты.

Я использую Atom и опцию «Lint on save». Меня радует, когда я вижу уродливый файл с плохим интервалом, плохим форматированием и потенциальными ошибками, которые выделяются и иногда автоматически исправляются при сохранении.

Просто вопрос предпочтений, но мне нравится, когда мой импорт идеально упорядочен, поэтому вот выдержка из моего файла .eslintrc.json:

{
  "rules": {
    "import/order": [
      "error",
      {
        "groups": [
          "builtin",
          [
            "external",
            "internal"
          ],
          "parent",
          [
            "sibling",
            "index"
          ]
        ]
      }
    ]
  }
}

Мне нравится использовать Jest и CircleCI для тестов и автоматического развертывания. Основная идея: не терять время на исправление и развертывание вещей! Это то, что я испытывал много раз в прошлом. Вы пишете код в течение нескольких дней, а затем, наконец, готовы опубликовать свой код! Вы чувствуете волнение и стараетесь не бегать везде и показывать всем то, что вы только что создали. Но… Ой! Некоторые ошибки в консоли, некоторые сбои после этого, некоторые неприятные ошибки, как только вы пытаетесь использовать свой веб-сайт в Интернете. Волнение сменилось разочарованием.

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

Я рекомендую вам прочитать кое-что о разработке через тестирование (TDD): https://medium.com/hackernoon/introduction-to-test-driven-development-tdd-61a13bc92d92

Также стоит упомянуть пакет Husky, который позволяет автоматически запускать линтер или тесты перед фиксацией через Git Hooks. Https://www.npmjs.com/package/husky

6. Не делайте идеальный компонент

Ты ведь хорошо учишься? Итак, когда вы узнали о философии React, вы также узнали, что компонент должен быть многоразовым. Теперь вы смотрите на мои предыдущие примеры и, вероятно, думаете: «Разве мне не следует поместить LoginForm в каталог / components, поскольку я могу повторно использовать его в другом месте?».

Угадай, что? Ты прав!

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

Вам понадобится LoginForm в вашей сцене SignIn. На этом пока все! Ваши компоненты должны быть простыми и поначалу делать как можно меньше. Позже вы откроете для себя другие варианты использования. Я бы даже сказал, что ваш основной компонент Button сначала должен быть инкапсулирован в сцену, потому что в конце концов он может вам понадобиться только один раз!

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

7. Избегайте библиотек npm и используйте ES6.

Вспоминаю с небольшой ностальгией первый выпуск jQuery. Это был золотой век фронтенд-разработчиков. Больше никаких сумасшедших вещей. Просто удобочитаемые селекторы в стиле CSS, которые упростили все! Угадай, что? Никто больше не хочет использовать jQuery. Он стал тяжелым и устаревшим, пережитком, к которому каждый разработчик Javascript относится со смесью ностальгии и отвращения.

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

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

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

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

В 90% случаев вы можете найти способы сделать это самостоятельно, используя собственный Javascript. ES6 великолепен, и вы можете делать много всего! Array.reduce, распространение объектов, Promise…

Дополнительные материалы: https://dev.to/saurabhdaware/how-i-baught-down-my-project-s-dependency-tree-from-36-packages-to-4-packages-1n0h

8. Избегайте импорта.

Этот даже более хардкорный, чем предыдущий. Конечно, вы должны использовать импорт! Могут быть какие-то локальные файлы или библиотеки. Но помните, что всякий раз, когда вы что-то импортируете, вы просто добавляете сложности. Вы усложняете тестирование своей функции, делаете ее более зависимой, менее надежной и менее понятной.

Очень простым примером может быть набор методов сбора Mongo. У вас может возникнуть соблазн написать такую ​​функцию для обновления имени пользователя:

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

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

… И имея всю логику в this. Таким образом, ваша функция читабельна, проста и тестируема. Отблагодаришь позже.

Вот полный пример, чтобы лучше понять:

9. Напишите четкие функциональные компоненты.

В сфере React были некоторые тенденции. Сначала люди были в классах, затем это показалось немного многословным, поэтому они передумали использовать функции без состояния с некоторыми HOC (компоненты высшего порядка), а теперь функциональные компоненты стали предметом благодаря новым хукам, таким как useState введено в React 16.8.

Я протестировал все эти тенденции и позвольте мне кое-что вам напомнить: все является функцией в Javascript! Используйте функциональные компоненты.

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

Вот пример, полученный из замечательной библиотеки UI материалов (https://material-ui.com/):

Разве это не красиво?

Заключение

Эти передовые методы могут выглядеть как «еще один набор правил для страдающих манией величия», которые предположительно лучше других. В некотором роде это так! В конце концов, это всего лишь рекомендация, рожденная из личного опыта. Некоторым людям нравится использовать столько модулей npm, сколько они хотят. Некоторым нравятся файлы index.js. Некоторым нравится писать компоненты в виде классов. И т.п.

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

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

Дайте мне знать, что вы думаете, какие лучшие практики вы бы добавили или есть ли у вас какие-либо предложения в разделе комментариев!