1.1.1 • Published 3 months ago

@custis/file-adapter-front v1.1.1

Weekly downloads
-
License
Apache-2.0
Repository
-
Last release
3 months ago

Сервис массовой обработки файлов. Web UI

Данный репозиторий содержит Web UI для сервиса массовой загрузки файлов (СМОФ). Более подробное описание СМОФ см. в репозитории file-adapter-back.

Грид для отображения данных. Используется в основных модулях. Поддерживает много функций (фильтрация, сортировка, пагинация, изменение отображения столбцов, выделение строк, и т.п.). Построен на основе библиотеки react-table.

Latest version

Основные компоненты библиотеки:

  • компонент FileDescriptors (FileDescriptors)
  • стор с данными для этого компонента FileDescriptorsStore
  • фабрика для создания стора FileDescriptorsStoreFactory
  • модели данных для запроса и результата

Чтобы встроить СМОФ в проект, нужно добавить на нужную страницу компонент FileDescriptors, в пропсы передать созданный черех FileDescriptorsStoreFactory стор.

import React, { useMemo } from 'react';
import { observer } from 'mobx-react';
import { useInjection } from '@custis/common';
import { FileDescriptors, FileDescriptorsStoreFactory } from '@custis/file-adapter-front';

export const FileAdapter = observer(() => {
  const storeFactory = useInjection(FileDescriptorsStoreFactory);
  const store = useMemo(() => storeFactory.create('/file-adapter'), []);

  return <FileDescriptors store={store} />;
});

Выпуск версии

  • В package.json нужно изменить "version": "1.0.1" далее создаеться тег и публикует сюда
  • Если версия в package.json не повышалась, то пакет не перезаписывется

Быстрый старт

  1. Установите зависимости npm install
  2. Соберите проект npm run build

Чтобы добавить изменения:

  1. Сделайте изменения, напишите тесты
  2. Проверьте сборку npm run build
  3. Запушьте в отдельную ветку
  4. После CR вмёржите ветку в мастер
  5. Поднимите версию приложения npm version x.y.z. Нумерация в соответствии с semver
  6. Запушьте с тегами

Общее

Используемые технологии, библиотеки и кодстайл

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 решения это проблемы:

  1. Явно указать экспортируемые символы в rollup.config.js, например:
    commonjs({
      namedExports: {
        'node_modules/react/react.js': ['Children', 'Component', 'PropTypes', 'createElement'],
      },
    });
  2. Убрать библиотеку из зависимостей (dependencies в package.json), но добавить её в devDependencies и в peerDependencies. Добавление в devDependencies даст возможность сборки на стенде, указание в peerDependencies проинформирует о необходимости установки этих зависимостей в приложение, использующее библиотеку