## 1. Общие положения 1. Все несамостоятельные компоненты должны быть написаны на TypeScript. Для самостоятельных компонентов (использующихся как страницы) (далее страницы) допускается использование JavaScript для ускорения написания; ### 1.1. Файловая структура проекта 1. Компоненты должны распределяться по директориям в соответствии со своим назначением: * `src/context` - Для контекстов приложения; * `src/components` - Для несамостоятельных компонентов, применяющихся многократно; * `src/pages` - Для страниц и компонентов, использующихся исключительно в единственном экземпляре; * `src/images` - Для компонентов-изображений. 2. Если страница описывается 1 файлом она должна именоваться в соответствии с содержимым, в ином случае должна быть создана директория с соответствующим названием, внутри которой будут находиться файлы страницы. Основной файл в таком случае должен быть переименован в `index.jsx`; 3. Файлы именуются в соответствии с таблицей: | Тип содержимого файла | Расширение | Стиль именования | |--------------------------------------|------------|--------------------------| | Компонент или страница | jsx/tsx | **PascalCase** | | Файл стилей | css/less | **snake_case** | | Вспомогательные методы или константы | js/ts | **snake_case** | | Описательные документы | md | **SCREAMING_SNAKE_CASE** | ### 1.2. Стилизация кода 1. Все строки должны по возможности описываться одинарными кавычками или при необходимости обратными: ```js const name = 'world' const msg = 'Hello, \'' + name + '\'!' const toPrint = `Message: ${msg}` ``` 2. Все переменные по возможности должны инициализироваться как `const`, применение `var` не допускается; 3. Переменные именуются в соответствии с таблицей: | Тип переменной | Стиль именования | |-------------------|--------------------------| | Метод, переменная | **camelCase** | | Константы | **SCREAMING_SNAKE_CASE** | | Компонент | **PascalCase** | ### 1.3. Импортирование / Экспортирование 1. Импортированные файлы (в том числе lazy import) необходимо указывать в самом верху документа в следующем порядке с разделением пустой строкой: 1. Внешние зависимости (`react`, `antd`, `webpack` и т.д.); 2. Локальные компоненты по порядку: 1. Контексты (`@asb/context`); 2. Компоненты (`@components/Table`); 3. Вспомогательные методы (`@utils`); 4. Сервисы API (`@api`). 3. Изображения и компоненты-изображения (`@images`); 4. Стили (`@styles`); 5. Lazy import (`const page = React.lazy(() => import('./page'))`). 2. При импорте локальных файлов стоит пользоваться alias'ами: | Путь | Alias | |------------------|--------------| | src/components | @components | | src/context | @asb/context | | src/images | @images | | src/pages | @pages | | src/services/api | @api | | src/styles | @styles | | src/utils | @utils | 3. По возможности импортировать из пакетов и файлов только использующиеся сущности: ```tsx // вместо import React from 'react' const page: React.ReactNode = React.lazy(() => import (...)) // стоит использовать import { lazy, ReactNode } from 'react' const page: ReactNode = lazy(() => import (...)) ``` ### 1.4. Работа с репозиторием #### 1.4.1. Подготовка к публикации работы по заданию При получений задания необходимо создать для неё ветку, наследуемую от **dev**. Ветка должна именоваться в **kebab-case** и иметь префикс соответствующий типу задачи: * "**feature/**" - для нового функционала или визуала; * "**fix/**" - для багов и любых исправлений. Название ветки должно кратко описывать проблему или новые возможности. Далее необходимо создать *pull request* на ветку dev от новосозданной и сразу отметить его как WIP. При завершении задания метку WIP необходимо снять. #### 1.4.2 Оформление коммита Изменения файлов необходимо разделять на коммиты по общим изменениям и соответствующе его именовать. Если в коммит попадает более одного логического изменения стоит указывать их в виде маркированного списка, например: ``` * На странице "Мониторинг" и "Архив" сокращено колличество запросов; * Страница "Сообщения" удалена. ``` ## 2. JS 1. Методы, константы и переменные документируются в соответствии с `JSDoc`; 2. При документации страниц необходимо указать её название, краткое описание и описание получаемых параметров: ```jsx import { memo } from 'react' import LoaderPortal from '@components/LoaderPortal' /** * Тестовая страница * * @description Данная страница не имеет смысла и просто выводит переданное название и контент * @param title - Название страницы * @param content - Контент страницы * @param loading - Отображать ли оверлей загрузки над блоком страницы */ export const TestPage = memo(({ title, content, loading }) => (
{title}
{content}
)) export default TestPage ``` ## 3. TS 1. Методы, константы и переменные документируются в соответствии с `TSDoc`; 2. При документации компонентов необходимо указать их название, краткое описание, а также описать параметры в типе: ```tsx import { memo } from 'react' import LoaderPortal from '@components/LoaderPortal' export type TestPageProps = { /** Название страницы */ title: ReactNode /** Контент страницы */ content: ReactNode /** Отображать ли оверлей загрузки над блоком страницы */ loading: boolean } /** * Тестовая страница * * @description Данная страница не имеет смысла и просто выводит переданное название и контент */ export const TestPage = memo(({ title, content, loading }) => (
{title}
{content}
)) export default TestPage ``` 3. Использование `any` в типах допустимо только, если значение используется только в параметрах компонентов, обозначенных типом `any`. Если метод предполагает работу с разными типами значений стоит описать его как обобщённый. ## 4. JSX/TSX ### 4.1. Стилизация кода 1. Все указываемые к компоненту параметры должны быть обёрнуты в фигурные скобки, кроме параметров флагов со значением `true`: ```jsx ``` 2. Если описание параметров компонента не укладывается в ширину в 120 строк стоит перенести их в соответствии с шаблоном: ```jsx ``` 3. Если JSX код передаётся как значение стоит обернуть его в круглые скобки: ```jsx const a = ( ) ``` ### 4.2. Логика поведения 1. Не допускается создание значений ссылочных типов в области рендера. Они должны быть вынесены в переменные или константы; 2. Не допускается создание переменных в функциональных компонентов без использования хуков `useMemo`/`useCallback`/`useState`; 3. Если переменные или методы не имеют зависимостей и не вызывают методы, доступные исключительно внутри компонента, они должны быть вынесены выше кода компонента. ## 5. LESS 1. Использование id должно быть сведено к минимуму; 2. Все классы именуются с префиксом компании "`dd-`"; 3. Слова в классах разделяются тире ("`-`"); 4. Файлы именуются в соответствии с компонентом, к которому относятся; 5. В одном файле описываются стили либо к конкретному компоненту, либо к странице; 6. Файл со стилями должен подключаться не более чем к одному компоненту (странице); 7. Файлы поделены на директории виду компонента, к которому применяются стили: * `styles/components` - для компонентов, не использующихся самостоятельно; * `styles/pages` - для компонентов, использующихся как страница; * `styles/widgets` - для компонентов, применяющихся как виджеты в дашбордах.