webpack7 бед - один ответ
Денис ИзмайловВедущий разработчик Компания 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