Шаг 2. Webpack-merge — как объединить несколько конфигов

Webpack-merge позволяет разделять и объединять конфиги.

Чтобы его добавить, нужнен проинициализированный проект (директория), в котором есть файл package.json. Если эти условия выполнены, вводим команду:

npm i webpack-merge -D

Именно с -D, так как это зависимость для разработки. Ждём, пока пакет скачается, и двигаемся дальше.

На данный момент вся логика приложения (конфиг) находится в файле webpack.config.js — его внутренняя структура аналогична той, которую вы можете наблюдать в исходных файлах проекта.

Для остальных файлов конфига создадим директорию build (название можете придумать сами), а в ней отдельный файл webpack.base.js. Затем полностью перенесём код из webpack.config.js в новый файл.

Теперь в файле webpack.config.js обратимся к установленному пакету и подключим нужную нам функцию. Делаем это уже по знакомой схеме, но с одной особенностью.

Если по уже привычному нам синтаксису webpack-merge будет подключён с использованием следующей записи...

  const merge = require('webpack-merge');

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

Ошибка. Переменная не является функцией и не может быть использована
Ошибка. Переменная не является функцией и не может быть использована

Исправить ошибку может barrel export \ import — метод «бочкования» экспортов и импортов. Благодаря ему при импорте (либо подключении) одного файла нам будут доступны множество функций, которые мы достаём с помощью деструктуризации.

Теперь переменная выглядит примерно так:

const {merge} = require('webpack-merge');

Мы просто достали функцию, объединяющую конфиги, из нужного нам каталога — куда не рекомендуется заходить и тем более что-то менять неопытным пользователям без осознанного понимания происходящего.

Следующий шаг — подключение базового конфига, ведь он также является своего рода пакетом (модулем):

const baseConfig = require('./build/webpack.base') // расширения можно не указывать, это будет видно в автодополнении вашего редактора кода

И теперь создадим каркас для вынесения логики в зависимости от режимов:

module.exports = (_, mode) => {
  switch (mode.mode) {
    case 'development':
      return merge(baseConfig);
    case 'production':
      return merge(baseConfig);
    default:
      throw new Error('No matching configuration was found!');
  }
};

В функцию module.exports можно передавать параметры. Первый — заглушка, а второй отвечает за режимы разработки, которые нам нужны для подключений разных файлов.

Примечание: сейчас конфиг не будет работать. Эту проблему мы решим по мере выполнения задания.