Изоморфный JavaScript – Будущее уже здесь

Изоморфный JavaScript

Будущее уже здесь

Денис Речкунов, Flamp

«Мартин, в будущем

JavaScript изоморфный!»

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

Что он нам даёт?

Что он нам не даёт?

Как мы к этому пришли?

27 мая 2009 года вышел релиз

Автор — Райан Дал, разработчик из Joyent

Вот оно!

В 2011 году вышел релиз сборщика

Автор — Джеймс Холлидей (substack)

Словно Делориан для изоморфного JavaScript

Люди начали его использовать

В своих проектах

18 октября 2011 появился пост Nodejitsu

"Scaling Isomorphic Javascript Code"

9 ноября 2011 nodejitsu представляет фреймворк

16 июня 2012 года Yahoo релизит фреймворк Mojito

Но термин "изоморфный"

Стал популярным благодаря Спайку Брехему из Airbnb

11 ноября 2013 появляется пост

"Isomorphic JavaScript: The Future of Web Apps"

Позже Спайк Брехм выступает на JSConf 2014 с докладом "Building Isomorphic Apps"

Как добиться изоморфизма?

Нужно решить ряд проблем

Разный рендеринг

Virtual DOM (на сервере)

Virtual DOM (в браузере)

Мартин не в восторге от Virtual DOM

Template Helpers (на сервере)

Template Helpers (в браузере)

Мартин по-прежнему не сильно рад

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

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

Прогрессивный рендеринг (в браузере)

Мы с Мартином выбираем этот вариант

Как балансировать между серверным и браузерным окружением

Серверный роутер

			Router.prototype.route = function (request, response) {
			  var context = { ... };
			  var state = this.getState(request.url);
			  renderer.render(state, context, response);
			};
		

Серверный контекст

			var context = {
			  userAgent: request.headers['user-agent'],
			  location: request.url,
			  redirect: function (url) {
			    response.writeHead(302, {Location: url});
			  },
			  getCookie: function () { return request.headers.cookie; }
			  setCookie: function (string) {
			    response.setHeader('Set-Cookie', string);
			  }
			};
		

Браузерный роутер

			Router.prototype.route = function (state) {
			  var context = { ... }
			  renderer.render(state, context);
			};
		

Браузерный контекст

			var context = {
			  userAgent: window.navigator.userAgent,
			  location: window.location.pathname + window.location.search,
			  redirect: function (url) {
			    window.location = url;
			  },
			  getCookie: function () { return document.cookie; }
			  setCookie: function (string) {
			    document.cookie = string;
			  }
			};
		

На что срабатывает роутинг?

			window.addEventListener('popstate', function (event) {
			  router.route(event.state);
			});
			window.document.body.addEventListener('click', function (event) {
			  event.preventDefault();
			  var location = window.location.toString();
			  var state = router.getState(location);
			  window.history.pushState(state, '', location);
			  router.route(state);
			});
		

Ну а остальное детали

Запросы к API по-разному

Собирать серверный код для браузера

package.json

			"browser": {
			  "./lib/Renderer.js": "./browser/Renderer.js",
			  "./lib/Router.js": "./browser/Router.js"
			}
		

И так, что мы имеем?

Готовые фреймворки:

Будущее уже здесь

Несколько изоморфных веб-приложений:

Спасибо за внимание!

catberry.github.io
Денис Речкунов, Flamp (denis@rdner.de)
rdner