webpack
7 бед - один ответ
Денис Измайлов
Ведущий разработчик
Компания Netris 27 ноября 2014
• CommonJS?
• AMD?
• Require.js?
• Browserify?
Начнём издалека
Начало
• Глобальные проблемы веб-разработки
• Локальные проблемы проектов
• Способы решения
4
Глобальные проблемы веб-разработки
• Многообразие решений
• Версии
• Форматы
5
Глобальные проблемы веб-разработки
1. Многообразие решений (одних и тех же задач)
• jQuery/Angular/React
• Underscore/lodash/Lazy
• MVC/MVVM/Flux
6
Глобальные проблемы веб-разработки
2. Версии
• 1.8
• 2.1
• 3.2
• 4.5
• …10, 24, 38…
7
Глобальные проблемы веб-разработки
3. Форматы (пре-процессинг)
• LESS, SCSS, Stylus, …
• Handlebars, jade, EJS, …
8
Локальные проблемы проектов
• Сложность роста
• Функциональная
• Технологическая
• Зависимости
• Версии
9
Локальные проблемы проектов
• Функциональный рост
• Регистрация
• Личный кабинет
• Загрузка фотографий
• Аналитика
• Поддержка языков
10
Локальные проблемы проектов
• Технологический рост
• Bootstrap
• jQuery
• Knockout
• Handlebars
• React
11
Локальные проблемы проектов
• Зависимости
• Загружены ли стили?
• А шаблоны?
• А библиотека?
• А нужный jQuery-плагин?
• А локализация для него?
• А стили?…
12
Локальные проблемы проектов
• Версии
• Один плагин требует jQuery 1.8
• Второй плагин требует jQuery 2.1
• Что делать?
13
Способ решения
Изолированные модули
14
Реализации
• AMD
• CommonJS
15
AMD
• Asynchronous Module Definition
• Пример 1:
define(["jquery"], function ($) {
return {
// …
};
});
16
AMD
• Asynchronous Module Definition
• Пример 2 (CommonJS wrapping):
define(function (require, module, exports) {
var $ = require("jquery");
module.exports = {
// …
};
});
17
CommonJS
• www.commonjs.org
• Нативно в Node.js/Rhino
• Пример:
var $ = require("jquery");
module.exports = {
// …
};
18
CommonJS
Преимущества перед AMD:
• читабельность
• “писабельность”
• изоморфизм:


var _ = require("lodash");
var data = require("./stock.json");
module.exports = _.where(data, function (item) {
return item[‘count’] > 0;
});
19
AMD & CommonJS
• создавать изолированные модули
• использовать их
• не думать о порядке загрузки
• подключать любую статику
• собирать всё в один JS-файл
• использовать разные версии библиотек
20
Итого
• Глобальные проблемы веб-разработки
• многообразие решения, версии, форматы
• Локальные проблемы проектов
• функциональный и технологический
• управление зависимостями и версиями
• Способы решения
• AMD
• CommonJS - лучшее
21
Так что же теперь?
Что воплотит наши
фантазии в жизнь?
Что лучшее мы имеем
на сегодняшний день?
Любая логика
Любые форматы
Ваш проект быстро
собирается
Ваш проект быстро
запускается
Cамые современные
инструменты разработки
webpack
• Плагины
• Загрузчики
• Асинхронная сборка
• Чанки (chunks)
• Инструменты разработки
31
API для плагинов
• Логика сборки и поиска модулей
• Самое сердце процесса
• Рассмотрим примеры:
• DefinePlugin
• BowerWebpackPlugin
• ExtractTextPlugin
32
DefinePlugin
• Определение констант
• Настройка:
…
plugins: [
DefinePlugin({
"NODE_ENV": "production"
})
…
33
DefinePlugin
• Определение констант
• Использование:
if (NODE_ENV === "development") {
console.log("Debug info");
}
if (NODE_ENV === "production") {
console.log("App started");
}
34
DefinePlugin
• Определение констант
• Собранный код:
if ("production" === "development") {
console.log("Debug info");
}
if ("production" === "production") {
console.log("App started");
}
• После минификации:
console.log("App started");
35
BowerWebpackPlugin
• Прозрачное использование bower-компонент
• Настройка:
…
plugins: [
new BowerWebpackPlugin({
modulesDirectories: ["bower_components"],
manifestFiles: ["bower.json"],
includes: /.*/,
excludes: /.*.less$/
})
…
36
BowerWebpackPlugin
• Прозрачное использование bower-компонент
• Использование:
$ bower install jquery —save
в коде:
var $ = require("jquery");
$("body").html("Hello MoscowJS!");
• Уже более 20000 пакетов
37
ExtractTextPlugin
• Позволяет извлекать данные и собирать их в один файл
• Настройка:
…
module: {
loaders: {
test: /.css$/,
loader: ExtractTextPlugin.extract("style-loader",
"css-loader")
}
},
plugins: [
new ExtractTextPlugin("style.css")
]
…
38
Загрузчики
• Прозрачное подключение статики:
• JSON
• CoffeeScript,
• Handlebars/jade/EJS, …
• CSS/LESS/SASS/Stylus и т.д.
39
Загрузчики
Настройка:
…
module: {
loaders: [
{ test: /.css$/, loader: "style-loader!css-loader"},
{ test: /.json$/, loader: "json-loader"},
{ test: /.hbs$/, loader: "handlebars-loader"},
{ test: /.coffee$/, loader: "coffee-loader"},
{
test: /.(eot|woff|ttf|svg|png|jpg)$/,
loader: "url-loader?limit=30000" +
"&name=[name]-[hash].[ext]"
},
]
}
…
40
Загрузчики
Использование:
var $ = require("jquery");
var pageTemplate = require("./page.hbs");
var offices = require("./offices.json");
require("bootstrap/bootstrap.min.css");
require("./page.css");
$("#content").html(pageTemplate(offices));
41
Пример подключения JSX
Установка:
$ npm install jsx-loader —save-dev
42
Пример подключения JSX
Настройка:
resolve: {
extensions: ["", ".js", ".jsx"],
},
module: {
loaders: [
{ test: /.jsx$/, loader: "jsx-loader"}
]
}
…
43
Пример подключения JSX
Использование:
var React = require("react");
// loads toolbar.jsx
var Toolbar = require("./toolbar");
React.render(
React.createElement(Toolbar, null),
document.getElementById("toolbar")
);
44
webpack-dev-server
• Инструмент для ускорения разработки
• Автоматическое обновления страницы без
пересборки проекта
• Можно запускать, как модуль или CLI
45
webpack-dev-server
• Как это работает:
• Веб-сервер на основе assets-директории
• При подключении файла-сборки,
устанавливает соединение через socket.io
• Как только что-то изменилось -
автоматически обновляется страница
46
Hot Module Replacement
• Обновления изменённых частей в реальном
времени
• Без перезагрузки страниц
• Это опция webpack-dev-server
47
Hot Module Replacement
Как это работает с React:
• В окне IDE изменяете код компонента
• В это время через открытое socket-соединение
передаётся информация об изменённой части
• Происходит “горячая” замена компонента
(unmount + mount)
• На странице обновляется только компонент
48
Итого
• AMD и CommonJS
• Более 30 готовых плагинов
• Более 50 готовых загрузчиков
• Асинхронной сборка
• Чанки (chunks)
• Развитые инструменты разработки
49
Были ли альтернативы?
• 2009 - Require.js
• 2010 - Browserify
• 2012 - webpack
50
Как насчёт поддержки?
• Высокая активность разработчиков
• Коммиты в github:
51
Так можно доверять?
• Команда Facebook использует webpack для веб-
интерфейса Instagram
• Twitter использует webpack для своих проектов
(Fronteers 2014, Nicholas Gallagher)
52
Заключение
• Глобальные проблемы веб-разработки
• Многообразие, версия, форматов
• Локальные проблемы проектов
• Функциональный и технологический рост
• Управление зависимостями и версиями
• Решение
• CommonJS и webpack
53
Документация и примеры:
http://webpack.github.io
Вопросы?
webpack: 7 бед - один ответ
Денис Измайлов
http://www.facebook.com/denis.izmaylov
http://www.github.com/DenisIzmaylov

webpack: 7 бед - один ответ