3. Write Less / Do More
Эра jQuery
$(element) - Основная структурная единица
1 Все манипуляции ориентированы на DOM ноды
Plugin основная единица экосистемы
2 Большинство популярных решений имели избыточный объем кода
Server Side Rendering
3 Получение отрендеренного html'a один из классических подходов эры
4. Model View Controller
ЭРА MVVC / MVC / VM / MC / MV / VC / ETC...
Plain JS Object - Основная архитектурная единица
1 new Constructor(), Object.prototype, Object.extend({}), итд...
Client-Side Rendering
2 Избавление сервера от дополнительной работы с шаблонами + гибкость
Триумф AMD
3 Загрузка модулей через AJAX, явные зависимости, и сборка на Java
Утром Data - Вечером HTML
4 Тренд на Dom-First Apps резко изменился на Data-First Apps
5. Наше время
Компонентная эра
Компоненты как архитектурная единица
1 Теперь модуль это не только Javascript. Все asset'ы внутри.
Триумф CommonJS
2 NPM, Модули для сервера и браузера, browserify, изоморфность.
Реактивное и асинхронное программирование
3 Promise, Generators, NextTick, Pipes
Большая нагрузка на клиента - почва для оптимизаций
4 Ленивая загрузка, разделение приложения на части, benchmarking
7. Построен на принципах реактивного программирования
Основные принципы
1 Vue.nextTick(), Queue, Reactive Directives
Поддерживает концепцию Web Components
2 V-component, Vueify, Component Registry, Custom Directives
Сущность это простой (plain) Javascript объект
3 Template as HTML String, Component as Javascript Object
8. Единая сущность Vue
Основные принципы
4 Объект содержит в себе $data, $methods, $events итд...
Дружелюбен к модульным системам
5 Простая интеграция с Common.JS и другими модульными системами
10. Основные принципы
1
Module is Everything
HTML строка, CSS таблица, Javascript функция, нет разницы.
2Только Javascript? Нет.
Webpack умеет собирать не только Javascript, также графику, шрифты итд...
3Ленивая / Частичная загрузка из пакета
Важный инструмент для больших приложений без излишних расширений
11. Основные принципы
4
Ориентирован на Client-Side приложения
Hot Module Replacement, JSONP, и другие браузерные решения
5AMD / CommonJS / Native
Нет разницы какую систему модулей вы используете
13. Технические требования приложения
Расширяется как в ширину так и в высоту
Приложение состоит из модулей
Приложение может быть интернационализировано
Приложение может быть менять свой внешний
вид на разных платформах
15. /** Module dependencies */
var Vue = require('vue');
/** Define application */
var app = module.exports = new Vue({
el: '#v-app'
});
Точка входа в приложение
doctype html
html
head
title Simple application
body#v-app
script(src='/public/build.js')
Построим HTML Layout
22. /** Define component */
module.exports = {
// Как загрузить HTML в require?!
template: require('./template.html')
};
Опишем webpack.config.js
module.exports = {
module: {
loaders: [
{ test: /.html$/, loader: "html" }
]
}
};
Создаем первый компонент
Капля оптимизации
23. Webpack Loaders
Загрузчики это функции которые выполняют
трансформацию файлов в модули приложения.
Аналогичны browserify transform.
http://webpack.github.io/docs/using-loaders.html
27. Технические требования приложения
Расширяется как в ширину так и в высоту
Приложение состоит из модулей
Приложение может быть интернационализировано
Приложение может быть менять свой внешний
вид на разных платформах
29. Controller - компонент отвечающий за состояние приложения
Содержит в себе все нужные для работы компоненты
1
Является точкой разрыва приложения. App -> Controller -> Components
2
Controller определяется в зависимости от состояния URL
3
30. Схема сбора и запуска приложения
Client App URL
State
Controller
Component Component Component
Controller Controller
31. Контроллер - место где наше приложение начинает
ответвляться от приложения. Именно тут мы можем
разделить наше приложение на части.
Для решения этой задачи подойдет require.ensure
представленный в CommonJS спецификации.
Webpack поддерживает этот метод.
http://wiki.commonjs.org/wiki/Modules/Async/A
require.ensure(['increment'], function(require) {
var inc = require('increment').inc;
var a = 1;
inc(a); // 2
});
Синтаксис:
32. Создадим явную карту наших контроллеров
/** Routes map */
var map = {
main: require('./controllers/main'),
alt: require('./controllers/alt')
};
Создаем контроллеры
Проблематика:
Основной проблематикой клиентских загрузчиков модулей является
"неумение" работать с динамическими аргументами require(). В
текущих реализациях мы вынуждены указывать имена модулей
явно. Node.JS умеет подтягивать модули динамически.
33. Делаем нашу карту модулей ленивой
/** Routes map */
var map = {
main: require('promise?bluebird!./controllers/main'),
alt: require('promise?bluebird!./controllers/alt')
};
Создаем контроллеры
Альтернативный вариант вызова Webpack Loaders
Для трансформации модулей можно использовать дополнительные
строковые параметры внутри require() отделив их через знак "!". В
указаном выше случае мы загружаем модуль пропуская его через
promise-loader.
34. Немного о Promise-Loader
Создаем контроллеры
Трансформация этим модулем позволяет сделать отложенный
require.ensure и обернуть его в Promise объект.
// Указываем библиотеку для обертки в Promise
var load = require("promise?bluebird!./file.js");
// Модуль не будет загружен пока вы не вызовете функцию
load().then(function(module) {
// Здесь вы можете работать с вашим модулем
});
37. Указываем элемент в котором расположим контроллер
doctype html
html
head
title Simple application
body#v-app
#v-panel(v-component="panel")
#v-controller(v-el="controller")
script(src='/public/build.js')
Создаем контроллеры
38. Загружаем и запускаем контроллер
module.exports = new Vue({
el: '#v-app',
created: function() {
var controller = url.getController();
var load = map[controller]();
load.then(function (module) {
var ctrl = new Vue(module);
ctrl.$mount(this.$$.controller);
}.bind(this));
}
...
});
Создаем контроллеры
39. Связать управление контроллерами с HTML5 History API
Следующие шаги
1 Состояние приложения можно хранить в this.$data
Спроектировать ленивую загрузку внутри контроллера
2 Актуально для больших контроллеров
3 Как инструмент дополнительной оптимизации
Использовать ApplicationCache и Deduplication Plugin
40. Технические требования приложения
Расширяется как в ширину так и в высоту
Приложение состоит из модулей
Приложение может быть интернационализировано
Приложение может быть менять свой внешний
вид на разных платформах
41. module.exports = {
template: require('./templates/' + platform + '.html')
};
Динамическая загрузка модулей
- templates
- ios.html
- android.html
- windows.html
Отлично подходит для кросс-платформенных решений
Другие возможности
42. Динамическая загрузка модулей
Другие возможности
При такой загрузке в сборку попадут все модули из
папки ./templates с форматом .html, а также внутри
загрузчика появиться карта соответствия имени
файла, id'шнику модуля.
43. Технические требования приложения
Расширяется как в ширину так и в высоту
Приложение состоит из модулей
Приложение может быть интернационализированно
Приложение может быть менять свой внешний
вид на разных платформах
44. var messages = require("json!po!./locale/en_US/LC_MESSAGES/messages.po");
Загрузка интернациональных пакетов
Другие полезные загрузчики
- autoprefixer
- mocha
- handlebars
- 6to5
- file
- json
Другие возможности
45. Технические требования приложения
Расширяется как в ширину так и в высоту
Приложение состоит из модулей
Приложение может быть интернационализировано
Приложение может быть менять свой внешний
вид на разных платформах