Как мы разрабатываем новый фронтенд / Филипп Нехаев (Tinkoff.ru)
«Пуленепробиваемый фронтенд: разработка под React на...
Transcript of «Пуленепробиваемый фронтенд: разработка под React на...
![Page 1: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/1.jpg)
Пуленепробиваемый фронтенд
Станислав Панферов
![Page 2: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/2.jpg)
Рассказывает
Рассказывает Станислав Панферов
Специализация Tech Lead
Чем занимается Разработка фронта и бекенда
Сейчас работаю Альфа Лаборатория
До этого работал NPTV
Опыт Более 7 лет
2
![Page 3: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/3.jpg)
План доклада
1. Когда нужна и когда не нужна типизация
2. Типизация компонент ReactJS
3. Типизация и Flux
4. Инструменты сборки
3
![Page 4: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/4.jpg)
4
Когда плюсы не очевидны?
➔ У вас в команде 2 - 3 человека
➔ Вы удерживаете в голове весь код проекта и основные зависимости
➔ Вы больше пишете, чем читаете и изменяете
➔ Покрытие кода юнит-тестами превышает 80%
![Page 5: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/5.jpg)
5
Когда нужна типизация?
➔ Команда из четырех и более человек
➔ Вы не можете удержать в голове весь код проекта
➔ Вы много рефакторите и читаете код
➔ Покрытие кода юнит-тестами менее 80%
![Page 6: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/6.jpg)
6
Почему React легко типизировать?
➔ Понятные точки типизации (props и state)
➔ Нет строковых шаблонов, только JavaScript
➔ Стандартная обвязка: ES6 Classes + ES6 Modules
Typed state
Component
Typed props Typed callbacks
![Page 7: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/7.jpg)
export class LinkClass extends React.Component {
render() {
var cssClass = cx('link'
this.props.behavior,
this.props.size
);
return dom.a({className: cssClass}, this.props.children);
}
}
export var Link = React.createFactory(LinkClass);
7
![Page 8: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/8.jpg)
export class LinkClass extends React.Component {
render() {
var cssClass = cx('link'
this.props.behavior, // 'normal', 'large'
this.props.size // 'navigate', 'control'
);
return dom.a({className: cssClass}, this.props.children);
}
}
export var Link = React.createFactory(LinkClass);
8
![Page 9: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/9.jpg)
9
Link({}) // behavior обязательный
Link({
size : 'big', // значение не из допустимого набора
behavior : 'cotrol' // значение написано с ошибкой
})
![Page 10: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/10.jpg)
propTypes: {
size: React.PropTypes.oneOf([
'normal',
'large'
]),
behavior: React.PropTypes.oneOf([
'navigate',
'control'
]).isRequired
}
10
![Page 11: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/11.jpg)
11
Минусы propTypes:
1. Проверки типов осуществляются в runtime
2. Невозможно выразить контракты на функции
3. Проверяются только в development окружении
4. Нельзя типизировать бизнес-логику
![Page 12: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/12.jpg)
ReactJS ♡ TypeScript
12
1. Напишем типы для полей Props и State
2. Напишем интерфейсы для Props и State
3. Укажем типы в компоненте
![Page 13: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/13.jpg)
export enum LinkSize {
Normal = <any>'normal',
Large = <any>'large'
}
export enum LinkBehavior {
Navigate = <any>'navigate',
Control = <any>'control'
}
13
Перечисления:
1. Документируют значения
2. Позволяют проверять значения из набора при компиляции
Типы для полей
![Page 14: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/14.jpg)
export interface LinkProps extends React.HTMLAttributes {
size?: LinkSize;
behavior: LinkBehavior;
}
export interface LinkState { }
14
Интерфейсы:
1. Документируют структуру объектов.
2. Позволяют проверять структуру объектов при компиляции.
Интерфейсы для Props и State
![Page 15: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/15.jpg)
export class LinkClass extends React.Component<LinkProps, LinkState> {
/* the same ... */
}
15
Типы в компоненте
![Page 16: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/16.jpg)
16
Link({})
> Argument of type '{}' is not assignable to parameter of type '{ size?:
LinkSize; behavior: LinkBehavior; }'. Property 'behavior' is missing in type
'{}'.
Link({
size : LinkSize.Big,
behavior : LinkBehavior.Cotrol
})
> Property 'Big' does not exist on type 'typeof LinkSize'.
![Page 17: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/17.jpg)
17
Выводы
➔ TypeScript позволяет типизировать компоненты
➔ Проверки осуществляются в compile time
➔ Типизировать не сложно
➔ Система типов позволяет проверять больше
![Page 18: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/18.jpg)
18
JSX в разработке
#2673
![Page 19: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/19.jpg)
А что с Flux?
19
![Page 20: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/20.jpg)
➔ Используем канонический Flux от
➔ Пишем с расчетом на типизацию
20
![Page 21: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/21.jpg)
export class Navigate extends Action {
constructor(public route: Route) { super() }
}
dispatcher.dispatch(new Navigate(route))
class AppStore extends Store {
dispatch(action: Action) {
if (action instanceof Navigate) { /* .. */ }
}
}
21
1. Action — общий интерфейс для всех событий.
2. События делаем классами.
3. В сторах используем instanceof для автоматического приведения типов.
![Page 22: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/22.jpg)
Выводы
➔ TypeScript для UI и бизнес-логики
➔ Больше контекста и документации
➔ Быстрое обнаружение ошибок
➔ Чтение, отладка и рефакторинг — быстрее
➔ Интеграция с IDE
22
![Page 23: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/23.jpg)
Инструментарий
23http://bit.ly/react_typescript
![Page 24: «Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав Панферов, MoscowJS 21](https://reader034.fdocument.pub/reader034/viewer/2022042701/55a77b8b1a28abbf668b4590/html5/thumbnails/24.jpg)
Спасибо!C вами был Станислав Панферов
24