@nsmp/js-api
Version:
Types for jsApi
288 lines (214 loc) • 14.3 kB
Markdown
# jsApi
Пакет предназначен для разработчиков встроенных приложений и предоставляет инструменты для улучшения и оптимизации процесса разработки. Пакет предоставляет:
- Функцию `initializeJsApi` для подключения `jsApi` в разных режимах (`development`, `test`, `production`);
- Данная функция содержит проксирование, которое в зависимости от окружения создает объект `jsApi`.
- Каждое окружение содержит объект `jsApi` со своим интерфейсом, который преобразовывается в объект с общим интерфейсом, что позволяет при разработке ВП использовать единый интерфейс вне зависимости от окружения.
- На текущий момент существует **3 окружения**:
- `smp4` - ВП встраивается в страницу устаревшего `GWT`-интерфейса внутрь `iframe`,
- `uiFrame` - ВП встраивается в страницу нового `react`-интерфейса внутрь `iframe`,
- `ui` - ВП встраивается в страницу нового `react`-интерфейса как `microfrontend`.
- Функция принимает объект настроек, который содержит свойства:
- `mock` - для определения `mock` объекта `jsApi` для локальной разработки;
- `getContext` - функция возвращает контекст приложения, если оно выведено как `microfrontend`;
- Функцию `getJsApi` для получения созданного объекта `jsApi`, если он создан, иначе выбрасывает ошибку, что объект не создан;
- Функцию `removeJsApi` для удаления созданного объекта `jsApi`;
- Хук `useInitializeJsApi` для подключения `jsApi` в `microfrontend` приложении, использующем `react`. При размонтировании приложения хук вызывает функцию `removeJsApi`. Это необходимо, чтобы удалился `singleton`-объект `jsApi` для экономии памяти и смены контекста.
- Файлы декларации типов `.d.ts` для `jsApi` при работе с `TypeScript`;
- `Mock`-функции `jsApi` для локальной разработки, а также инструменты для их переопределения и уточнения;
- Инструменты для локальной разработки с проксированием запросов к приложению.
## Содержание
- [Быстрый старт](#быстрый-старт)
- [Инициализация и использование `jsApi`](#инициализация-и-использование-jsApi)
- [Типизация `jsApi`](#типизация-jsapi)
- [Переопределение методов `jsApi`](#переопределение-методов-jsapi)
- [Конфигурации](#конфигурации)
- [Настройка проксирования запросов](#настройка-проксирования-запросов)
## Быстрый старт
1. Установить пакет: ```npm i @nsmp/js-api```
2. Инициализировать `jsApi` в проекте - [Инициализация и использование jsApi](#инициализация-и-использование-jsApi)
3. В режиме разработки (при необходимости):
1. переопределить стандартные методы `jsApi` - [Переопределение методов jsApi](#переопределение-методов-jsapi)
2. настроить проксирование запросов - [Настройка проксирования запросов](#настройка-проксирования-запросов)
[К содержанию](#содержание)
## Инициализация и использование `jsApi`
Инициализация `jsApi` зависит от того, в каком окружении будет использоваться ВП.
### ВП будет использоваться во всех трех окружениях
Пример для ВП с использованием контекста:
Необходимо в корневом компоненте, обычно это `App`, вызвать хук `useInitializeJsApi` и передать в него контекст приложения.
Приложение как `microfrontend` - это `react`-компонент, который принимает контекст через `props` компонента.
Импорт хука и функций для работы с `jsApi` для `react` приложений осуществляется по пути `@nsmp/js-api/react`.
```tsx
import {JsApiComponentProps, useInitializeJsApi, getJsApi} from '@nsmp/js-api/react';
const EmbeddedApp = () => {
const jsApi = getJsApi();
return (
<div>{jsApi.findApplicationCode()}</div>
)
};
const App = (props: JsApiComponentProps) => {
const {context} = props;
useInitializeJsApi({
getContext: () => context
});
return (
<EmbeddedApp />
);
};
```
Пример использования с расширением методов `jsApi` через моки:
```tsx
import {deepMergeJsApi, getJsApi, IJsApi, JsApiComponentProps, jsApiMock, useInitializeJsApi} from '@nsmp/js-api/react';
// @nsmp/partial-js-api - используется в качестве примера, в реальности пакет не существует
import {IPartialJsApi, partialApiMock} from '@nsmp/partial-js-api';
const EmbeddedApp = () => {
const jsApi = getJsApi<IJsApi & IPartialJsApi>();
return (
<div>{jsApi.findApplicationCode()}</div>
)
};
const App = (props?: JsApiComponentProps) => {
useInitializeJsApi<IPartialJsApi>({
// В режиме разработки методы из переменной `partialApiMock` переопределят методы `jsApi`, которые есть в библиотеке
mock: process.env.NODE_ENV !== 'production' ? partialApiMock : {}
});
return (
<EmbeddedApp />
);
};
```
Объект `mock` это объект с таким же интерфейсом, как и объект `jsApi` в режиме `production`, но у него своя реализация методов под нужды разработки.
### ВП будет использоваться в окружениях `uiFrame` и `smp4`
Пример:
```typescript
import {initializeJsApi, getJsApi} from '@nsmp/js-api';
// В режиме `development` будут использоваться методы `jsApi`, которые определены в пакете @nsmp/js-api с помощью `mock` объекта
// Контекст берется автоматически из окружения, можно не передавать
initializeJsApi();
const jsApi = getJsApi();
jsApi.findContentCode();
```
Или
```typescript
import {initializeJsApi, IJsApi} from '@nsmp/js-api';
import {IMockApi, mockJsApi} from 'mocks/mockJsApi';
// В режиме `development` методы из переменной mockJsApi переопределят методы `jsApi`, которые есть в библиотеке
initializeJsApi<IMockApi>({mock: mockJsApi});
const jsApi = getJsApi<IJsApi & IMockApi>();
jsApi.findContentCode();
```
[К содержанию](#содержание)
## Типизация `jsApi`
Пакет предоставляет типы для методов `jsApi` в TypeScript:
- `JsApi` - включает все методы `jsApi`. Требует указания всех методов пакета, заменяя их новыми
- `PartialJsApi` - также включает все методы, но позволяет переопределять только необходимые, оставляя остальные без изменений
### Типизация собственных моков
Если нужно создать моки с частичным переопределением функций, а затем передать их в `initializeJsApi`, следует использовать тип `PartialJsApi` при создании моков.
Пример:
```typescript
import {PartialJsApi} from '@nsmp/js-api';
const mock: PartialJsApi = {
extractSubjectUuid () {
return 'subjectUuid$123';
},
findContentCode () {
return 'contentCode';
},
}
initializeJsApi(mock)
```
[К содержанию](#содержание)
## Переопределение методов `jsApi`
В пакете есть возможность переопределить стандартные методы. Для этого необходимо создать переменную в проекте, которая будет хранить новые значения методов `jsApi`, например:
```typescript
import {PartialJsApi} from '@nsmp/js-api';
// При работе с TypeScript указан тип PartialJsApi
const mockJsApi: PartialJsApi = {
extractSubjectUuid () {
return 'subjectUuid$123';
},
findContentCode () {
return 'contentCode';
},
getCurrentUser () {
return {
uuid: 'user$123'
};
},
urls: {
objectCard: (uuid: string) => `/${uuid}`
}
};
```
При работе с TypeScript переменной с моковыми методами `jsApi` можно указать тип PartialJsApi из данного пакета - [Типизация `jsApi`](#типизация-jsapi)
[К содержанию](#содержание)
## Конфигурации
### typescript для работы ВП
Для корректной работы `react` приложений необходимо в файле `tsconfig.json` добавить настройку:
```json
{
"compilerOptions": {
"moduleResolution": "bundler"
}
}
```
Это необходимо, чтобы путь `@nsmp/js-api/react` воспринимался компилятором
### typescript для jest
`moduleResolution: "bundler"` нельзя использовать с ts-jest — он не поддерживает этот режим. Для корректной работы `jest` необходимо создать новый файл конфигурации, например, `tsconfig.test.json`. В файле `tsconfig.test.json` добавить настройку:
```json
{
"compilerOptions": {
"moduleResolution": "node"
}
}
```
### jest
Хук `useInitializeJsApi` использует подключение `react`. Т.к. `react` не устанавливается в этом пакете, то он использует пакет из внешнего приложения.
При работе с `jest` может возникать ошибка, что в этом пакете нет `react`.
Для исправления проблемы нужно добавить настройку в файл `jest.confing.js`:
```javascript
module.exports = {
moduleNameMapper: {
'^react$': require.resolve('react')
}
}
```
Для подключения нового файла конфигурации, например, `tsconfig.test.json` нужно добавить настройку в файл `jest.confing.js`:
```javascript
module.exports = {
transform: {
'^.+\\.[t|j]sx?$': ['ts-jest', {
tsconfig: 'tsconfig.jest.json'
}]
}
}
```
[К содержанию](#содержание)
## Настройка проксирования запросов
Пакет имеет возможность проксирования запросов в режиме локальной разработки приложения. Чтобы проксирование запросов работало правильно, необходимо создать файл `dev.env` и определить переменные окружения:
- `ACCESS_KEY` - ключ доступа для REST запросов
- `APP_URL` - URL стенда
- `APP_CODE` - код ВП
- `CONTENT_CODE` - код контента, на котором выведено ВП
- `REST_PATH` - путь REST запроса (rest или earest)
- `SUBJECT_UUID` - идентификатор объекта, на котором выведено ВП
- `USER_LOGIN` - логин пользователя
- `USER_UUID` - идентификатор пользователя
Пример:
```dotenv
ACCESS_KEY=your-access-key
APP_URL=https://your-domain.ru/
APP_CODE=app_code
CONTENT_CODE=content_code
REST_PATH=earest
SUBJECT_UUID=subject$123
USER_LOGIN=your_login
USER_UUID=user$123
```
Также необходимо изменить строку запуска dev режима приложения в файле package.json, например:
- Было - `"dev": "cross-env NODE_ENV=development webpack serve --mode=development --config ./webpack/config.js"`
- Стало - `"dev": "cross-env NODE_ENV=development start-webpack-server --mode=development --config ./webpack/config.js --env ./dev.env"`
`config` и `env` являются опциональными аргументами командной строки. Если они не указаны по стандарту будут браться пути:
- `config` - `./webpack/config.js`
- `env` - `./dev.env`
Команда `start-webpack-server` запускает webpack server с добавленным в него проксированием запросов и всеми переменными окружения из файла `dev.env`
[К содержанию](#содержание)