Стиль кода

  1. Общие правила определены в eslint, могут меняться по согласованию участников проекта.

  2. Для авто форматирования кода используется prettier.

  3. Отступы в коде — 2 пробела.

  4. Названия файлов и директорий в нижнем регистре через дефис. kebab стиль. /some-name/index.js.

  5. Файлы компонент, модулей и потенциально расширяемых на несколько файлов частей кода, группируются в директории.

    • Название директории — это название компонента или модуля.
    • Файлы внутри директории не должны содержать названия компонента или модуля. Их названия — это именования составных частей: index.js, actions.js, style.less, favicon.png
      articles
      ├──state.js
      ├──actions.js 
      └──reducer.js
      ...
      button
      ├──index.js
      ├──style.less 
      └──checked.svg
      
  6. В одном файле кода содержится логика с однозначным назначением, не должно быть кучи всего в одном месте.

  7. Упорядочивать функции в классе (объекте) по приоритету или последовательности исполнения — чтобы был хоть какой-то порядок для быстрой ориентации по коду.

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

  9. Логика должна быть четко сгруппирована на логические блоки. Ни в коем случаи не писать где попало новый хук, объявлять переменную или выполнять импорт. Разработчик должен интуитивно знать, где искать определение функции или переменной

    • Инициализация useInit().
    • Получение внешних данных select = useSelectMap(),
    • Локальный стейт [stateActive, setStateActive] = useState()
    • Описание колбэков callbacks = {}.
    • Инициализация опций, расчётов для рендера options = {}.
    • Вынесенные в функции фрагменты рендеры renders = {}.
    • Сайд эффекты.
  10. Импорт файлов приложения через алиас "@src/" вместо относительных путей.

  11. Комментировать строки кода, если логика неочевидная, не типовая, сложная.

  12. Комментировать назначение функций в jsDoc формате: краткое описание, параметры @param, возвращаемое значение @return и другие опционально.

Пример кода с логическими блоками

import CustomOption from '@src/components/elements/custom-option';
/**
 * Пример компонента с логическими блоками
 * @param props {Object} Свойства компонента
 * @return {Object}
 */
function SomeCompoennt(props){

  // Состояние из redux
  const select = useSelectorMap(state => ({
     active: state.categories.active,
     items: state.categories.items
  }));

  // Функции обратного вызова
  const callbacks = {
    onClick: useCallback(()=>{...}, []),
    onSubmit: useCallback(()=>{...}, []),
  }

  // Замороженные опции
  const options = {
    items: useMemo(()=>{...}, [])
  }

  // Отдельные функции рендера
  const renders = {
    item: useCallback((itemProps)=>(<CustomOption {...itemProps}/>), []),
  }

  return (
    <select onClick={callbacks.onClick} className={themes('Select', {'disabled': props.disabled})}>
      {options.items.map(item => (renders.item(item)))}
    </div>
  )
}