46
Разработка больших приложений Vue Webpack Кирилл Кайсаров github.com/markuplab http://vuejs.org http://webpack.github.io

#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

  • Upload
    jsib

  • View
    405

  • Download
    1

Embed Size (px)

Citation preview

Page 1: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Разработка больших приложений

Vue Webpack

Кирилл Кайсаровgithub.com/markuplab

http://vuejs.org http://webpack.github.io

Page 2: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Какими были Javascript приложения в период с 2006 по 2015 год

Минутка ностальгии

Page 3: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Write Less / Do MoreЭра jQuery

$(element) - Основная структурная единица1 Все манипуляции ориентированы на DOM ноды

Plugin основная единица экосистемы2 Большинство популярных решений имели избыточный объем кода

Server Side Rendering3 Получение отрендеренного html'a один из классических подходов эры

Page 4: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Model View Controller ЭРА MVVC / MVC / VM / MC / MV / VC / ETC...

Plain JS Object - Основная архитектурная единица1 new Constructor(), Object.prototype, Object.extend({}), итд...

Client-Side Rendering2 Избавление сервера от дополнительной работы с шаблонами + гибкость

Триумф AMD3 Загрузка модулей через AJAX, явные зависимости, и сборка на Java

Утром Data - Вечером HTML4 Тренд на Dom-First Apps резко изменился на Data-First Apps

Page 5: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Наше время Компонентная эра

Компоненты как архитектурная единица1 Теперь модуль это не только Javascript. Все asset'ы внутри.

Триумф CommonJS2 NPM, Модули для сервера и браузера, browserify, изоморфность.

Реактивное и асинхронное программирование3 Promise, Generators, NextTick, Pipes

Большая нагрузка на клиента - почва для оптимизаций4 Ленивая загрузка, разделение приложения на части, benchmarking

Page 6: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Vue.JSОсновные принципы

Page 7: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Построен на принципах реактивного программирования

Основные принципы

1 Vue.nextTick(), Queue, Reactive Directives

Поддерживает концепцию Web Components2 V-component, Vueify, Component Registry, Custom Directives

Сущность это простой (plain) Javascript объект3 Template as HTML String, Component as Javascript Object

Page 8: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Единая сущность Vue

Основные принципы

4 Объект содержит в себе $data, $methods, $events итд...

Дружелюбен к модульным системам5 Простая интеграция с Common.JS и другими модульными системами

Page 9: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

WebpackОсновные принципы

Page 10: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Основные принципы

1 Module is EverythingHTML строка, CSS таблица, Javascript функция, нет разницы.

2 Только Javascript? Нет.Webpack умеет собирать не только Javascript, также графику, шрифты итд...

3 Ленивая / Частичная загрузка из пакетаВажный инструмент для больших приложений без излишних расширений

Page 11: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Основные принципы

4 Ориентирован на Client-Side приложенияHot Module Replacement, JSONP, и другие браузерные решения

5 AMD / CommonJS / NativeНет разницы какую систему модулей вы используете

Page 12: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

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

Client-Side приложениями?

Page 13: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Технические требования приложения

Расширяется как в ширину так и в высоту

Приложение состоит из модулей

Приложение может быть интернационализировано

Приложение может быть менять свой внешнийвид на разных платформах

Page 14: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Время для котикадинга

Page 15: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

/** Module dependencies */var Vue = require('vue');

/** Define application */var app = module.exports = new Vue({ el: '#v-app'});

Точка входа в приложение

doctype htmlhtml head title Simple application body#v-app

script(src='/public/build.js')

Построим HTML Layout

Page 16: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

$ sudo npm i webpack -g

Устанавливаем Webpack

module.exports = { entry: { app: "./components/app.js" },

output: { path: "./public/build", filename: "app.js" }}

Описываем webpack.config.js

Page 17: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

$ webpack -p

Hash: f2f8823c3ad505796c0dVersion: webpack 1.4.15Time: 3230ms Asset Size Chunks Chunk Namesapp.js 59934 0 [emitted] app + 63 hidden modules

Собираем наше приложение

Page 18: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Создаем первый компонент

doctype htmlhtml body#v-app #v-panel(v-component="panel")

Объявляем в Layout

Регистрируем компонент в нашем приложении/** Define application */var app = module.exports = new Vue({ el: '#v-app',

components: { panel : require('./panel') }});

Page 19: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Описываем компонент/** Define component */module.exports = { template: '<div class="v-panel">Я панель по имени {{ firstName }} ' + 'и фамилии <span v-html="lastName"></span></div>',

data: function(){ return { firstName: 'Петя' } },

created: function() { this.$set('lastName', 'Петров'); }};

Создаем первый компонент

Page 20: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Создаем первый компонентРезультат

Page 21: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Капля оптимизации

/** Define component */module.exports = { template: require('./template.html'),

data: function(){ return { firstName: 'Петя' } },

created: function() { this.$set('lastName', 'Петров'); }};

Создаем первый компонент

Page 22: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

/** Define component */module.exports = { // Как загрузить HTML в require?! template: require('./template.html')};

Опишем webpack.config.jsmodule.exports = { module: { loaders: [ { test: /\.html$/, loader: "html" } ] }};

Создаем первый компонентКапля оптимизации

Page 23: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Webpack LoadersЗагрузчики это функции которые выполняюттрансформацию файлов в модули приложения.

Аналогичны browserify transform.http://webpack.github.io/docs/using-loaders.html

Page 24: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

/** Define component assets */require('./styles.less')

/** Define component */module.exports = { template: require('./template.html')};

Дополним наш webpack.config.js загрузчиком стилейmodule: { loaders: [ { test: /\.html$/, loader: "html" }, { test: /\.less$/, loader: "style!css!less" } ]}

Создаем первый компонент

Page 25: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Результат template.htmlmodule.exports = "<div class=\"v-panel\">\n Я панель по имени {{ firstName }} и фамилии\n <span v-html=\"lastName\"></span>\n</div>\n";

/***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(32)(); exports.push([module.id, "span {\n color: #999;\n}\n", ""]);/***/ }

Результат styles.less

Создаем первый компонент

Page 26: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Создаем первый компонентРезультат

Page 27: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Технические требования приложения

Расширяется как в ширину так и в высоту

Приложение состоит из модулей

Приложение может быть интернационализировано

Приложение может быть менять свой внешнийвид на разных платформах

Page 28: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Добавим немного динамики

Page 29: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Controller - компонент отвечающий за состояние приложения

Содержит в себе все нужные для работы компоненты1Является точкой разрыва приложения. App -> Controller -> Components2Controller определяется в зависимости от состояния URL3

Page 30: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Схема сбора и запуска приложения

Client App URLState

Controller

Component Component Component

Controller Controller

Page 31: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Контроллер - место где наше приложение начинаетответвляться от приложения. Именно тут мы можемразделить наше приложение на части.

Для решения этой задачи подойдет 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});

Синтаксис:

Page 32: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Создадим явную карту наших контроллеров

/** Routes map */var map = { main: require('./controllers/main'), alt: require('./controllers/alt')};

Создаем контроллеры

Проблематика:Основной проблематикой клиентских загрузчиков модулей является"неумение" работать с динамическими аргументами require(). Втекущих реализациях мы вынуждены указывать имена модулейявно. Node.JS умеет подтягивать модули динамически.

Page 33: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Делаем нашу карту модулей ленивой

/** Routes map */var map = { main: require('promise?bluebird!./controllers/main'), alt: require('promise?bluebird!./controllers/alt')};

Создаем контроллеры

Альтернативный вариант вызова Webpack LoadersДля трансформации модулей можно использовать дополнительныестроковые параметры внутри require() отделив их через знак "!". Вуказаном выше случае мы загружаем модуль пропуская его черезpromise-loader.

Page 34: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Немного о Promise-Loader

Создаем контроллеры

Трансформация этим модулем позволяет сделать отложенныйrequire.ensure и обернуть его в Promise объект.

// Указываем библиотеку для обертки в Promisevar load = require("promise?bluebird!./file.js"); // Модуль не будет загружен пока вы не вызовете функциюload().then(function(module) { // Здесь вы можете работать с вашим модулем});

Page 35: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Контроллеры выделены в отдельные файлы

$ webpackHash: 5fa98cfa191aa5dafdb4Version: webpack 1.5.3Time: 827ms Asset Size Chunks Chunk Namesapp.js 349774 0 [emitted] app1.1.js 287 1 [emitted] 2.2.js 294 2 [emitted] + 78 hidden modules

Создаем контроллеры

Page 36: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Результат

Создаем контроллеры

Page 37: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Указываем элемент в котором расположим контроллер

doctype htmlhtml head title Simple application

body#v-app #v-panel(v-component="panel") #v-controller(v-el="controller")

script(src='/public/build.js')

Создаем контроллеры

Page 38: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Загружаем и запускаем контроллер

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)); }

...});

Создаем контроллеры

Page 39: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Связать управление контроллерами с HTML5 History API

Следующие шаги

1 Состояние приложения можно хранить в this.$data

Спроектировать ленивую загрузку внутри контроллера2 Актуально для больших контроллеров

3 Как инструмент дополнительной оптимизацииИспользовать ApplicationCache и Deduplication Plugin

Page 40: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Технические требования приложения

Расширяется как в ширину так и в высоту

Приложение состоит из модулей

Приложение может быть интернационализировано

Приложение может быть менять свой внешнийвид на разных платформах

Page 41: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

module.exports = { template: require('./templates/' + platform + '.html')};

Динамическая загрузка модулей

- templates - ios.html - android.html - windows.html

Отлично подходит для кросс-платформенных решений

Другие возможности

Page 42: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Динамическая загрузка модулей

Другие возможности

При такой загрузке в сборку попадут все модули изпапки ./templates с форматом .html, а также внутризагрузчика появиться карта соответствия именифайла, id'шнику модуля.

Page 43: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Технические требования приложения

Расширяется как в ширину так и в высоту

Приложение состоит из модулей

Приложение может быть интернационализированно

Приложение может быть менять свой внешнийвид на разных платформах

Page 44: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

var messages = require("json!po!./locale/en_US/LC_MESSAGES/messages.po");

Загрузка интернациональных пакетов

Другие полезные загрузчики

- autoprefixer- mocha- handlebars- 6to5- file- json

Другие возможности

Page 45: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Технические требования приложения

Расширяется как в ширину так и в высоту

Приложение состоит из модулей

Приложение может быть интернационализировано

Приложение может быть менять свой внешнийвид на разных платформах

Page 46: #3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кайсаров

Вопросы???