Как работает WebPack

239
03 января 2018, 20:53

У меня есть проект и в нём куча подключённых библиотек, например lodash. Из этой библиотеки я использую пока только одну функцию _.isEqual, я хочу понять после обработки webpack-ом моего проекта, в результирующий JavaScript попадут все функции lodash или только isEqual?

Аналогично и с css неиспользованые селекторы попадают в результат?

Конечно я могу создать простой проект и проверить, так сказать на практике, но хочется узнать как вообще это должно работать.

Answer 1

Приветствую!

Тут дело не столько в вебпаке/роллап, так как вебпак со второй версии поддерживает es6 тришейкинг. А дело в том, как модули импортировать. У вас разве не на тайпсприпте проект, или это другой? Потому что тайпскрипт чуть меняет ситуацию (т.к. бабель плагины не используются).

Подробности:

Дело в том, что если в бандлер (после всех прелоадеров) попадёт es5-код вида

var lodash_1 = require('lodash');
var map = lodash_1.map;

Тогда +700 килобайт к размеру бандла обеспечено. Так как бандлер не будет знать, как этот объект lodash_1 уменьшить.

Если же в бандлер попадает es6 импорт типа

import { map } from 'lodash';

Тогда умный бандлер дёрнет из библиотеки только то, что мы используем.

Далее встаёт вопрос - как же не допустить попадания подобного кода в бандлер? Вариантов несколько

1) В чистом js можно, в общем-то, использоваться бабель-плагин-лодаш, он кстати не только с лодашем работает, а также, к примеру, с semantic-ui-react.

2) Можно испортировать функции по одной const map = require('lodash/map');

3) Можно устанавливать только те функции лодаш из npm, которые нужны (но это если нужно всего несколько)

npm install lodash.map
npm install lodash.sortBy

В тайпкрипте, ситуация чуть другая и зависит от параметра target в tsconfig.

1) Если параметр равен es5, тогда тришейкинг работать не будет, так как мы передаём ес5 код в бандлер. В этом случае можно и нужно импортировать функции по одной:

import map = require('lodash/map');

Как вариант, можно создать файл, который будет импортировать нужные функции по одной, и реэкспортировать все вместе, вот так:

// utils/lodash.ts
import clamp = require('lodash/clamp');
import curry = require('lodash/curry');
import debounce = require('lodash/debounce');
import filter = require('lodash/filter');
export { clamp, curry, debounce, filter };

2) Если target = es6 и выше, тогда в бандлер приходит es6 код и всё должно быть хорошо.

1) В вебпаке есть очень хорошие плагины - инструменты профилирования сборки. Один из низ - WebpackMonitor, что это такое можно погуглить, ОБЯЗАТЕЛЕН при продакшн-сборке:

new WebpackMonitor({
  capture: true, // -> default 'true'
  launch: false, // -> default 'false'
  port: 3030, // default -> 8081
  target: 'stats.prod.json'
}),

Он показывает из чего состоит бандл, сколько это весит, а также хранит историю изменений.

2) Обязательно стоит завести 2 конфига для вебпака. Точнее 3:

webpack.common.js
webpack.dev.js
webpack.production.js

В common настраиваем общие параметры. В дев и прод. импортирует общий конфиг и дополняем требуемыми настройками/плагинами/лоадерами. К примеру, WebpackMonitor идёт в продакшн. ExtractText тоже в продакшн. И т.д.

READ ALSO
Положение пользователя в дереве Treant.Js

Положение пользователя в дереве Treant.Js

Здравствуйте, кто нибудь работал с плагином TreantJS? Как в настройках плагина указать местоположения пользователя в дереве?

223
Цвет фона при скроле

Цвет фона при скроле

Доброго времени суток! Есть один вопрос к знатакамСделал я фиксированое меню с якорями, но есть проблема: Когда я скролю вниз, у меня к прозрачному...

225
Функция dump / dd в laravel

Функция dump / dd в laravel

Всем привет, кто - то вкурсе как изменить css функции dump в laravel ?

212