#3 "webpack и vue.js: Создание больших приложений и их...

Post on 08-Aug-2015

405 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Vue Webpack

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

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

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

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

Write Less / Do MoreЭра jQuery

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/** 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

$ sudo npm i webpack -g

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

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

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

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

$ webpack -p

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

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

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

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

Описываем компонент/** 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', 'Петров'); }};

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

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

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

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

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

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

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

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

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

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

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

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

/** 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" } ]}

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

Результат 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

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

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

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

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

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

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

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

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

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

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

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

Client App URLState

Controller

Component Component Component

Controller Controller

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

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

Синтаксис:

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

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

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

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

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

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

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

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

Немного о Promise-Loader

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

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

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

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

$ 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

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

Результат

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

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

doctype htmlhtml head title Simple application

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

script(src='/public/build.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)); }

...});

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вопросы???

top related