@custis/common
v2.10.2
Published
Общие вещи для проектов. Включает в себя DI, утилиты для форматирования дат и чисел, несколько общих компонентов и сервисов и утилиты для типов.
Downloads
92
Maintainers
Readme
Custis common
Общие вещи для проектов. Включает в себя DI, утилиты для форматирования дат и чисел, несколько общих компонентов и сервисов и утилиты для типов.
Быстрый старт
- Возьмите токен (см. ниже) и добавьте его в переменную окружения NPM_TOKEN
- Установите зависимости
npm install
- Соберите проект
npm run build
Чтобы добавить изменения:
- Сделайте изменения, напишите тесты
- Проверьте сборку
npm run build
- Запушьте в отдельную ветку
- После CR вмёржите ветку в мастер
- Поднимите версию приложения
npm version x.y.z
. Нумерация в соответствии с semver - Запушьте с тегами
Общее
Используемые технологии, библиотеки и кодстайл
React
Основная библиотека для UI. Стараемся обновлять до актуальной версии.
Используем функциональные компоненты. При написании кода выносим всю ui-логику в хуки (даже если логика не переиспользуется). Компоненты делаем максимально простыми. Бизнес логику выносим в mobx-store.
В библиотеках тип пропсов экспортируем, в приложениях можно не экспортировать.
interface MyComponentProps {
foo: string;
}
export const MyComponent: FC<MyComponentProps> = (props) => {
const { foo } = props;
const { someHandler, someField, store } = useMyComponent(foo);
return (
<div>
<button onClick={someHandler}>Click</button>
<p>{someField}</p>
<OtherComponent store={store} />
</div>
);
};
Tsyringe
Библиотека для DI. На её основе выстраиваем DI-систему в приложениях и библиотеках. Классы с логикой помечаем
декоратором injectable
. Стараемся использовать в качестве токенов типы, а не строки. К сожалению, в тайпскрипте нет
возможности использовать интерфейсы как токен, так что если есть острая необходимость использовать интерфейсы, то
используем строку как токен и внедряем такую зависимость через аннотацию inject
в конструктор. Внедрять классы в
классы просто - достаточно указать зависимость в конструкторе. Чтобы внедрить сервис используйте хук useInjection
из
библиотеки @custis/common
:
@injectable
export class BackendService {
async getItems(): Promise<Item[]> {
// ...
}
}
@injectable
export class SomeStore {
// Внедрение в класс
constructor(private backendService: BackendService) {}
}
export const MyComp: FC = () => {
// Внедрение в компонент
const store = useInjection(SomeStore);
return <></>;
};
MobX
Библиотека для хранения состояния. Бизнес логику, связанную с состоянием реализуем в классах-сторах. В этих классах
отслеживаемые поля помечаем как observable
, вычисляемые поля (геттеры) помечаем как computed
, методы, изменяющие
состояние помечаем как action
. Сами сторы делаем injectable
, чтобы они были доступны для DI.
@injectable
export class SomeStore {
@observable items: Item[] = [];
@observable loading: boolean = false;
constructor(private backendService: BackendService) {}
@action
async loadItems(): Promise<void> {
this.loading = true;
const result = await this.backendService.getItems();
this.items = result.items;
this.loading = false;
}
}
Линтеры и форматтеры
В проектах за качеством кода следят линтеры. Перед началом работы убедитесь, что ваш редактор или IDE настроены на работу с ними.
Линтер кода - Eslint
В качестве линтера используется eslint. Он настроен на проверку правил typescript (проверяет правила типизации), и реакт (следит за именованием компонентов и хуками). Выставлены достаточно строгие правила проверки кода.
Проверьте, что ваш редактор использует eslint. Для этого, например, в любом ts-файле можете добавить такой код. В комментариях показаны места, где линтер должен оповестить об ошибках.
function a(arg1: any) {
// ^-- @typescript-eslint/no-explicit-any
let var1 = 1;
// ^-- prefer-const
console.log(var1);
return arg;
// ^-- @typescript-eslint/no-unsafe-return
}
Если в редакторе появятся ошибки, то линтер настроен.
Для запуска линтера по всему проекту есть npm-скрипты:
npm run check:linting
для отлова ошибок. Если в проекте есть хоть одна ошибка, запуск команды завершится с ненулевым кодом.npm run check-extra:linting-with-warn
для отлова ошибок и предупреждений. Если в проекте больше чем 10 предупреждений, запуск команды завершится ошибкой.
Для исправлений замечаний eslint запустите команду npm run fix:lint
Форматтер кода - Prettier
В проекте для контроля форматирования кода используется prettier. В принципе, eslint может следить и исправлять
отклонения от стиля кода, но prettier делает это лучше. В редакторе желательно настроить форматирование кода через
prettier при сохранении. Для проверки всего проекта на соответствие формату кода используйте
команду npm run check:format
. Если какие-то файлы не соответствуют формату, то команда завершится с ненулевым кодом.
Для исправления форматирования по всему проекту есть команда npm run fix:format
Хуки гита
При запуске команды npm install
запускается настройка husky - средства для
управления хуками в гит. При коммите запускаются 2 npm-скрипта
npm run fix
- исправление кода, сам скрипт запускает следующие скриптыnpm run fix:lint
- исправления линтераnpm run fix:format
- исправления форматтера
npm run check
- проверка кода, сам скрипт запускает все скрипты, начинающиеся наcheck:
:npm run check:types
- проверка корректности типов, позволяет без сборки проверить код на корректность используемых типовnpm run check:format
- форматированиеnpm run check:lint
- кодстайл
Если секция npm run check
завершится с ненулевым кодом, то коммит не произойдёт. Если всё-же нужно закоммитить код,
который не проходить проверки, то нужно при коммите добавить опцию --no-verify
.
Сборка проекта
Сборка любых проектов выполняется командой npm run build
. При этом, до запуска самой сборки запускается секция
проверки кода и тесты (пока только в библиотеках).
Сборка приложений
Для сборки приложений используется webpack. За основу взят конфиг из create-react-app
, у которого выполнен eject. Из
изменений:
- сборщик для typescript заменён на
awesome-typescript-loader
- добавлена возможность использовать css-модули для less-файлов
Сборка библиотек
Для сборки библиотек используется rollup с плагинами. Есть особенность сборки библиотек и указания зависимостей. Если вы указываете какую-то библиотеку в зависимостях, то иногда плагин commonjs не может разрешить некоторые зависимости и сборка падает с не очень внятной ошибкой. Есть 2 решения это проблемы:
- Явно указать экспортируемые символы в
rollup.config.js
, например:commonjs({ namedExports: { 'node_modules/react/react.js': ['Children', 'Component', 'PropTypes', 'createElement'], }, });
- Убрать библиотеку из зависимостей (dependencies в package.json), но добавить её в devDependencies и в peerDependencies. Добавление в devDependencies даст возможность сборки на стенде, указание в peerDependencies проинформирует о необходимости установки этих зависимостей в приложение, использующее библиотеку
Линковка библиотек в проект
Чтобы протестировать работу библиотеки в проекте локально, можно прилинковать её в node_modules
проекта. В обычном
варианте это делается так:
- Заходим в директорию библиотеки
- Собираем её
- Запускаем команду
npm link
- Заходим в директорию проекта
- Запускаем команду
npm link @custis/library_name
- Запускаем проект
Однако, из-за особенностей работы библиотек для DI, tsyringe в нашем случае (грубо говоря, такие библиотеки не
поддерживают символические ссылки), этот способ не подходит. Можно воспользоваться скриптом в приложении, который сам
соберёт нужные библиотеки и скопирует их внутрь папки node_modules. Чтобы он заработал, достаточно скопировать
файл libs.config.sample.js
в новый файл с именем libs.config.js
. В нём нужно указать для выбранной библиотеки путь
до неё относительно приложения, в котором мы хотим протестировать эту библиотеку. После этого нужно
- Собрать библиотеку
- Запустить в приложении команду
npm run link
- Запустить проект
Чтобы удалить локальную копию библиотеки из node_modules, можно выполнить команду npm run unlink
или просто запустить
заново npm install
Настройка стендов
Для связи с бэкендом используется прокси. В файле src/dev.proxy.config.js
описаны пути до стендов. По-умолчанию, для
запуска ничего дополнительно настриаивать не нужно. Однако, вы можете переопределить настройки прокси локально, для
этого достаточно создать файл src/dev.proxy.conf.local.js
в проекте с содержимым,
аналогичным src/dev.proxy.config.js
.