Архитектура проекта
Steroids предлагает единую архитектуру для ваших проектов. Следуя данным принципам и правилам, вы сможете в короткие сроки создавать сложные приложения, которые будет легко поддерживать в будущем.
Структура приложения
Общая структура приложения с одной страницей и макетом выглядит следующим образом:
├── node_modules
├── public - директория для билда, используемая веб-сервером
├── src
│ ├── actions - redux actions
│ ├── reducers - redux reducers
│ ├── modals - модальные окна
│ ├── routes - роуты (страницы) приложения
│ │ └── IndexPage - папка реакт компонента
│ │ └── views - компоненты, используемые только в IndexPage
│ │ ├── MyBox.ts
│ │ └── MyBox.scss
│ │ ├── IndexPage.ts - реакт компонент
│ │ ├── IndexPage.scss - БЭМ стили компонента
│ │ └── index.ts - подгрузка компонента как директории
│ ├── shared - общие компоненты
│ │ └── Layout
│ │ ├── Layout.ts
│ │ ├── Layout.scss
│ │ └── index.ts
│ ├── ui - стилизованные и кастомные UI компоненты
│ │ └── form
│ │ ├── Button
│ │ │ ├── ButtonView.tsx
│ │ │ └── ButtonView.scss
│ │ └── CustomField
│ │ ├── CustomField.ts
│ │ ├── CustomFieldView.tsx
│ │ └── CustomFieldView.scss
│ ├── style
│ │ ├── index.scss - главный файл стилей
│ │ └── variables.scss - scss переменные
│ ├── Application.tsx - основной компонент приложения
│ └── index.tsx
├── .eslintrc
├── index.d.ts - глобальное определение типов для кода, написанного без typescript
├── package.json
├── tsconfig.json
├── webpack.js
└── yarn.lockВ директорию public можно добавлять статику (картинки, шрифты) для использования их в приложении по абсолютному пути.
В эту же директорию будут сохраняться минифицированные бандлы приложения, генерируемые вебпаком.
Папка src - исходники проекта, они не публикуются при выгрузке проекта на продакшен.
В корне исходников лежат два файла - index.tsx и Application.tsx. Их разделение и названия лучше оставлять именно
такими, т.к. при использовании SSR, nodejs сервер-приложение будет рендерить именно Application.tsx. Файл index.tsx
в данном случае используется только для рендера через react-dom в браузере.
В директориях actions и reducers содержатся соответственно экшены и редьюсеры для redux хранилища. Их не обязательно
создавать, в библиотеке уже есть множество редьюсеров, которыми может пользоваться приложение. Если папка reducers не
создана, то вебпак возьмет редьюсеры из библиотеки node_modules/@steroidsjs/reducers.
Все роуты описываются в файле routes/index.ts. Подробнее об их возможностях и формате записи можно прочитать
в разделе Роутинг.
React компоненты приложения распределяются по папкам modals, routes, shared и ui.
В других папках их объявлять не следует для поддержания структуры и удобства навигации.
Кастомизация приложения
В файле Application.tsx можно кастомизировать приложение - добавить кастомные reducers, components, icons.
Вот так выглядит файл в boilerplate:
import useApplication from '@steroidsjs/core/hooks/useApplication';
import HttpComponent from '@steroidsjs/core/components/HttpComponent';
import LocaleComponent from '@steroidsjs/core/components/LocaleComponent';
import customIcons from 'icons/index';
import 'style/index.scss';
export default function Application() {
const {renderApplication} = useApplication({
reducers: require('@steroidsjs/core/reducers').default,
routes: () => require('routes').default,
layoutView: () => require('shared/Layout').default,
screen: {},
components: {
locale: LocaleComponent,
http: HttpComponent,
},
onInit: ({ui}) => {
ui.addViews(require('./ui/bootstrap').default);
ui.addFields(require('@steroidsjs/core/ui/form').default);
ui.addFormatters(require('@steroidsjs/core/ui/format').default);
ui.addIcons(require('@steroidsjs/bootstrap/icons/index').default(customIcons));
},
});
return renderApplication();
}Подробные инструкции по кастомизации различных частей приложения можно посмотреть в статье Кастомизация приложения.
React компоненты
React компоненты фреймворка Steroids обладают некоторыми особенностями и преимуществами:
- Наличие раздельных
coreиviewчасти для каждого компонента. - Возможность настройки стилей через
SCSS variables. - Возможность полностью заменить как
*.scss, так и*.tsxфайлы компонентов для кастомизации. - Описанные на
TypeScriptинтерфейсы для компонентов и ихviewчастей. - Возможность глобальной настройки
default propsкак всех сразу, так и выбранных компонентов. - Логика работы ui-компонентов в связке с компонентами приложения, роутингом и
redux. - Возможность обработки метаданных моделей и перечислений, приходящих с бэкенда, для создания форм на их основе.
Разделение логики и отображения компонента
Каждый UI компонент (элемент формы, список, модальное окно, ...) - состоит из двух частей:
1. Core - ядро компонента. Оно содержит всю бизнес-логику компонента, принимает и обрабатывает полученные данные из
props, находит нужную "вьюшку" – view компонента и прокидывает в нее подготовленные данные. Core компонент не
содержит jsx кода и не обращается к DOM элементам.
2. View - отображение компонента. Это часть, которая отвечает за непосредственную отрисовку компонента. Она содержит
только jsx код и scss стили компонента с минимальным или отсутствующим кодом бизнес-логики. При кастомизации
компонента - его *View.tsx и/или *View.scss файлы могут (при необходимости) полностью копироваться в проект
и изменяться под дизайн конкретного проекта.
Подробнее о том, как использовать преимущество разделения core и view частей компонента, можно прочитать здесь.
Структура файлов компонента
React компоненты состоят из двух файлов - tsx и scss. Даже если сейчас нет необходимости задавать компоненту стили,
но компонент содержит jsx код, то все равно стоит создать *.scss файл стилей и подключить его через import в *.tsx файле. Таким образом структура файлов компонента будет единообразна для всего проекта.
Каждый компонент выделяется в отдельную папку, в которой объявляется index.ts. В этом файле находится импорт и экспорт компонента:
import IndexPage from './IndexPage';
export default IndexPage;Файл index.ts служит для экспорта компонента из папки. При наличии таких файлов у компонентов, в коде проекта можно использовать лаконичные импорты, например - routes/IndexPage вместо длинных импортов из файла компонента, например - routes/IndexPage/IndexPage.
Для больших компонентов, например для страниц приложения, выделяют вложенные компоненты. Если такие компоненты используются только в данном компоненте, то их нужно расположить в папке views (см. routes/IndexPage/views/* в структуре). Если компоненты переиспользуются в других больших компонентах, например на других страницах приложения, то их нужно вынести на верхний уровень в папку shared (см. src/shared в структуре).
Общие стили приложения
Базовые стили приложения располагаются в папке src/style и экспортируются из файла src/style/index.scss. Они
подключаются при инициализации приложения в файле Application.tsx.
Общие стили используются для объявления используемых шрифтов, базовых стилей для html-тегов, миксинов и scss-переменных. Также
в этом файле могут подключаться css-файлы различных библиотек или дефолтные стили для Steroids - @import '@steroidsjs/bootstrap/index.scss';
Scss-переменные, которые будут использоваться в различных компонентах, импортируются в отдельный файл - style/variables.scss. Дальнейшее его использование в компонентах выглядит так:
@use "style/variables";
.Block {
background-color: variables.$gray;
border: 1px solid variables.$graphite;
}Если переменных большое количество и их можно разделить на группы, то структура будет следующая:
├── style
│ ├── variables - папка с файлами для scss-переменных
│ │ ├── colors.scss - scss-переменные для цветов
│ │ ├── typography.scss - scss-переменных для типографики
│ │ └── index.scss - экспорт всех файлов с scss-переменными из папки
│ ├── index.scss - главный файл стилей
│ └── variables.scss - содержит импорт index файла из папки variables и другие файлы с переменными (например для библиотек)Scss-mixins, импортируются в отдельный файл - style/mixins.scss. Дальнейшее его использование в компонентах выглядит так:
@use "style/mixins";
.Block {
@include mixins.loading(1s);
}Если scss-mixins можно разделить на группы - каждая группа в отдельном файле, то структура будет такая же, как для scss-переменных.