184
Basis.js Роман Дворнов Июнь, 2014 «под капотом»

Basis.js – «под капотом»

  • Upload
    basisjs

  • View
    835

  • Download
    4

Embed Size (px)

DESCRIPTION

Технический обзор фреймворка basis.js, из чего он состоит, как работают некоторые его части.

Citation preview

Page 1: Basis.js – «под капотом»

Basis.js

Роман ДворновИюнь, 2014

«под капотом»

Page 2: Basis.js – «под капотом»

basis.js – фреймворк для разработки

одностраничный веб-приложений

2

Page 3: Basis.js – «под капотом»

Ядро

3

Page 4: Basis.js – «под капотом»

Ядро• Инициализация и настройка

• Вспомогательные функции

• Модульность

• Классы

4

Page 5: Basis.js – «под капотом»

Функции

5

Page 6: Basis.js – «под капотом»

Утилитарные функции• Работа с объектами, строками, числами, массивами и функциями

• Polyfill'ы для ES5 методов и исправления некоторых методов для старых браузеров

• Обертка над консольными методами (basis.dev)

6

Page 7: Basis.js – «под капотом»

Специальные функции• Функции по работе с путями (basis.path)

• Выполнение кода в следующем фрейме (basis.setImmediate/clearImmediate, basis.nextTick)

• Асинхронная работа с document (basis.doc)

• basis.getter, basis.ready

7

Page 8: Basis.js – «под капотом»

Модульность

8

Page 9: Basis.js – «под капотом»

CommonJS реализация близка к node.js

9

Page 10: Basis.js – «под капотом»

Пример// подключаем другие модулиvar foo = basis.require('./path/to/module.js');!

// делаем что-тоvar instance = new foo.SomeClass({ ... });!

// экспортируемmodule.exports = instance;

10

Page 11: Basis.js – «под капотом»

Модульность основана на ресурсах

11

Page 12: Basis.js – «под капотом»

Ресурс – это интерфейс к файлу

12

Page 13: Basis.js – «под капотом»

Ресурс• Ленивый интерфейс (объявление не приводит к загрузке содержимого)

• Это функция – ее вызов или ее метода .fetch() возвращает содержимое ресурса, которое кешируется

• Повторный вызов возвращает значение из кеша

13

Page 14: Basis.js – «под капотом»

Пример// объявление, файл не будет загруженvar someText = basis.resource('./path/to/file.txt');!

// файл будет загружен, его содержимое// будет закешировано и возвращеноconsole.log(someText());!

// эквивалент, будет возвращено уже закешированое значениеconsole.log(someText.fetch());

14

Page 15: Basis.js – «под капотом»

basis.require(..) =

basis.resource(..).fetch()

15

Page 16: Basis.js – «под капотом»

Расширение файла определяет тип результата

16

Page 17: Basis.js – «под капотом»

Разные типы

17

JSON.parse(content)

compileAndRun(content)

new CssResource(content)

content

.json

.js

.css

все остальное

Расширение Результат

Page 18: Basis.js – «под капотом»

Можно добавить свой типvar Compiler = basis.require('./path/to/cs.js').CoffeeScript;var processJs = basis.resource.extensions['.js'];!

basis.resource.extensions['.coffee'] = function(content, url){ return processJs(Compiler.compile(content), url); };

18

* так же делается и в node.js

Page 19: Basis.js – «под капотом»

Относительные пути

19

Page 20: Basis.js – «под капотом»

JS-модули получают• __filename* – путь к файлу

• __dirname* – путь к папке файла

• resource = basis.resource(__dirname + fn)

• require = basis.require(__dirname + fn)

20

* как и в node.js

Page 21: Basis.js – «под капотом»

Разрешение путей

• basis.resource и basis.require разрешают пути относительно html файла

• resource и require – относительно файла модуля

21

Page 22: Basis.js – «под капотом»

Относительные пути упрощают реструктуризацию проекта

22

Page 23: Basis.js – «под капотом»

Пространства имен

23

Page 24: Basis.js – «под капотом»

В начале играли важную роль

24

Page 25: Basis.js – «под капотом»

Ресурсы уменьшили их значимость, планомерно выводим из

фреймворка

25

docs.google.com/document/d/1no1mEp3BsWa8DaXz675oKnLgapSUKcXBwYEo9LOj_DA/edit

Page 26: Basis.js – «под капотом»

Остаются только как сокращение относительных путей

26

Page 27: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Page 28: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейс

Page 29: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейсИм назначается абсолютный путь

Page 30: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейсИм назначается абсолютный путь

/abs/path/to/

Page 31: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейс Путь к файлуИм назначается абсолютный путь

/abs/path/to/

Page 32: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейс Путь к файлуИм назначается абсолютный путь Точки заменяются на слеши и

добавляет расширение .js

/abs/path/to/

Page 33: Basis.js – «под капотом»

Namespace → path

27

basis.ui.popup

Корневой неймспейс Путь к файлуИм назначается абсолютный путь Точки заменяются на слеши и

добавляет расширение .js

/abs/path/to/ basis/ui/popup.js

Page 34: Basis.js – «под капотом»

Классы

28

Page 35: Basis.js – «под капотом»

Придерживаемся prototype inheritance

29

Page 36: Basis.js – «под капотом»

синтасический сахар лишь для создания

классов и экземпляров

30

Page 37: Basis.js – «под капотом»

Создание классаvar Foo = basis.Class(null, { property: 'example', init: function(value){ // конструктор this.property = value; }, method: function(){ // что-то делаем }});

31

Page 38: Basis.js – «под капотом»

Наследованиеvar Bar = Foo.subclass({ init: function(value){ Foo.prototype.init.call(this, value); // ... }, method: function(){ Foo.prototype.method.call(this); // ... }});

32

Page 39: Basis.js – «под капотом»

Наследованиеvar Bar = Foo.subclass({ init: function(value){ Foo.prototype.init.call(this, value); // ... }, method: function(){ Foo.prototype.method.call(this); // ... }});

32

Вызов переопределенных

методов

Page 40: Basis.js – «под капотом»

Больше сахара• Хелперы

• Авторасширение

• Расширяемые поля

33

basisjs.github.io/articles/ru-RU/basis.Class.html

Page 41: Basis.js – «под капотом»

Пользовательский интерфейс

34

Page 42: Basis.js – «под капотом»

Компонентный подход

35

Page 43: Basis.js – «под капотом»

36

«Component-based software engineering (CBSE) ... is a reuse-based approach

to defining, implementing and composing loosely coupled independent components

into systems...»

en.wikipedia.org/wiki/Software_component

Page 44: Basis.js – «под капотом»

Компонентный подход это про декомпозицию и

переиспользование

37

Page 45: Basis.js – «под капотом»

Обычный подход

38

list

item

item

item

item

Page 46: Basis.js – «под капотом»

Компонентный подход

39

list item

item

item

item

Page 47: Basis.js – «под капотом»

Обычный подход

40

window

form

field

field

panel button button

Page 48: Basis.js – «под капотом»

Компонентный подход

41

window form field

field

panel

button button

Page 49: Basis.js – «под капотом»

basis.ui.Node основная единица интерфейса

42

Page 50: Basis.js – «под капотом»

Стек функциональности

43

Функция Класс

События basis.event.Emitter

Данные basis.data.Object

DOM и патерны basis.dom.wrapper.Node

Шаблон basis.ui.Node

Наследование

Page 51: Basis.js – «под капотом»

Событияbasis.event.Emitter

44

Page 52: Basis.js – «под капотом»

Патерн Observer

45

Page 53: Basis.js – «под капотом»

Общение между объектами осуществляется

через события

46

Page 54: Basis.js – «под капотом»

Почти все классы наследники Emitter

47

Page 55: Basis.js – «под капотом»

Событие – специальный метод

48

Page 56: Basis.js – «под капотом»

Событие – специальный метод

var Foo = basis.Class(null, { emit_myEvent: basis.event.create('myEvent'), method: function(){ // выбрасываем событие this.emit_myEvent(foo, bar); }});

49

Объявляем

Используем

Page 57: Basis.js – «под капотом»

Работа со слушателямиvar emitter = new basis.event.Emitter();var handler = { foo: function(){ .. }, bar: function(){ .. }};!

// добавление слушателяemitter.addHandler(handler, context);// удаление слушателяemitter.removeHandler(handler, context);

50

Page 58: Basis.js – «под капотом»

Работа со слушателямиvar emitter = new basis.event.Emitter();var handler = { foo: function(){ .. }, bar: function(){ .. }};!

// добавление слушателяemitter.addHandler(handler, context);// удаление слушателяemitter.removeHandler(handler, context);

50

Обычно переиспользуется

Page 59: Basis.js – «под капотом»

Обработчики хранятся списком

51

Page 60: Basis.js – «под капотом»

Эффективно по памяти

52

Фреймворк 1 событие 2 события 3 события

Basis 240 240 240

Backbone 1 520 2 860 3 840

Ember 5 480 6 520 7 560

10 000 экземпляров, Кб

Page 61: Basis.js – «под капотом»

Эффективно по времени

53

Фреймворк 1 событие 2 события 3 события

Basis ~ 0 ~ 0 ~ 0

Backbone 20 29 38

Ember 49 68 89

10 000 экземпляров, ms

Page 62: Basis.js – «под капотом»

Данные basis.data.Object

54

Page 63: Basis.js – «под капотом»

Интерфейсный узелможет быть моделью

55

Page 64: Basis.js – «под капотом»

Хранить данных как ключ-значение

56

Page 65: Basis.js – «под капотом»

Работа c даннымиvar object = new basis.data.Object({ data: { foo: 1, bar: 2 }});!

// обновляемobject.update({ bar: 3, baz: 4 });

57

Если будут изменения, выбросит событие update с дельтой и вернет дельту.

Здесь дельта { bar: 2, baz: undefined }

Page 66: Basis.js – «под капотом»

Но в основном ради делегирования*

58

* об этом будет дальше

Page 67: Basis.js – «под капотом»

DOM basis.dom.wrapper.Node

59

Page 68: Basis.js – «под капотом»

Интерфейс представляет собой одно большое дерево

60

Page 69: Basis.js – «под капотом»

Для его организации используется модель DOM

61

Page 70: Basis.js – «под капотом»

Взято из DOM• свойства:

childNodes, firstChild, lastChild, nextSibling, previousSibling, parentNode

• методы:appendChild, insertBefore, removeChild, replaceChild

62

Page 71: Basis.js – «под капотом»

Свои дополнения• сателлиты*

• методы:setChildNodes, clear

63

* basisjs.github.io/articles/ru-RU/basis.dom.wrapper_satellite.html

Page 72: Basis.js – «под капотом»

DOM дает универсальность

64

Page 73: Basis.js – «под капотом»

Общие патерны• сортировка

• группировка (любая вложенность)

• выделение (с созданием контекста)

• disabled/enabled (с созданием контекста)

• и т.д.65

Page 74: Basis.js – «под капотом»

Привязка данных:автоматическая синхронизация

набор → childNodes

66

Page 75: Basis.js – «под капотом»

Большая часть фич в basis.js возможна именно

благодаря DOM

67

Page 76: Basis.js – «под капотом»

Шаблон basis.ui.Node

68

Page 77: Basis.js – «под капотом»

На модуле basis.ui лежит вся работа с шаблоном

69

Page 78: Basis.js – «под капотом»

На стороне JavaScript

70

var view = new basis.ui.Node({ template: resource('./button.tmpl'), binding: { ... }, action: { ... }});

Page 79: Basis.js – «под капотом»

На стороне JavaScript

70

var view = new basis.ui.Node({ template: resource('./button.tmpl'), binding: { ... }, action: { ... }});

Описание шаблона

Page 80: Basis.js – «под капотом»

На стороне JavaScript

70

var view = new basis.ui.Node({ template: resource('./button.tmpl'), binding: { ... }, action: { ... }});

Значения для шаблона

Описание шаблона

Page 81: Basis.js – «под капотом»

На стороне JavaScript

70

var view = new basis.ui.Node({ template: resource('./button.tmpl'), binding: { ... }, action: { ... }});

Значения для шаблона

Действия, которые можно вызывать из шаблона

Описание шаблона

Page 82: Basis.js – «под капотом»

Binding

71

var Foo = basis.ui.Node.subclass({ title: 'no title', binding: { title: function(leaf){ return leaf.title; } }, setTitle: function(newTitle){ this.title = newTitle; this.updateBind('title'); // когда надо обновить }});

binding – дополняется при наследовании

Page 83: Basis.js – «под капотом»

Обычно есть события

72

var Foo = basis.ui.Node.subclass({ binding: { disabled: { events: ['disable', 'enable'], getter: function(node){ return node.isDisabled(); } } }});

Page 84: Basis.js – «под капотом»

Action

73

var Foo = basis.ui.Node.subclass({ ... action: { select: function(event){ this.select(); }, ... }});

action – дополняется при наследовании

Page 85: Basis.js – «под капотом»

В шаблоне

74

<div class="foo {selected}" event-click="select"> {caption}</div>

Page 86: Basis.js – «под капотом»

В шаблоне

74

<div class="foo {selected}" event-click="select"> {caption}</div>

Значения из binding

Page 87: Basis.js – «под капотом»

В шаблоне

74

<div class="foo {selected}" event-click="select"> {caption}</div>

Значения из binding

Выполнение действия из action по событию

Page 88: Basis.js – «под капотом»

Разделение логики и представления

75

Объект Шаблон (DOM fragment)

binding

action

DOM операции

event listeners

DocumentJavaScript

Page 89: Basis.js – «под капотом»

В коде• Абстрагируемся от верстки

• Нет селекторов

• Нет указания CSS классов, имен тегов

• Нет HTML

• Нет стилей

76

Page 90: Basis.js – «под капотом»

В шаблонах• Не известно как и откуда берутся значения

• Нет кода

• Нет циклов

• Нет ветвлений (if)*

• Нет вычислений*

77

* вероятно появится

Page 91: Basis.js – «под капотом»

В большинстве случаев полное разделение

логики и представления

78

Page 92: Basis.js – «под капотом»

Но в любом правиле есть исключения ;)

79

Page 93: Basis.js – «под капотом»

Компоненты

80

Page 94: Basis.js – «под капотом»

В basis.js есть готовые компоненты

81

Page 95: Basis.js – «под капотом»

… но больше как пример и для прототипирования

82

Page 96: Basis.js – «под капотом»

Создавать свои компоненты достаточно просто

83

Page 97: Basis.js – «под капотом»

Делаем кнопку

84

Page 98: Basis.js – «под капотом»

Модуль с классомmodule.exports = require('basis.ui').Node.subclass({ template: resource('./button.tmpl'), binding: { caption: 'caption' }, action: { click: function(){ if (!this.isDisabled()) this.click(); } }});

85

Page 99: Basis.js – «под капотом»

Шаблон и стиль

<b:style src="./button.css"/><button class="my-button" event-click="click"> {caption}</button>

86

.my-button { ...}

Стиль (button.css)

Шаблон (button.tmpl)

Page 100: Basis.js – «под капотом»

Используемvar Button = require('./path/to/button.js');!

new Button({ caption: 'Click me!', click: function(){ alert('Hello world!'); }});

87

Page 101: Basis.js – «под капотом»

Данные

88

Page 102: Basis.js – «под капотом»

Классы basis.js

89

НаборыОбъектыСкаляры

Token Object

Entity

Dataset

Merge Автоматические наборы

Агрегатные функции

Value

Expression

Источники данныхТрансформеры

Vector

Page 103: Basis.js – «под капотом»

Особенности• Все данные имеют состояние

• При изменении данных создается дельта изменений

• Механизм делегирования

• Объекты взаимодействуют через изменение данных и состояния

• ...

90

Page 104: Basis.js – «под капотом»

Делегирование

91

Page 105: Basis.js – «под капотом»

Как работает

92

Данные и состояние

Данные и состояние

basis.data.Objectbasis.data.Object

Page 106: Basis.js – «под капотом»

Как работает

92

Данные и состояние

Данные и состояние

basis.data.Objectbasis.data.Objectdelegate

Page 107: Basis.js – «под капотом»

Как работает

92

Данные и состояние

basis.data.Objectbasis.data.Objectdelegate

Page 108: Basis.js – «под капотом»

93

С.delegate -> B D.delegate -> B B.delegate -> A

A

DC

B

Строим деревья

Page 109: Basis.js – «под капотом»

93

Данные и состояние

С.delegate -> B D.delegate -> B B.delegate -> A

A

DC

B

Строим деревья

Page 110: Basis.js – «под капотом»

На практике

94

window

panel

button button

Page 111: Basis.js – «под капотом»

На практике

94

window

panel

button button

new Button({ delegate: panel, handler: { stateChanged: function(){ this.setDisabled( this.state == 'processing'); } }});

Page 112: Basis.js – «под капотом»

На практике

94

window

panel

button button

new Button({ delegate: panel, handler: { stateChanged: function(){ this.setDisabled( this.state == 'processing'); } }});

Сработает, не важно у кого менять состояние: у кнопки, панели или окна –

данные и состояние одни

Page 113: Basis.js – «под капотом»

dataSource → childNodes

95

Datasetbasis.ui.Node

Object

Object

Object... ItemschildNodes

Page 114: Basis.js – «под капотом»

dataSource → childNodes

95

Datasetbasis.ui.NodedataSource

Object

Object

Object... ItemschildNodes

Page 115: Basis.js – «под капотом»

dataSource → childNodes

95

Datasetbasis.ui.NodedataSource

Object

Object

Object...

Node

Node

Node...

delegate

delegate

delegate

ItemschildNodes

Page 116: Basis.js – «под капотом»

Разные задачи, разные решения

96

• Произвольные поля • Строгий набор полей • Вычисляемые поля • Индекс • Нормализация значений • Defaults • Rollback • ...

basis.entity.Entitybasis.data.Objectдешево и сердито дороже, но с плюшками

Page 117: Basis.js – «под капотом»

97

Подробнее в докладе Не бойся, это всего лишь данные... просто их много

tinyurl.com/client-side-big-data

Page 118: Basis.js – «под капотом»

Наборы данных

98

Dataset (Collection)

Page 119: Basis.js – «под капотом»

Набор – это неупорядоченное множество объектов

99

Page 120: Basis.js – «под капотом»

"Автоматические" наборы• Merge – слияние множеств: объединение, разность и др

• Subtract – вычитание

• Filter – получение подмножества

• Split – разбиение на группы 1:1

• Cloud – разбиение на группы 1:М

• Slice – срез

• Extract – разворачивание

100

Page 121: Basis.js – «под капотом»

Наборы: пример

101

Page 122: Basis.js – «под капотом»

102

contacts

Page 123: Basis.js – «под капотом»

103

???

selected contacts

Page 124: Basis.js – «под капотом»

104

new basis.data.dataset.Subtract({ minuend: contacts, subtrahend: selectedContacts });

Page 125: Basis.js – «под капотом»

105

new basis.data.dataset.Filter({ source: new basis.data.dataset.Subtract({ minuend: contacts, subtrahend: selectedContacts }), rule: function(item){ return /ч/i.test(item.data.title); } });

Page 126: Basis.js – «под капотом»

Итог• Описана некоторая логическая схема связи данных и компонент

• Код работающий с contacts и selectedContacts остался прежним

• О согласованности наборов и данных заботится фреймворк

106

Page 127: Basis.js – «под капотом»

Шаблоны

107

Page 128: Basis.js – «под капотом»

DOM-based шаблонизатор

108

Page 129: Basis.js – «под капотом»

Известно какая будет DOM-структура и как будет

меняться

109

Page 130: Basis.js – «под капотом»

... еще до построения нативного DOM, на этапе

парсинга

110

Page 131: Basis.js – «под капотом»

111

<div class="entry"> {title}</div>

На этапе парсинга

Атрибут

Текстовый узел

Элемент

Page 132: Basis.js – «под капотом»

112

Описание шаблона = DOM узлы + инструкции

Page 133: Basis.js – «под капотом»

Знания о DOM структуре позволяют использовать

оптимизации

113

Page 134: Basis.js – «под капотом»

Например

• cloneNode(true) – быстрое создание DOM-фрагмента

• обработка событий через один глобальный capture-обработчик на документе для каждого уникального события

114

Page 135: Basis.js – «под капотом»

Шаблонизатор производит DOM-фрагменты

и обслуживает их

115

Page 136: Basis.js – «под капотом»

116

<div{el} class="example"> {text}</div>

{ el: <div>, text: #text, set: function(name, value){ ... }}

Описание Экземпляр

Интерфейс прилагается

Запись в DOM

Page 137: Basis.js – «под капотом»

117

<div{el} class="example"> <h1>{text}</h1> <ul{content}/></div>

el = fragment.firstChildtext = el.firstChild.firstChildcontent = el.lastChild

Описание Получение ссылок

Нет нужды в селекторах

(пути генерирует шаблонизатор)

Page 138: Basis.js – «под капотом»

Процесс

• построение DOM-фрагмента или cloneNode(true)

• создание интерфейса

• DOM-операции118

Создание Обновление

• DOM-операции

Page 139: Basis.js – «под капотом»

Работает быстро

119

Page 140: Basis.js – «под капотом»

Может проигрывать при генерации больших

фрагментов неизменяемой верстки

120

Page 141: Basis.js – «под капотом»

Но выигрывает на генерации повторяющихся

фрагментов

121

Page 142: Basis.js – «под капотом»

TodoMVC

122

100 items 1000 items

AngularJS 125 ms 1491 ms

Backbone 53 ms 510 ms

Knockout 39 ms 489 ms

vanilla 23 ms 1882 ms

jQuery 20 ms 184 ms

Backbone + basis.js templates 18 ms 202 ms

basis.js 8 ms 95 ms

2.5x быстрее

Page 143: Basis.js – «под капотом»

Всегда выигрывают на обновлении

123

Page 144: Basis.js – «под капотом»

Подробнее в докладе

Как построить DOM

124

tinyurl.com/build-dom

Page 145: Basis.js – «под капотом»

Конструкции

125

Page 146: Basis.js – «под капотом»

Подключение стилей <b:style>

126

Page 147: Basis.js – «под капотом»

127

<b:style src="block.css"/>!

<div class="block block_{hidden}"> {caption}</div>

Подключение стилей

.block{ ...}.block_hidden{ ...}

block.cssblock.tmpl

Page 148: Basis.js – «под капотом»

Включение других шаблонов <b:include>

128

Page 149: Basis.js – «под капотом»

129

<b:style src="./example.css"/><div class="wrapper"> <b:include src="./button.tmpl"> <b:after ref="caption"> {count}</b:after> </b:include></div>

Включение шаблонов

Результат

example.tmpl

<b:style src="./button.css"/><b:style src="./example.css"/><div class="wrapper"> <button class="button"> {caption} {count} </button></div>

<b:style src="./button.css"/><button class="button"> {caption}</button>

button.tmpl

Page 150: Basis.js – «под капотом»

Изоляция стилей <b:isolate>

130

Page 151: Basis.js – «под капотом»

131

<b:style src="option.css"/>!

<div class="xo-bookings-change-status-popup-option xo-bookings-change-status-popup-option_{disabled} xo-bookings-change-status-popup-option_{hidden}"> <span class="xo-bookings-change-status-popup-option__caption xo-bookings-change-status-popup-option__caption_{selected}"> {title} </span></div>

До

Page 152: Basis.js – «под капотом»

132

<b:style src="option.css"/><b:isolate/>!

<div class="option option_{disabled} option_{hidden}"> <span class="caption caption_{selected}"> {title} </span></div>

После

Page 153: Basis.js – «под капотом»

Храним шаблоны в отдельных файлах

133

Page 154: Basis.js – «под капотом»

Абстрагирование +

внешние файлы =

Live update134

Page 155: Basis.js – «под капотом»

Live update – обновление DOM-фрагментов без перезагрузки страницы

135

Page 156: Basis.js – «под капотом»

136

<div class="sidebar"> ...

<ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ...

</div>

<div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul></div>

Замена DOM-фрагментаСтарый DOM Новый DOM

Page 157: Basis.js – «под капотом»

136

<div class="sidebar"> ...

<ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ...

</div>

<div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul></div>

insertBefore

Замена DOM-фрагментаСтарый DOM Новый DOM

Page 158: Basis.js – «под капотом»

136

<div class="sidebar"> ...

<ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ...

</div>

<div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul></div>

replaceChild

insertBefore

Замена DOM-фрагментаСтарый DOM Новый DOM

Page 159: Basis.js – «под капотом»

Live update +

Логика =

Адаптивные View

137

Page 160: Basis.js – «под капотом»

Live update +

Наборы шаблонов =

Темы

138

Page 161: Basis.js – «под капотом»

Тема = HTML + CSS

139

Page 162: Basis.js – «под капотом»

Без перезагрузки страницы!

140

Page 163: Basis.js – «под капотом»

Live update экономит время и

разгоняет разработку

141

Page 164: Basis.js – «под капотом»

Экземпляры шаблонов хранят мета-информацию*

142

* только в dev-режиме

Page 165: Basis.js – «под капотом»

Возможность определять к какому шаблону относится

DOM-узел

143

Page 166: Basis.js – «под капотом»

Это дает Heat map, карту показывающую

где и как часто меняется DOM

144

Page 167: Basis.js – «под капотом»

Анализ и выявление проблем• какие классы используются в разметке, но их нет в стилях

• какие селекторы никогда не сработают

• конфликты стилей

• и т.д.

145

Page 168: Basis.js – «под капотом»

Оптимальная сборка• Минимизация классов

• Удаление не используемых разметки и стилей

• и т.д.

146

Page 169: Basis.js – «под капотом»

Что есть еще?

147

Page 170: Basis.js – «под капотом»

Локализация

148

Page 171: Basis.js – «под капотом»

Роутер

149

Page 172: Basis.js – «под капотом»

Работа с сетью:ajax, jsonp, soap, upload

150

Page 173: Basis.js – «под капотом»

И разного всякого:crypt, dragdrop, resize,

computedStyle, UA, xml, etc.

151

Page 174: Basis.js – «под капотом»

Разработка

152

Page 175: Basis.js – «под капотом»

Инструменты153

Page 176: Basis.js – «под капотом»

basisjs-tools

• Консольный инструмент для разработки

• Работает под управлением node.js

• Установка:npm install -g basisjs-tools

154

Page 177: Basis.js – «под капотом»

В состав входят• server – dev-сервер

• extract – строит граф файлов и извлекает информацию о приложении

• build – сборка приложения

• create – кодогенерация

155

Page 178: Basis.js – «под капотом»

Сборка• Не требует деклараций, списков файлов, карты зависимостей и т.п.

• Рекурсивно парсит и анализирует файлы, строя граф файлов приложения

• Использует AST для анализа

• Может применять различные оптимизации

156

Page 179: Basis.js – «под капотом»

Достаточно выполнить

basis build

157

Page 180: Basis.js – «под капотом»

Google Chrome Plugin

158

(расширение для Developer Tools)

Page 181: Basis.js – «под капотом»

Резюме• Модульный фреймворк, решающий большую часть задач

• Большинство решений хорошо стыкуются между собой

• Полноценная экосистема (инструменты)

• Простое моделирование систем, меняющихся во времени

• Использование подходов "будущего": DOM-based шаблонизатор, анализ проекта и автоматическая его сборка, реактивное программирование

159

Page 182: Basis.js – «под капотом»

Ориентирован на большие долгосрочные проекты

160

Постоянное добавление нового функционала, удаление старого, переделка существующего

Page 183: Basis.js – «под капотом»

"Временные сложности" :)

• Только набирает известность и популярность

• Документация все еще в процессе написания

161

Page 184: Basis.js – «под капотом»

Вопросы?

162

Роман Дворнов @rdvornov [email protected]

basis.js basisjs.com

github.com/basisjs