Medium 2017 02 08 webpack v2 quick start 7be56d30

Несколько способов ускорить сборку webpack’ом

Если Вы работаете над крупным проектом, в котором много файлов относящихся к фронтенду (причем это могут быть еще и различные пакеты из node_modules), то в какой-то момент скорость сборки фронтенда начинает снижаться.

Итак, в этой статье я рассмотрю несколько простых способов, которые помогут ускорить сборку фронтенда webpack’ом как минимум в два раза. Начну с простых способов, и закончу более сложными.

Итак, поехали.

Включите кэширование для babel-loader

{
  test:   /\.(js|jsx)$/,
  exclude: /node_modules/,
  loader: 'babel',
  query: {
    cacheDirectory: true, // включить кэширование
    presets: ['es2015', 'react'],
    plugins: ['transform-runtime']
  }
}

Если включить опцию cacheDirectory, то для кэширования результатов babel-loader’а будет использоваться отдельный каталог. При последующих сборках лоадер будет пытаться считать кэш предыдущих сборок, чтобы избежать потенциально «дорогой» операции повторной компиляции. Кэш будет взят из node_modules/.cache/babel-loader или, в случае если лоадер не найдет такую директорию, он обратится к стандартной директории для хранения временных файлов в ОС. Способ довольно простой, но и выигрыш он дает крайне скромный, всего 3-5 секунд.

Используйте плагин webpack-uglify-parallel

Сборку можно ускорить примерно на 5-10 секунд, если минифицировать js-файлы в нескольких потоках. Добиться этого поможет плагин webpack-uglify-parallel.

Используйте DLL-сборки

По аналогии с динамически подключаемыми библиотеками (DLL) из мира настольных приложений, у webpack есть отличные встроенные инструменты для создания динамически подключаемых библиотек. Называются эти инструменты DllPlugin и DllReferencePlugin.

Принцип использования этих плагинов примерно такой:

  • Создается дополнительный webpack-конфиг для сборки библиотек (вендоров)
  • В основном webpack-конфиге дается ссылка на манифест, созданный первым конфигом.
  • Запускается дополнительный конфиг, собирающий все указанные библиотеки в отдельный файл.
  • Основной webpack-конфиг исключает из сборки библиотеки, собранные на этапе 3.
  • Profit!!!

Итак, перейдем к конкретному примеру конфига с DLL-сборкой.

Первым делом, создадим дополнительный конфиг, который будет отвечать за сборку наших библиотек (вендоров):

// vendor.webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: {
    vendor: [
      'jquery',
      'lodash',
      'jquery.nicescroll',
      'react-redux',
      'redux',
      'react',
      'react-dom'
    ]
  },
  output: {
    path: path.join(__dirname, '/../public/vendor'),
      filename: '[name].bundle.js',
      library: 'vendor_lib',
  },
  module: {
    noParse: /node_modules/
  },
  plugins: [
    new webpack.DllPlugin({
      name: 'vendor_lib',
      path: path.join(__dirname, '/../public/vendor/vendor-manifest.json'),
    })
  ]
};

Как можно заметить, в единственной точке входа (entry point) vendor, я перечислил все библиотеки, которые хочу исключить из основного файла сборки. Разумеется, таких точек входа может быть несколько. Например, если какие-то библиотеки используются только в админке, имеет смысл вынести их в отдельную точку входа. Здесь все зависит от проекта.

Итак, теперь, после создания дополнительного конфига, необходимо «привязать» его к основному конфигу. С этим делом поможет DllReferencePlugin. Добавим его к списку плагинов основного конфига webpack:

plugins: [
  ..., // другие плагины
  new webpack.DllReferencePlugin({
    context: '.',
    manifest: require('./../public/vendor/vendor-manifest.json')
  })
]

Теперь, когда произведена настройка конфигов, можно собрать вендоров (запустив vendor.webpack.config.js), после чего запустить основной конфиг webpack’а (webpack.config.js) и увидеть ускорение скорости сборки почти в 2 раза!

Переменные окружения

Не забывайте выставлять переменные окружения, что тоже дает некоторый выигрыш в скорости.

plugins: [
   ..., // другие плагины
   new webpack.DefinePlugin({
      'process.env': {
         NODE_ENV: '"production"'
      }
   })
]

Используйте HappyPack

HappyPack позволит значительно ускорить сборку за счет параллелизации. Т.е. сборка ваших бандлов будет проходить в несколько потоков, количество который можно конфигурировать.

Заключение

Надеюсь, вышеперечисленные способы помогут вам ускорить процесс сборки webpack. Особенно хочу отметить способы 1-4, как наиболее надежные. Вполне возможно, со временем появятся какие-то еще способы ускорения сборки, но даже первых четырех способов хватит для ускорения сборки примерно в два раза.