59
pragmadash Денис Речкунов Ведущий JavaScript-разработчик Зачем изоморфный JavaScript? Почему Catberry.js?

Зачем изоморфный JavaScript? Почему Catberry.js?

Embed Size (px)

Citation preview

Page 1: Зачем изоморфный JavaScript? Почему Catberry.js?

pragmadash Денис РечкуновВедущий JavaScript-разработчик

Зачем изоморфный JavaScript?Почему Catberry.js?

Page 2: Зачем изоморфный JavaScript? Почему Catberry.js?

Жизненнаяистория

Page 3: Зачем изоморфный JavaScript? Почему Catberry.js?

Вы – веб-разработчик

Page 4: Зачем изоморфный JavaScript? Почему Catberry.js?

И вот у вас заказчик

Page 5: Зачем изоморфный JavaScript? Почему Catberry.js?

Буду делать Single Page Application!

Page 6: Зачем изоморфный JavaScript? Почему Catberry.js?

Берете любимый фронт-енд фреймворк

Page 7: Зачем изоморфный JavaScript? Почему Catberry.js?

Радостно сдаёте проект

Page 8: Зачем изоморфный JavaScript? Почему Catberry.js?
Page 9: Зачем изоморфный JavaScript? Почему Catberry.js?

Почему?

• Долго открывается

• Плохо индексируется

• В старых браузерах—ничего

9

Page 10: Зачем изоморфный JavaScript? Почему Catberry.js?

Что можно сделать?

• Использовать headless browser

• Написать бэкенд

• Переписать все на изоморфном JavaScript-фреймворке

10

Page 11: Зачем изоморфный JavaScript? Почему Catberry.js?

ИзоморфныйJavaScript?

Page 12: Зачем изоморфный JavaScript? Почему Catberry.js?

Коротко

Page 13: Зачем изоморфный JavaScript? Почему Catberry.js?

Одностраничный фронт-енд & SEO бэк-енд

Page 14: Зачем изоморфный JavaScript? Почему Catberry.js?

Подробнее

Page 15: Зачем изоморфный JavaScript? Почему Catberry.js?

Что такое изоморфный JavaScript-код?

• Исполняется в различных окружениях

(нам важен сервер и браузер)

• Гарантирует одно поведение

• Справляется с разностью окружений через абстракции

15

Page 16: Зачем изоморфный JavaScript? Почему Catberry.js?

Зачем?

Хочется:

1. Иметь одностраничное приложение

2. Не жертвовать SEO

3. Быструю инициализацию страницы

4. Одну языковую среду — JavaScript

5. Экономить ресурсы сервера

6. И чтобы все это было просто

16

Page 17: Зачем изоморфный JavaScript? Почему Catberry.js?

Что получаем

1. Одностраничное приложение

2. HTML с сервера, используя тот же код

3. Задержки инициализации нет, HTML пришел с сервера

4. Вы пишите на серверном JavaScript

5. Сервер не особо напрягается (node.js хорош)

6. За вас всё сделает фреймворк (если он хорош)

17

Page 18: Зачем изоморфный JavaScript? Почему Catberry.js?

Какойфреймворк?

Page 19: Зачем изоморфный JavaScript? Почему Catberry.js?

Catberry.jsконечно же

Page 20: Зачем изоморфный JavaScript? Почему Catberry.js?

Почему?

• Flux-архитектура

• Изоморфные веб-компоненты

• Прогрессивный рендеринг

• Всё на Promises

• Dependency Injection

• Неблокирующие алгоритмы

20

Page 21: Зачем изоморфный JavaScript? Почему Catberry.js?

Flux

Page 22: Зачем изоморфный JavaScript? Почему Catberry.js?

Flux

Page 23: Зачем изоморфный JavaScript? Почему Catberry.js?

Flux

Page 24: Зачем изоморфный JavaScript? Почему Catberry.js?

Почему Flux?

Page 25: Зачем изоморфный JavaScript? Почему Catberry.js?

Flux — это более безопасный MVC

• Нет моделей и привязок

• Когда Store изменился, данные запрашиваются заново

• Есть Dispatcher, который контролирует Work~ow

• Нет беспорядка с событиями

• Обновление View полностью

25

Page 26: Зачем изоморфный JavaScript? Почему Catberry.js?

Flux Stores в Catberry.js

Директория "catberry_stores" с .js-файлами

./catberry_stores/

doge/

Wow.js

Such.js

Store.js

grumpy-cat/

No.js

26

Page 27: Зачем изоморфный JavaScript? Почему Catberry.js?

Как писать логику Store

module.exports = Wow;

function Wow() {...}

// время актуальности данных в мс

Wow.prototype.$lifetime = 60000;

// загрузка данных

Wow.prototype.load = function () {...}

// обработка Action

Wow.prototype.handleVeryAction = function () {...}

01.

02.

03.

04.

05.

06.

07.

08.

27

Page 28: Зачем изоморфный JavaScript? Почему Catberry.js?

Метод "load"

Wow.prototype.load = function () {...}

// запрашивает данные, например по REST

// возвращает объект или Promise

return {such: 'load'};

};

01.

02.

03.

04.

05.

28

Page 29: Зачем изоморфный JavaScript? Почему Catberry.js?

Метод "handle"

Wow.prototype.handleVeryAction = function () {...}

// может запостить данные по REST

// вернуть результат или Promise

return {very: 'action'};

};

01.

02.

03.

04.

05.

29

Page 30: Зачем изоморфный JavaScript? Почему Catberry.js?

Метод "handle"

Wow.prototype.handleVeryAction = function () {...}

// а может отправить сигнал,

// что Store изменился

this. $context .changed();

};

01.

02.

03.

04.

05.

30

Page 31: Зачем изоморфный JavaScript? Почему Catberry.js?

Web/Cat-Components

Page 32: Зачем изоморфный JavaScript? Почему Catberry.js?

Почти как веб-компоненты, но:

• Их можно отрендерить на сервере

• Они хранятся как директория в проекте

• Компонент описыватся файлом cat-component.json

• Шаблон на языке любого* шаблонизатора

• Нет Shadow DOM

• Можно ставить через NPM

32

Page 33: Зачем изоморфный JavaScript? Почему Catberry.js?

Cat-component

hello-world/

assets/

hello.svg

world.svg

index.js

template.hbs

error.hbs

cat-component.json

33

Page 34: Зачем изоморфный JavaScript? Почему Catberry.js?

Используются как кастомные тэги:

<cat-hello-world id="uniq-id"

cat-store="some/Store"

any-attribute="any-value">

</cat-hello-world>

В этот тэг отрендерится шаблон, который может содержать тэги

компонентов, процесс повторяется рекурсивно

01.

02.

03.

04.

34

Page 35: Зачем изоморфный JavaScript? Почему Catberry.js?

Как писать логику в index.js

module.exports = HelloWorld;

function HelloWorld() {...}

// этапы жизни компонента

HelloWorld.prototype.render = function () {...}

HelloWorld.prototype.bind = function () {...}

HelloWorld.prototype.unbind = function () {...}

01.

02.

03.

04.

05.

06.

35

Page 36: Зачем изоморфный JavaScript? Почему Catberry.js?

Этап "render"

Тэг компонента рендерит свой шаблон

HelloWorld.prototype.render = function () {

// может вернуть данные для шаблона

// или Promise на них

return {hello: 'world'};

};

01.

02.

03.

04.

05.

36

Page 37: Зачем изоморфный JavaScript? Почему Catberry.js?

Этап "bind"

Рендеринг завершен, можно привязать события

HelloWorld.prototype.bind = function () {

// может вернуть карту событий

// для дочерних элементов или Promise на нее

return {

click: {'div.clickable': this.clickHandler}

};

};

01.

02.

03.

04.

05.

06.

07.

37

Page 38: Зачем изоморфный JavaScript? Почему Catberry.js?

Этап "unbind"

Компонент готовится к удалению или обновлению

HelloWorld.prototype.unbind = function () {

// здесь нужно прибраться, если вы

// что-то делали в bind помимо карты событий

// события из карты отвязываются автоматически

};

01.

02.

03.

04.

05.

38

Page 39: Зачем изоморфный JavaScript? Почему Catberry.js?

Как в итоге это работает?

• Можно привязать компонент к Store через атрибут cat-store

• Когда Store меняется, обновляются все привязанные компоненты

• Store получают параметры из URL через роутинг

• Store может использовать данные другого Store

39

Page 40: Зачем изоморфный JavaScript? Почему Catberry.js?

this.$context

Page 41: Зачем изоморфный JavaScript? Почему Catberry.js?

У компонента или Store есть $context:

• isBrowser/isServer

• userAgent

• location/referrer

• locator

• redirect('location')/notFound()

• cookie.get('name')/cookie.set(object)

41

Page 42: Зачем изоморфный JavaScript? Почему Catberry.js?

У компонента дополнительно:

• element

• attributes

• getComponentById(‘id’)

• createComponent(‘name’, attributesObject)

• collectGarbage()

• getStoreData()

• sendAction(‘name’, object)

• sendBroadcastAction(‘name’, object)

42

Page 43: Зачем изоморфный JavaScript? Почему Catberry.js?

У Store дополнительно:

• state

• changed()

• setDependency('storeName')/unsetDependency('storeName')

• getStoreData('storeName')

• sendAction('storeName', ‘actionName’, object)

• sendBroadcastAction(‘name’, object)

43

Page 44: Зачем изоморфный JavaScript? Почему Catberry.js?

Как из компонента получить данные Store

this.$context.getStoreData()

.then(function () {

// ура, Store отдал данные

});

.catch(function (error) {

// печаль :(

});

01.

02.

03.

04.

05.

06.

07.

44

Page 45: Зачем изоморфный JavaScript? Почему Catberry.js?

Как из компонента отправить Action

this.$context.sendAction('item-submit', item)

.then(function () {

// ура, Action обработался

});

.catch(function (error) {

// печаль :(

});

01.

02.

03.

04.

05.

06.

07.

45

Page 46: Зачем изоморфный JavaScript? Почему Catberry.js?

IoC и DI

Page 47: Зачем изоморфный JavaScript? Почему Catberry.js?

Service Locator

locator.register(‘uhr’, UHR);

locator.registerInstance('uhr', new UHR());

locator.resolve(‘uhr’);

locator.resolveAll(‘uhr’);

locator.resolveInstance(SomeConstructorDependsOnUHR);

01.

02.

03.

04.

05.

47

Page 48: Зачем изоморфный JavaScript? Почему Catberry.js?

Dependency Injection

function StoreConstructor ( $uhr , someConfigSection) {

// можно внедрять и использовать $uhr

// и внедрять даже конфиг-секции

}

01.

02.

03.

04.

48

Page 49: Зачем изоморфный JavaScript? Почему Catberry.js?

Прогрессивныйрендеринг

Page 50: Зачем изоморфный JavaScript? Почему Catberry.js?

Как работает Catberry.js

50

Page 51: Зачем изоморфный JavaScript? Почему Catberry.js?

Что происходит первый раз на сервере:

• Используется Node.js Streams API,

Catberry реализует Transform Stream

• ourTransform.pipe(response).end(document.render());

• Transform Stream ищет кастомные тэги компонентов в стриме HTML

• Если нашел—рендерит в них соответствующий шаблон

• Который пропускается через такой же Transform Stream

• Отрендеренный HTML сразу уходит в браузер порциями

51

Page 52: Зачем изоморфный JavaScript? Почему Catberry.js?

Что происходит потом в браузере:

• Используется History API и перехватывается любой клик по ссылке

• Если ссылка попадает под роутинг, из URL парсятся новые параметры

• Параметры применяются к Stores, у них вызывается

this.$context.changed();

• Вычисляются корни изменений в DOM

• Начинается пошаговый ререндеринг изменившихся компонентов

• Данные запрашиваются в процессе

52

Page 53: Зачем изоморфный JavaScript? Почему Catberry.js?
Page 54: Зачем изоморфный JavaScript? Почему Catberry.js?

Когда у вас прогрессивный рендеринг

54

Page 55: Зачем изоморфный JavaScript? Почему Catberry.js?
Page 56: Зачем изоморфный JavaScript? Почему Catberry.js?

В боевых условиях

• Flamp.ru/best—это 3 млн уников в месяц и 20 млн просмотров

• Konfettin.ru

• статус-строй.рф

• С десяток проектов в разработке по всему миру:

Аргентина, Латвия, Украина, США, Россия

56

Page 57: Зачем изоморфный JavaScript? Почему Catberry.js?

С чего начать?

$ npm -g install catberry-cli

$ catberry init example

catberry-todomvc

catberry-homepage

catberry-debugger

01.

02.

57

Page 58: Зачем изоморфный JavaScript? Почему Catberry.js?

Где следить за новостями?

catberry.org

github.com/catberry/catberry

twitter.com/catberryjs

58

Page 59: Зачем изоморфный JavaScript? Почему Catberry.js?

Вопросы?