Изоморфные java script приложения с catberry.js
TRANSCRIPT
pragmadash Денис Речкуновnode.js-разработчик
Изоморфные JavaScript-приложенияс Catberry.js
Изоморфные приложения?
Одностраничный фронт-енд & SEO бэк-енд
Один код и
одно поведение
Зачем?Хочется:
1. Иметь одностраничное приложение
2. Не жертвовать SEO
3. Не повторяться (DRY)
4. Одну языковую среду — JavaScript
5. Экономить ресурсы сервера
6. И чтобы все это было просто
5
И не только мне хочется• Rendr (AirBnb)
• Kraken (Paypal)
• Mojito (Yahoo)
• Meteor
• Derby
• Invisible
• Ezel
• ... who knows?
6
Почему они
не так хороши?
Используют фронт-енд на сервере• Rendr, Ezel — Backbone
• Mojito — YUI
• MEAN — Angular
8
Привязаны к одной БДНапример, MongoDB:
• Rendr
• Meteor
• Derby + Redis
9
Навязывают сложный real-time• Meteor
• Derby
10
А хочется-то
просто сайт
Catberry.js
Service-Module-Placeholer• Service — RESTful API про данные
(node, Scala, Erlang и что угодно)
• Module — Подготовка данных для шаблона и обработка событий
• Placeholder — Шаблон
14
Почему не MVC?• Нет обработки и хранения данных как в Model
• Все обрабатывается и хранится на удаленном Service
• Placeholder не привязан к Model как View
• Placeholder привязан к Module
• Module инициатор обновления Placeholder`ов, а не Model
• Отслеживается состояние Module, а не Model
15
Потоковый рендеринг с бэк-енда• Нет "белого экрана"
• Браузер не простаивает
• Экономим память
17
Параллельный рендеринг на фронт-енде• Когда меняется состояние модуля
• Все запросы к RESTful API параллельны
• Все очень быстро
19
Настоящая изоморфность• URL path
• Очистка URL hash
• User Agent
• Referrer
• Чтение/редактирование Cookie
• Redirect
• Universal HTTP(S) request
• Rendered cache
20
Module API
Service Locatorlocator.register(‘uhr’, UHR);
locator.registerInstance('uhr', new UHR());
locator.resolve(‘uhr’, UHR);
locator.resolveInstance(SomeModuleDependsOnUHR);
01.
02.
03.
04.
22
Dependency Injectionfunction ModuleConstructor ($uhr, someConfigSection) {
// use injected $uhr
// and event config sections
}
01.
02.
03.
04.
23
Render methodModuleConstructor.prototype.renderSome = function () {
// get data from somewhere
return {some: data}; //
};
01.
02.
03.
04.
24
After methodModuleConstructor.prototype.afterRenderSome =
function (dataContext) {
// do everything with rendered Placeholder
};
01.
02.
03.
04.
25
Handle methodModuleConstructor.prototype.handleSome = function (event) {
// do something
// event.args
// event.element
// event.isEnding
// event.isHashChanging
};
01.
02.
03.
04.
05.
06.
07.
26
Submit methodModuleConstructor.prototype.submitSome = function (event) {
// handle form submit
// event.values
// event.element
};
01.
02.
03.
04.
05.
27
Конвенции именования
Auto camelCaseЕсли шаблон называется some-cool-placeholder
ModuleConstructor.prototype.renderSomeCoolPlaceholer =
function () {
// ...
};
И так для всех методов
01.
02.
03.
04.
29
PromisesМожно адаптировать колбэки
return new Promise(function (fulfill, reject) {
fulfill(result); // when ready
// or
reject(error); // if error
});
01.
02.
03.
04.
05.
30
PromisesЧейнинг асинхронного кода
promise
.then(function (result) {
// return Promise
})
.then(function (result) {
// return result
});
01.
02.
03.
04.
05.
06.
07.
31
PromisesОбработка ошибок в одном месте
promise
// many .then
.then(null, function (error) {
// handle error
});
01.
02.
03.
04.
05.
32
А где-то уже используется?
konfettin.ru
flamp.ru (скоро)
catberry.org (скоро)
33
Open Source
— это круто!
Благодаря чему все это есть?• Идея потокового рендеринга взята с trumpet
github.com/substack/node-trumpet
• Серверный код работает в браузере благодаря browserify
github.com/substack/node-browserify
• Используется форк форка шаблонизатора Dust
github.com/catberry/catberry-dust
• И все это подключается к express/connect
github.com/strongloop/express / github.com/senchalabs/connect
35
Где узнать больше?
github.com/catberry/catberry
twitter.com/catberryjs
runnable.com/catberry
$ npm -g install catberry-cli
$ catberry init example
01.
02.
36
Вопросы?