SlideShare a Scribd company logo
1 of 83
Download to read offline
Внутреннее устройство
и оптимизация бандла
webpack
Алексей Иванов, Злые марсиане
Злые марсиане
Злые марсиане
Над чем я работаю
—  React в бандле весит больше чем lib/react.js .
—  Несколько версий lodash или  underscore .
—   Moment.js грузит 100+ локалей.
—  Непонятные полифилы.
—  Не работает tree shaking.
—  Изменяется кеш для неизменившихся чанков.
—  И так далее.
Проблемы
Для кого
этот доклад
—  CommonJS.
—  Резолв путей до файлов.
—  Устройство бандла изнутри.
—  Глобальные константы и DefinePlugin.
—  UglifyJS и dead code elimination.
—  ES6 modules и tree shaking.
—  Выделение чанков и асинхронная подгрузка.
—  Анализ результатов сборки.
План
CommonJS
// module.js
const one = 1;
exports.two = 2;
module.exports = { one };
// othermodule.js
const m = require('module');
console.log(m.one);
console.log(m.two); // ошибка
CommonJS
—  JS-файл с переменными require , exports , module .
—   this равно exports .
—   exports по умолчанию равно {} .
—  Чтобы мы могли использовать npm-модули в браузере, нам нужно
эмулировать в браузере это поведение.
CommonJS
Резолв путей
—   / , ./ , ../ – как в файловой системе.
—  Библиотеки:
—  папка с именем модуля в  node_modules ,
—  если нет в  node_modules , ищем рекурсивно выше по дереву,
—  Добавляем в конец пути .js или  /index.js .
Схема резолва путей в node.js
Схема резолва путей в webpack 2
Резолв путей в require()
./
node_modules/
lodash-5.0.0/
some-lib-1.0.0/
node_modules/
lodash-1.0.0/
index.js
Несколько версий библиотек
ПРОБЛЕМА 1
Базовое
устройство
бандла
function( module, exports, require ) {
const module = require('../path');
// ...
module.exports = ...;
}
CommonJS модуль в браузере
function(module, exports, __webpack_require__ ) {
const module = __webpack_require__(0) ;
// ...
module.exports = ...;
}
CommonJS модуль в браузере
(function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
/* код инициализации */
}
// ...
return __webpack_require__(1); // корневой файл
})([ /* массив модулей */ ]);
Как выглядит простой бандл
(function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
/* код инициализации */
}
// ...
return __webpack_require__(1) ; // корневой файл
})([ /* массив модулей */ ]);
Как выглядит простой бандл
1.  Ищет инициированный модуль в кэше.
2.  Создает заглушку и добавляет её в массив.
Что делает __webpack_require__
{
i: moduleId,
l: false,
exports: {}
}
Что делает __webpack_require__
1.  Ищет инициированный модуль в кэше.
2.  Создает заглушку и добавляет её в массив.
3.  Выполняет код модуля с  this равным module.exports .
Что делает __webpack_require__
modules[moduleId].call(
module.exports , // exports будет this для модуля
module,
module.exports , // по-умолчанию равно {}
__webpack_require__
);
Что делает __webpack_require__
{
i: moduleId,
l: false,
exports: // тут теперь какой-то код
}
Что делает __webpack_require__
1.  Ищет инициированный модуль в кэше.
2.  Создает заглушку и добавляет её в массив.
3.  Выполняет код модуля с  this равным module.exports .
4.  Возвращает module.exports .
Что делает __webpack_require__
const p = '4';
const m = require("./module" + p );
Require в бандле:
const m = __webpack_require__(3)("./module" + p );
Как работает подключение
модуля по маске
var map = {
" ./module ": 1, " ./module.js ": 1,
" ./module2 ": 0, " ./module2.js ": 0,
}
function webpackContext(...) {/* код выбора модуля */};
module.exports = webpackContext;
Справка по Dependency management
Модуль резолва пути в бандле
require('./locale/' + name); // 118 локалей
Решение:
new webpack.ContextReplacementPlugin(
/moment[/]locale$/,
/ en|ru /
)
moment/moment.js
ПРОБЛЕМА 2
Глобальные
константы
и DefinePlugin
const version = VERSION ;
if ( process.env.NODE_ENV !== "production") {
const module = require('module');
// что-то делаем
}
Константы в коде
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
RUBY_ENV: '"production"',
BOOL: "true",
},
VERSION: JSON.stringify(process.env.VERSION),
});
DefinePlugin
const version = "1.0.1" ;
if ( false ) {
const module = require('module'); // не импортирован
// что-то делаем
}
Преобразованный код
// До преобразования
const { NODE_ENV } = process.env ;
// После преобразования
var _process$env = process.env,
NODE_ENV = _process$env.NODE_ENV;
Ссылка на песочницу с Babel
Неточная строка для замены
ПРОБЛЕМА 3
var _process$env = process.env,
NODE_ENV = "production";
if (NODE_ENV !== "production") {
const m = __webpack_require__(0) ;
}
Неточная строка для замены
ПРОБЛЕМА 3
Что будет, если
не заменить
process.env?
process – стандартная переменная в node.js, webpack её заполифилит
для совместимости.
Многие другие переменные из  node.js тоже будут заменены.
Полифилы node.js
ПРОБЛЕМА 4
—  React
—  Redux
—  ...
Функции отладки в библиотеках
ПРОБЛЕМА 5
Сжатие кода
—  Удаляет пробелы.
—  Переименовывает переменные короткими именами.
—  Делает dead code elimination.
Ссылка на песочницу с UglifyJS2
UglifyPlugin
function text() {
var one = 1;
var two = 2;
var three = 3;
return one + two;
}
Было
СОКРАЩЕНИЕ ИМЁН И УДАЛЕНИЕ ПЕРЕМЕННЫХ
function text(){var t=1,e=2
return t+e}
Стало
СОКРАЩЕНИЕ ИМЁН И УДАЛЕНИЕ ПЕРЕМЕННЫХ
var one = 1;
var two = 2;
var three = 3;
console.log(one + two);
Было
А ВОТ ТАК НЕ СРАБОТАЕТ
var one=1,two=2,three=3
console.log(one+two)
Стало
А ВОТ ТАК НЕ СРАБОТАЕТ
if ( true ) {
console.log(1);
}
if ( false ) {
console.log(2);
}
Было
УДАЛЕНИЕ УСЛОВИЙ
console.log(1);
Стало
УДАЛЕНИЕ УСЛОВИЙ
var f = false;
if (f) {
console.log(1);
}
Было
ТАК ТОЖЕ НЕ СРАБОТАЕТ
var f=!1
f&&console.log(1)
Стало
ТАК ТОЖЕ НЕ СРАБОТАЕТ
var _process$env = process.env,
NODE_ENV = "production";
if ( NODE_ENV !== "production" ) {
const m = __webpack_require__(0);
}
Переменные в условиях
ПРОБЛЕМА 6
ES6 modules
// CommonJS
const m = require('./m');
exports.one = 1;
module.exports = 2;
// ES Modules
import m from './m';
export const one = 1;
export default 2;
Импорты и экспорты обязательно иммутабельны.
Документация по import, export
Отличия от CommonJS
В теории webpack может точно определить, что используется у нас
в приложении, и помечать их соответственно.
На практике все несколько сложнее.
Tree shaking
export const method (() => {
window.foo == '111';
})();
Сайд эффекты
TREE SHAKING
// module.js
export const one = 1;
export const two = 2;
// index.js
import { one, two } from './module';
console.log(one);
Пример импорта и экспорта
var __WEBPACK_IMPORTED_MODULE_0__module__
= __webpack_require__(0);
console.log( __WEBPACK_IMPORTED_MODULE_0__module__ ["a"]);
index.js в бандле
const one = 1;
__webpack_exports__["a"] = one;
const two = 2;
// нет __webpack_exports__ за ненадобностью
module.js в бандле
import module3 from './folder/module-3';
// импорт из method попадет в сборку
export const method = () => module3 ;
// export.default пометится как используемый
export default 1223;
Работает только с экспортами
ПРОБЛЕМА 7
Такой код импортирует всю библиотеку:
import { method } from 'lodash-es';
Решение:
—   import { method } from 'lodash-es/method'
—  babel-plugin-lodash
Работает только с экспортами
ПРОБЛЕМА 7
Выключите в Babel обработку modules , чтобы он не менял их
на  require и  exports :
{"presets": [
["latest", {
"es2015": { "modules": false }
}]
]}
Важно!
Чанки
—  Синхронные и асинхронные.
—  В первый файл добавляется функция window["webpackJsonp"] .
—  В следующих файлах вызывается функция webpackJsonp со списком
модулей и id модулей, которые надо запустить.
Чанки
webpackJsonp(
[0], // id чанка
[{ 22: function(...){...} }], // массив модулей
[12] // id модулей для запуска
]);
Чанки
—  Синхронные и асинхронные.
—  В первый файл добавляется функция window["webpackJsonp"] .
—  В следующих файлах вызывается функция webpackJsonp со списком
модулей и id модулей, которые надо запустить.
—  Все модули попадают в общий массив и используются оттуда.
Чанки
import('./module4').then((module4) => {
console.log(module4);
});
Асинхронная подгрузка чанков
__webpack_require__.e (0)
.then(__webpack_require__.bind(null, 1))
.then((module4) => {
console.log(module4);
});
Асинхронная подгрузка чанков
Создание имени чанка при наличии [chunkhash] :
script.src = chunkId + "." + {
"0":" 588290cc688bace070b6 ",
"1":" 5966f9b147ab01778e34 ",
}[chunkId] + ".js";
Имена файлов чанков
CommonsChunk
Plugin
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: '[name].[chunkhash].js',
minChunks: 2
})
Выносим общие модули
в отдельный файл
import() -чанки игнорируются CommonsChunkPlugin .
Чтобы не игнорировались, добавьте:
new webpack.optimize.CommonsChunkPlugin({
...,
children: true
})
Вложенные чанки
ПРОБЛЕМА 8
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: function (module) {
return module.context &&
module.context.indexOf(" node_modules ") !== -1;
}
})
Вынос node_modules
Пример c node_modules не работает для кэша:
1.  При добавлении файлов меняются индексы;
2.  Код загрузки и инициализации живет в первом файле:
—  меняется стартовый индекс,
—  меняются ссылки на чанки.
Изменяющиеся индексы
ПРОБЛЕМА 9
(function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
/* код инициализации */
}
// ...
return __webpack_require__(1) ; // корневой файл
})([ /* массив модулей */ ]);
Изменяющиеся индексы
ПРОБЛЕМА 9
Создание имени чанка при наличии [chunkhash] :
script.src = chunkId + "." + {
"0":" 588290cc688bace070b6 ",
"1":" 5966f9b147ab01778e34 ",
}[chunkId] + ".js";
Изменяющиеся индексы
ПРОБЛЕМА 9
—   NamedModulesPlugin() – меняет индексы на пути до файла.
—   HashedModuleIdsPlugin()  — меняет индексы на хэш содержимого.
Фиксируем имена модулей
new webpack.optimize.CommonsChunkPlugin({
name: "manifest",
minChunks: Infinity
}),
Выносим инициализацию
в отдельный файл
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor', ...
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest', ...
})
Несколько CommonsChunkPlugin
Анализ бандла
Строит treemap бандлов. Удобно проверять, не попали ли в бандл:
—  Две версии одной библиотеки.
—  Копии библиотеки в разных чанках.
—  Бибиотеки, которые должны были вырезаться по условию.
—  Непредвиденные зависимости у библиотек.
—  Просто большие файлы.
webpack-bundle-analyzer
Показывает отношения между файлами в графе — кто на кого
ссылается, кто кого добавил в сборку. Удобно использовать, чтобы
понять:
—  Кто именно использует файл.
—  Кто именно подключил библиотеку.
webpack-runtime-analyzer
—  Сделайте пустой бандл и посмотрите содержимое, там 40 строчек.
—  Не бойтесь ходить в исходники и смотреть что получилось в коде.
—  После добавления библиотек всегда запускайте анализатор банда
и смотрите что он с собой притащил.
—  После добавления чанков проверяйте их содержимое.
Итого
Алексей Иванов, Злые марсиане
Twitter: @iadramelk
Внутреннее устройство
и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpack

More Related Content

What's hot

Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Ontico
 
Knockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-ОнлайнKnockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-Онлайн2ГИС Технологии
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноRoman Dvornov
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.Igor Shkulipa
 
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)Ontico
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»Roman Dvornov
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Roman Dvornov
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOMRoman Dvornov
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьCodeFest
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов2ГИС Технологии
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстромRoman Dvornov
 
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft UkraineHTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft UkraineVolha Banadyseva
 
DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"Roman Dvornov
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node jsAlex Tumanoff
 
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)Ontico
 
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИСTARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС2ГИС Технологии
 
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)Как мы ускоряли WebGL / Мстислав Живодков (2GIS)
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)Ontico
 
Making Scalable JavaScript Application
Making Scalable JavaScript ApplicationMaking Scalable JavaScript Application
Making Scalable JavaScript ApplicationMikhail Davydov
 

What's hot (20)

Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
 
Knockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-ОнлайнKnockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-Онлайн
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективно
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOM
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесь
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстром
 
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft UkraineHTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
 
DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node js
 
Суперсилы Chrome developer tools
Суперсилы Chrome developer toolsСуперсилы Chrome developer tools
Суперсилы Chrome developer tools
 
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)
Стабильность WebGL приложений / Кирилл Дмитренко (Яндекс)
 
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИСTARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
 
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)Как мы ускоряли WebGL / Мстислав Живодков (2GIS)
Как мы ускоряли WebGL / Мстислав Живодков (2GIS)
 
Making Scalable JavaScript Application
Making Scalable JavaScript ApplicationMaking Scalable JavaScript Application
Making Scalable JavaScript Application
 

Similar to Внутреннее устройство и оптимизация бандла webpack

Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
JavaScript-модули "из прошлого в будущее"
JavaScript-модули "из прошлого в будущее"JavaScript-модули "из прошлого в будущее"
JavaScript-модули "из прошлого в будущее"oelifantiev
 
Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPAEugene Abrosimov
 
Обзор ES2015(ES6)
Обзор ES2015(ES6)Обзор ES2015(ES6)
Обзор ES2015(ES6)Alex Filatov
 
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...Омские ИТ-субботники
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаAlexander Kucherenko
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CYandex
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage CollectorOlexandra Dmytrenko
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBDmitry Viskov
 

Similar to Внутреннее устройство и оптимизация бандла webpack (20)

Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
JavaScript-модули "из прошлого в будущее"
JavaScript-модули "из прошлого в будущее"JavaScript-модули "из прошлого в будущее"
JavaScript-модули "из прошлого в будущее"
 
Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPA
 
Обзор ES2015(ES6)
Обзор ES2015(ES6)Обзор ES2015(ES6)
Обзор ES2015(ES6)
 
JSSDK: Начало
JSSDK: НачалоJSSDK: Начало
JSSDK: Начало
 
Zend Framework и Doctrine
Zend Framework и DoctrineZend Framework и Doctrine
Zend Framework и Doctrine
 
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...
2015-11-07 01 Виталий Кравцов. Webpack: человеческий подход к разработке веб ...
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языка
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
 
RequireJS і Magento 2
RequireJS і Magento 2RequireJS і Magento 2
RequireJS і Magento 2
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
Java 9 - Back to the Future
Java 9 - Back to the FutureJava 9 - Back to the Future
Java 9 - Back to the Future
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDB
 

Внутреннее устройство и оптимизация бандла webpack