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

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

rdner

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

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

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

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

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

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

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

Почему?

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

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

Коротко

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

Подробнее

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

Зачем?

Хочется:

Что получаем

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

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

Почему?

Flux

Flux

Flux

Почему Flux?

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

Flux Stores в Catberry.js

Директория "catberry_stores" с .js-файлами
			./catberry_stores/
    doge/
        Wow.js
        Such.js
        Store.js
    grumpy-cat/
        No.js

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

			module.exports = Wow;
			function Wow() {...}
			// время актуальности данных в мс
			Wow.prototype.$lifetime = 60000;
			// загрузка данных
			Wow.prototype.load = function () {...}
			// обработка Action
			Wow.prototype.handleVeryAction = function () {...}
		

Метод "load"

			Wow.prototype.load = function () {...}
				// запрашивает данные, например по REST
				// возвращает объект или Promise
				return {such: 'load'};
			};
		

Метод "handle"

			Wow.prototype.handleVeryAction = function () {...}
				// может запостить данные по REST
				// вернуть результат или Promise
				return {very: 'action'};
			};
		

Метод "handle"

			Wow.prototype.handleVeryAction = function () {...}
				// а может отправить сигнал,
				// что Store изменился
				this.$context.changed();
			};
		

Web/Cat-Components

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

Cat-component

			hello-world/
    assets/
        hello.svg
        world.svg
    index.js
    template.hbs
    error.hbs
    cat-component.json

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

			<cat-hello-world id="uniq-id" 
			  cat-store="some/Store"
			  any-attribute="any-value">
			</cat-hello-world>
		
В этот тэг отрендерится шаблон, который может содержать тэги компонентов, процесс повторяется рекурсивно

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

			module.exports = HelloWorld;
			function HelloWorld() {...}
			// этапы жизни компонента
			HelloWorld.prototype.render = function () {...}
			HelloWorld.prototype.bind = function () {...}
			HelloWorld.prototype.unbind = function () {...}
		

Этап "render"

Тэг компонента рендерит свой шаблон
			HelloWorld.prototype.render = function () {
				// может вернуть данные для шаблона
				// или Promise на них
				return {hello: 'world'};
			};
		

Этап "bind"

Рендеринг завершен, можно привязать события
			HelloWorld.prototype.bind = function () {
				// может вернуть карту событий
				// для дочерних элементов или Promise на нее
				return {
					click: {'div.clickable': this.clickHandler}
				};
			};
		

Этап "unbind"

Компонент готовится к удалению или обновлению
			HelloWorld.prototype.unbind = function () {
				// здесь нужно прибраться, если вы
				// что-то делали в bind помимо карты событий
				// события из карты отвязываются автоматически
			};
		

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

this.$context

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

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

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

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

			this.$context.getStoreData()
			  .then(function () {
			    // ура, Store отдал данные
			  });
			  .catch(function (error) {
			    // печаль :(
			  });
		

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

			this.$context.sendAction('item-submit', item)
			  .then(function () {
			    // ура, Action обработался
			  });
			  .catch(function (error) {
			    // печаль :(
			  });
		

IoC и DI

Service Locator

			locator.register(‘uhr’, UHR);
			locator.registerInstance('uhr', new UHR());
			locator.resolve(‘uhr’);
			locator.resolveAll(‘uhr’);
			locator.resolveInstance(SomeConstructorDependsOnUHR);
		

Dependency Injection

			function StoreConstructor ($uhr, someConfigSection) {
			  // можно внедрять и использовать $uhr
			  // и внедрять даже конфиг-секции
			}
		

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

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

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

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

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

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

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

			$ npm -g install catberry-cli
			$ catberry init example
		
catberry-todomvc
catberry-homepage
catberry-debugger

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

catberry.github.io
github.com/catberry/catberry

Вопросы?