Веб-сайты и веб-приложения развивались, и по мере их появления мы видели множество инструментов для объединения наших файлов, выполнения задач и / или настройки наших сред разработки. Тем не менее, Webpack взял на себя инициативу и стал основным сборщиком пакетов и средством выполнения задач, используемым в наши дни для веб-приложений. Webpack прошел через 4 основные версии, и, на мой взгляд, последняя версия намного проще в использовании и понимании.

Часто связывание - это то, о чем узнают лишь частично или не знают вообще, вместо шаблонного кода, такого как create-react-app. Однако, если вы не узнаете о комплектации на ранней стадии или не используете шаблон, вы просто настроите себя на неприятности в будущем.

Итак, в этой статье я рассмотрю фундаментальные концепции, которые вы должны учитывать при встраивании Webpack в вашу интерфейсную архитектуру, предоставив вам шаблон конфигурации, который должен покрыть большинство потребностей для малых и средних приложений, объясняя каждый раздел config и что он делает, а также дает вам несколько идей, на которые следует обратить внимание при расширении этой конфигурации.

Основная идея Webpack состоит в том, чтобы взять ваши отдельные файлы, а затем создать пакеты из этих файлов, которые уменьшают количество HTTP-запросов, которые браузер пользователя должен выполнить для отображения веб-приложения. Попутно вы можете использовать возможность формировать выходные данные этих пакетов, уменьшая их содержимое, разделяя файлы по своему усмотрению, сжимая изображения и многое другое.

Установка

npm init -y
npm I -D webpack webpack-cli webpack-dev-server

Создайте свой файл конфигурации

Webpack использует файлы конфигурации, чтобы сообщить ему, как действовать и что делать с файлами вашего приложения. Далее следует лишь один из способов настройки файла конфигурации. Он не включает в себя все варианты или вариации, поэтому думайте об этом как о предложении, из которого вы можете выбирать по своему усмотрению, и ни в коем случае не является золотым правилом.

Стандартно называть файл конфигурации webpack.config.js, но вы можете называть файл конфигурации как хотите. Если присутствует файл webpack.config.js, то Webpack автоматически его подберет. В противном случае вы можете использовать флаг - config в своих сценариях npm для ссылки на предпочтительный файл конфигурации по имени, например:

“scripts”: {
  “dev”: “webpack-dev-server --config webpack.dev.js --open”,
  “build”: “webpack --config webpack.prod.js”
}

Итак, когда вы запускаете «npm run dev», Webpack будет использовать файл webpack.dev.js, но если вы запустите «npm run build», Webpack будет использовать файл webpack.prod.js.

Конфиги

Webpack может быть головной болью, по крайней мере, я так думал, когда впервые начал его использовать. Я считаю, что его стало легче настраивать по мере увеличения количества версий и, конечно же, с увеличением числа пользователей и документации. Если у вас все еще возникают проблемы с пониманием Webpack или вы новичок в этом, не волнуйтесь, мы собираемся обмануть… выяснить это! Эй, чувак!

Вот две конфигурации, которые мы будем обсуждать. Один для производства и один для разработки вместе с package.json.

Конфигурация разработки

Конфигурация производства

Package.json

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

Конфигурация разработки

Сначала мы рассмотрим конфигурацию разработки, а затем перейдем к производственной конфигурации. Мы рассмотрим свойство config по свойству. Прежде всего, это свойство режима.

Свойство режима

Начиная с Webpack 4, была представлена ​​новая функция режима. Есть два основных варианта режима: «разработка» и «производство». В производственном режиме Webpack будет использовать «встроенные оптимизации», чтобы создать для вас производительную / оптимизированную сборку. Вы также можете отказаться, установив режим «Нет». Есть 4 основных способа использовать эту функцию «режима»:

Метод 1

Создайте файл конфигурации для каждого режима, а затем ссылайтесь на соответствующие файлы конфигурации в своем сценарии NPM, мы только что говорили об этом выше. Как правило, это хорошая идея, если ваши файлы конфигурации сильно различаются в зависимости от используемого вами режима. Это метод, который я вам покажу.

“scripts”: {
  “dev”: “webpack-dev-server --config webpack.dev.js --open”,
  “build”: “webpack --config webpack.prod.js”
}

Способ 2

Создайте один файл конфигурации, а затем используйте флаг режима в своих сценариях NPM, чтобы указать Webpack, в каком режиме должна выполняться конфигурация. Обычно это хорошая идея, когда ваша производственная конфигурация и конфигурация разработки идентичны, и вы просто ищете результат сборки для оптимизации и минимизации с помощью Webpack. Простые веб-сайты, веб-приложения и доказательства концепций были бы хорошим вариантом использования для этого. Также можно использовать, если вы просто хотите сгруппировать всю свою конфигурацию в один файл, который будет действовать одинаково в любом режиме.

“scripts”: {
  “dev”: “webpack-dev-server --mode=development --open”,
  “build”: “webpack --mode=production”
}

Способ 3

Это гибрид двух вышеперечисленных. Если вы используете один файл конфигурации вместе с флагом режима в сценарии NPM. Затем вы экспортируете функцию вместо объекта, а также используете операторы if в своей конфигурации для ссылки на режим. В зависимости от того, в каком режиме, вы можете выполнять определенные блоки кода. Это позволяет вам быть СУХИМ и не повторять свой код.

Метод 4

Используйте библиотеку webpack-merge. Здесь вы создадите файл webpack.common.js, который будет содержать все ваши свойства конфигурации, которые используются совместно разработкой и производством. Затем у вас будут файлы webpack.dev.js и webpack.prod.js, которые будут содержать их соответствующие свойства. Как и выше, это позволяет вам использовать концепцию СУХОЙ.

webpack.common.js

webpack.dev.js

webpack.prod.js

Свойство входа

entry: {
  main: './src/index.js'
},

Это именно то, на что это похоже, точка входа в ваше приложение. Это будет любой файл JavaScript, на который ссылается ваш файл index.html вашего приложения. В данном случае index.js - это точка входа в мои приложения. Как правило, входной файл зависит от других JS-файлов, и поэтому Webpack строит свой граф зависимостей (иерархическое дерево ваших JS-файлов), начиная с входного файла.

Я назвал свой входной файл «основным», назвав это свойство «основным». Это также обычное место для называния пакета. Мне нравится использовать main при разделении кода, поэтому очевидно, что содержит мою ... ну ... мою основную группу файлов. Подробнее об этом позже. Общее правило - одна запись для одного файла HTML. Поэтому, если у вас есть одностраничное приложение, у вас обычно будет только одна запись. Если у вас есть многостраничное приложение, у вас обычно будет несколько записей. Назовите их как хотите. Вы указываете относительный путь к этим входным файлам в виде строки. Вы также можете передать массив, но мы не будем сейчас об этом говорить.

Свойство вывода

output: {
  path: path.join(__dirname, '/dist'),
  filename: 'js/[name].[contenthash].js'
},

Опять же, как следует из названия, это место, куда вы хотите, чтобы Webpack поместил ваши пакеты после того, как он выполнил свои обязанности. Здесь вы можете видеть, что я помещаю все свои файлы в каталог dist. Вы можете разместить их там, где хотите, и назвать каталог, как вам нравится.

Давайте поговорим о двух свойствах выходного свойства.

Свойство path служит базовым путем для всех ваших ресурсов в вашем приложении. Таким образом, любые файлы, изображения, видео и т. Д. Будут размещены относительно этого пути. Мы импортируем и используем модуль собственного пути Node.js, который у нас есть, поскольку Webpack работает в Node.js.

Имя файла выглядит немного странно. Что это, новый язык? Нет, эти скобки - это то, что Webpack называет заменами, и их можно использовать для динамического заполнения данных. Таким образом, вам не нужно жестко кодировать имена для каждого выхода. Также рекомендуется использовать замены при разделении кода или создании многостраничного приложения. Итак, вы видите, что мы говорим Webpack поместить все наши файлы JavaScript в каталог с именем «js» в нашем каталоге «dist». Помните, что мы использовали свойство path для создания справочного каталога, которым был dist. Итак, каталог «js» создается в соответствии с этим. Затем мы используем подстановку для ссылки на имя пакета, в этом случае имя будет «main», поскольку ранее я назвал свойство «main» в свойстве entry. Затем мы используем другую замену для contenthash, которая представляет собой серию буквенно-цифровых символов. Наконец, мы добавляем расширение файла в конец строки. В конце концов, Webpack выведет файл с именем main.7169f27654ef3da3b2f4.js в ваш ./dist/js directory. А теперь давайте подробнее остановимся на этом хэше контента.

Замена Contenthash

Пока мы знаем, что хеш - это строка буквенно-цифровых символов, но какого черта нам нужно, чтобы вся эта глупая тварь была в именах наших файлов?!? Для очистки кеша !! Но давайте вкратце поговорим о кешах и о том, почему мы хотим их заблокировать!

Ваш браузер часто автоматически кэширует файлы, которые он получает с сервера, когда пользователь впервые посещает ваше приложение. После первого запроса файла он будет кэширован (сохранен локально), так что, если пользователь снова вернется в ваше приложение, ему не нужно будет снова отправлять этот запрос на сервер. Он просто заберет файл из вашего кеша. Прохладный! Меньше запросов, выше производительность! Что случилось с этим? Браузеры используют имя файла для поиска в его кеше, чтобы узнать, есть ли в нем этот файл, но что, если вы обновили свой файл с момента первого посещения пользователем вашего сайта? Если вы внесли изменения, вы хотите, чтобы пользователь видел эти изменения, отраженные в приложении. Как тогда браузер узнает, что файл был изменен? Не будет! Таким образом, он просто предоставит пользователю файл в кеше, и ваши изменения никогда не будут отражены. Что ж, это отстой, мы определенно хотим продолжить кэширование, чтобы поддерживать производительность, но мы также хотим, чтобы изменения отражались. Перебор кеша спешит на помощь! Возвращаясь к этому, вот почему мы хэшируем имена файлов. В частности, мы используем хеширование содержимого, потому что каждый раз, когда вы изменяете файл и запускаете его через Webpack, содержимое выходного пакета будет изменяться, и Webpack назначит новый буквенно-цифровой хэш, который будет включен в имя файла. Таким образом, даже если ваш браузер выполнил свою работу и кэшировал файл в первый раз, когда ваш index.html сообщает браузеру захватить то же имя файла, но на этот раз с другим хешем, он будет искать в своем кеше, а не видеть файл. с этим новым хешем, а затем запросит новый пакет с сервера. Это очистка кеша.

Вы увидите, что Contenthash используется в обеих конфигурациях, во всех случаях он используется по той же причине, что я только что объяснил.

Свойство Devtool

devtool: 'eval-source-map',

Это позволяет вам выбрать, если и как вы хотите, чтобы сопоставление источников работало для вашего приложения. Сопоставление источника - это сопоставление сжатого / минимизированного файла с исходным файлом. Мы хотим добиться повышения производительности за счет сжатия и минимизации файлов, но если вы когда-либо пытались использовать инструменты разработчика своего браузера для устранения неполадок исходного кода, вы будете знать, что файлы практически невозможно прочитать. Сопоставление исходного кода решает эту проблему, пытаясь сопоставить минимизированный файл обратно с исходным файлом, что позволяет вам просматривать исходный исходный код в том виде, в котором вы его написали, в зависимости от переданного вами параметра. Здесь есть много вариантов на выбор, они будут отличаться в зависимости от вашего варианта использования и среды. Те, которые я выбрал, предназначены для каждой среды и позволяют легко читать исходный исходный код.

Свойство оптимизации

optimization: {
  runtimeChunk: 'single',
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all'
      }
    }
  }
},

Ну для чего это могло быть? Оптимизация! Даааааа. Здесь мы говорим Webpack, как разделить наш код на разные пакеты. Подождите, вы имеете в виду сделать больше пакетов и сделать больше запросов? Разве это не противоречит интуиции? Ну да, может быть, но не в этом случае. Уменьшение количества HTTP-запросов и избежание многочисленных циклов запрос-ответ - это всегда хорошо. Однако, если у вас действительно большое приложение, у вас будет очень большой пакет, если он у вас только один. Для загрузки этого пакета с сервера может потребоваться много времени, что означает, что вам придется дождаться завершения этой загрузки, прежде чем ваше приложение может быть отображено. Это приведет к медленной загрузке и плохому приложению. Разделив код большого приложения на разные части, мы все еще можем получить прирост производительности за счет объединения и отсутствия необходимости запрашивать сотни отдельных файлов, но сохраним эти фрагменты достаточно маленькими для относительно быстрой загрузки. Золотая середина, если хотите? Это часто используется в так называемой отложенной загрузке, которую мы не будем делать в этом примере, но я упомяну немного больше в конце.

Независимо от того, загружаете ли вы ленивую загрузку или нет, всегда полезно разделить код на несколько вещей. По крайней мере, вы должны разделить свой основной код, который вы написали, в один фрагмент, а код вашего поставщика (все библиотеки, которые ваше приложение использует в каталоге node_modules), на другой фрагмент. Это восходит к концепции очистки кеша, о которой я упоминал ранее. Как правило, файлы кода вашего приложения будут меняться чаще, чем библиотеки, которые вы используете, особенно если вы привязаны к определенным версиям. Фрагмент поставщика - это большой фрагмент, и браузеру пользователя действительно не нужно повторно загружать все это, если вы просто обновили имя переменной в одном из файлов своего приложения. Таким образом, отделив файлы поставщика от основного пакета, каждый раз, когда вы обновляете код приложения, основной пакет будет единственным с обновленным хешем содержимого и, следовательно, будет загружен при следующем посещении вашего приложения пользователем. Однако пакет тяжелых поставщиков будет извлечен из кеша пользователя, поскольку он вообще не изменился. Это означает, что файлы меньшего размера будут загружаться, и, следовательно, ваше приложение, вероятно, будет загружаться быстрее, и теперь все знают, что вы являетесь богом производительности приложений!

Вернемся к конфигу. Строка runtimeChunk: «single» используется для указания Webpack создать пакет, который создает файл времени выполнения, который будет использоваться всеми сгенерированными фрагментами. Этот фрагмент времени выполнения будет содержать данные времени выполнения и манифеста для вашего приложения, которые представляют собой практически весь код, необходимый Webpack для соединения всех ваших пакетов во время его работы. Все остальное, что следует далее, - это настройка пакета поставщика. Мы говорим ему проверить, содержатся ли какие-либо файлы в каталоге node_modules, присваиваем пакету имя и сообщаем, что он включает как динамически, так и статически импортированные библиотеки в этот пакет, передав ему строку «all».

Свойство DevServer

devServer: {
  historyApiFallback: true
},

Это свойство связано с webpack-dev-server, который является сервером Webpack для обслуживания ваших файлов. Это используется только в среде разработки и не используется в производстве. Есть много вариантов, которые вы можете добавить к этому свойству, но мне это действительно не нужно. Единственное свойство, которое я использую, - это свойство, показанное в конфигурации, свойство historyAPIFallback. Позвольте мне объяснить, почему мы хотели бы установить это значение true.

До того, как SPA стал популярным, навигация осуществлялась браузером, где пользователь переходил по определенному URL-пути. Как только пользователь перейдет по этому пути, браузер отправит HTTP-запрос GET на файловый сервер, запрашивая любые ресурсы, связанные с этим путем. Если сервер был настроен для этого пути, он отвечает файлами, а затем браузер отображает страницу. Если ему не известен этот путь, он отвечает кодом состояния 404. Однако при создании SPA вы будете предоставлять пользователю только один файл index.html. В этом весь смысл. Однако это становится проблематичным, когда вы пытаетесь перемещаться по своему приложению. В SPA навигация осуществляется с помощью JavaScript, который использует HTML 5 History API, а не браузером. Поэтому, когда вы обновляете свое приложение или переходите по пути, который сервер не распознает (даже если это действительный путь для вашего приложения), он ответит кодом состояния 404, как и должно. Чтобы обойти эту проблему, установите для свойства historyApiFallback значение true. Это указывает webpack-dev-серверу отвечать файлом index.html всякий раз, когда встречается путь, для которого сервер не настроен, вместо кода состояния 404. Это позволит коду вашего приложения обрабатывать навигацию вместо сервера.

Свойство модуля

Здесь вы можете настроить параметры, чтобы определить, как различные типы модулей будут обрабатываться в вашем проекте. Свойство rules в свойстве модуля представляет собой массив объектов. Каждый из этих объектов указывает Webpack, что делать или как обрабатывать определенные типы файлов. Вы можете видеть, что все они имеют одинаковую общую структуру. Существует тестовое свойство, которое является регулярным выражением для фильтрации определенных типов расширений файлов. Свойство exclude, которое сообщает Webpack, когда не следует применять эти изменения. Свойство использования, которое содержит свойство загрузчика и свойство параметров. Свойство загрузчика содержит библиотеку, которая будет использоваться для внесения изменений в файл, а свойство options содержит параметры того, как эти изменения будут внесены. Давайте поговорим о каждом объекте в массиве правил.

JavaScript

{
  test: /\.js$/,
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader'
  }
},

Первый объект, который мы тестируем для любых файлов JavaScript. Мы исключаем файлы JavaScript, которые содержатся в библиотеке node_modules. Мы используем babel-loader для преобразования нашего кода в дружественный к браузеру код ES5. Babel позволяет нам использовать синтаксис ES5 и выше для упрощения разработки, но затем преобразует этот код в код ES5, чтобы наше приложение не нарушало работу некоторых браузеров, которые не приняли некоторые из этих изменений. Мы смотрим на вас, Microsoft! Причина, по которой мы исключаем любые файлы JS в каталоге node_modules, заключается в том, что опубликованный код в этих библиотеках почти всегда уже транспилирован, поэтому нет необходимости делать это снова, особенно при отсасывании большого каталога.

При использовании babel для транспиляции кода вам необходимо указать ему, как это сделать. Вы можете сделать это с помощью предустановок. Эти предустановки указывают babel, как переносить определенные сегменты кода. Например, существует предустановка реакции, которая инструктирует babel, как преобразовать код JSX в код ES5. Это необходимо, потому что ваш браузер не поддерживает код JSX. Вы можете ссылаться на эти предустановки в реальной конфигурации или в отдельной конфигурации, называемой файлом .babelrc.

{
  "presets": ["@babel/env", "@babel/react"]
}

SCSS и CSS

{
  test: /\.(s*)css$/,
  use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader',    'sass-loader']
},

Затем мы используем RegEx для проверки любых расширений файлов .scss или .css. Если вы используете SCSS или SASS для своего стиля, вы захотите преобразовать его в CSS. Давайте пройдемся по этой цепочке загрузчиков, чтобы понять, что каждый из них делает. Загрузчики воздействуют на файл справа налево, поэтому в этом случае загрузчик sass будет первым загрузчиком, с которым столкнется входящий файл. Загрузчик sass просто конвертирует SCSS или SASS в CSS. Следующий загрузчик - это postcss-loader, который делает препроцессор PostCSS доступным для Webpack. PostCSS - это инструмент для преобразования стилей с помощью плагинов JS. Таким образом, это позволяет использовать для преобразования и обогащения наших файлов CSS. Как и в случае с babel, вам нужно создать файл конфигурации в корневом каталоге вашего проекта. Файл конфигурации postcss.config.js содержит объект, содержащий массив плагинов, который импортирует различные библиотеки, которые мы хотим использовать для преобразования нашего CSS. У меня здесь двое. Плагин autoprefixer использует данные с caniuse.com, чтобы определить, следует ли добавлять префиксы поставщиков к вашим стилям, чтобы обеспечить более широкий охват браузером. Второй плагин минимизирует наш код CSS, чтобы уменьшить окончательный размер файла. Css-loader интерпретирует операторы @import и url () как операторы импорта / требования JavaScript и, следовательно, разрешает их объединение. Наконец, ваши файлы попадают в плагин mini-css-extract-plugin, который берет весь ваш CSS и объединяет его в свой собственный уникальный пакет, а затем вставляет ссылку в тег head вашего index.html. Обратите внимание, что я импортирую плагин в верхнюю часть файла, а затем создаю новый экземпляр плагина в нижней части файла. Мы обсудим это позже.

Все остальные файлы, кроме изображений

{
  test: /\.(woff(2)?|ttf|eot)$/,
  use: {
    loader: 'file-loader',
    options: {
      name: '[name].[contenthash].[ext]',
      outputPath: 'assets/fonts/',
      publicPath: 'assets/fonts/'
    }
  }
},
{
  test: /\.pdf$/,
  use: {
    loader: 'file-loader',
    options: {
      name: '[name].[contenthash].[ext]',
      outputPath: 'assets/docs/',
      publicPath: 'assets/docs/'
    }
  }
},
{
  test: /\.(mp3|wav|wma|ogg)$/,
  use: {
    loader: 'file-loader',
    options: {
      name: '[name].[contenthash].[ext]',
      outputPath: 'assets/audio/',
      publicPath: 'assets/audio/'
    }
  }
},
{
  test: /\.(mp4|webm)$/,
  use: {
    loader: 'file-loader',
    options: {
      name: '[name].[contenthash].[ext]',
      outputPath: 'assets/videos/',
      publicPath: 'assets/videos/'
    }
  }
}

Все остальные расширения, кроме изображений, обрабатываются загрузчиком файлов. File-loader просто включает файлы, на которые есть ссылки с помощью операторов import и require, в выходные пакеты. Вы увидите, что для свойства name используются подстановки. Вы увидите свойство outputPath, в которое эти файлы будут помещены со ссылкой на путь, на который мы ссылались ранее в свойстве output. Свойство publicPath - это место, где файлы будут размещаться относительно корня сервера. Таким образом, ваше приложение знает, откуда брать эти файлы, когда ему нужно их отобразить. Это стандартная архитектура для всех случаев расширения файлов.

Изображения

{
  test: /\.(jpe?g|png|gif|svg)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 40000,
        name: '[name].[contenthash].[ext]',
        outputPath: 'assets/images/',
        publicPath: 'assets/images/'
      }
    },
    'image-webpack-loader'
  ]
},

Вы увидите, что в этом случае мы используем два разных загрузчика. Опять же, справа налево, мы сначала используем image-webpack-loader, который сжимает ваши изображения, чтобы уменьшить размер их файлов. Затем они передаются загрузчику URL. Url-loader преобразует файлы в URI в кодировке base64. Мы передаем свойство limit, чтобы установить предел, который будет определять, кодировать файл или нет. В этом случае, если размер файла меньше 40 КБ, он будет закодирован, если нет, он будет выведен как отдельный файл в каталог изображений.

Свойство подключаемых модулей

Плагины похожи на загрузчики на стероидах. Они более глубоко интегрированы в Webpack, чем загрузчики, и имеют доступ к компилятору. Загрузчики работают с отдельными файлами во время или до создания пакета, в то время как плагины работают на уровне пакета или фрагмента и обычно работают в конце процесса создания пакета.

Здесь мы используем 3 плагина. Первый плагин - HashedModuleIdsPlugin. Вы можете видеть в верхней части страницы, что мы импортируем библиотеку webpack, чтобы мы могли получить доступ к этому плагину. Этот плагин предотвращает обновление хэша пакета поставщика, если вы повторно запустите Webpack. Без этого плагина, если вы снова запустите Webpack, хэш пакета поставщика также обновится из-за изменения его module.id. Этот плагин предотвращает это, поэтому хэш поставщика будет обновляться только при изменении кода поставщика, как и должно быть.

Следующий плагин - это HtmlWebpackPlugin, который мы импортируем в верхнюю часть файла конфигурации. Этот плагин автоматически создает для нас файл index.html. Есть разные варианты, которые вы можете передать этому плагину, но давайте поговорим о тех, которые я использовал здесь. Inject: true указывает Webpack динамически вставлять наши пакеты в index.html. Свойство шаблона сообщает Webpack о необходимости создания динамического index.html на основе нашего шаблона, расположенного по этому пути. Свойство filename сообщает Webpack, как назвать динамически сгенерированный html-файл.

Последний плагин, который мы здесь видим, - это MiniCssExtractPlugin, о котором мы говорили ранее. Как видите, мы передаем ему имя и место, где он будет выводить пакет стилей.

Конфигурация производства

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

В этом конфиге установлен режим production, о котором мы говорили ранее.

Свойство devtool использует исходную карту вместо eval-source-map. Это готовый к производству вариант для сопоставления источников.

Здесь нет свойства devServer, потому что помните, что мы используем только webpack-dev-server в режиме разработки.

Здесь вы увидите дополнительный плагин. CleanWebpackPlugin импортируется вверху и создается в свойстве plugins. Этот плагин отвечает за удаление любого каталога, который вы в него передаете, перед созданием новой сборки. Мы удаляем старое, чтобы освободить место для нового. Если бы мы этого не сделали, мы бы быстро получили раздутый каталог dist, в котором есть куча файлов сборки, потому что старые не удаляются.

new CleanWebpackPlugin('dist', {}),

Выходные пакеты

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

Давайте сначала поговорим о выводе на консоль. Я слишком простое приложение для реагирования, которое отображало текст и 2 изображения. Одно изображение было маленьким, а другое - большим. В самом верху вывода вы увидите наше большое изображение. Обратите внимание на размер этого изображения. Первоначально он был 430 КБ, а теперь был сжат до 265 КБ благодаря image-webpack-loader. Также обратите внимание, что это отдельный файл, не связанный ни с чем. Но что случилось с нашим маленьким изображением? Это не отображается в выводе. Это связано с тем, что изображение меньшего размера было меньше предела, установленного для загрузчика URL, который составлял 40 КБ. Итак, образ base64 закодирован и включен в основной комплект! Woohoo! Это был хороший тест, чтобы убедиться, что все работает. В качестве примечания, Webpack предупреждает меня, что большое изображение все еще «[большое]», и мы должны уменьшить его размер перед сжатием.

Вы также заметите, что все наши ожидаемые пакеты тоже присутствуют: main, vendor, runtime и styles. Как мы и ожидали. У каждого из них также есть файл .map. При использовании опции source-map для свойства devtools полная SourceMap создается как отдельный файл. Он добавляет ссылочный комментарий к исходному пакету, чтобы инструменты разработки знали, где его найти. Обратите внимание, что для правильной работы сопоставления источников может потребоваться дополнительная настройка файла конфигурации и / или браузера. Я не хотел углубляться в эту статью, поэтому позволю вам изучить это. Информация находится в документации Webpack.

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

Если вы посмотрите на файловую структуру, в частности на каталог dist, вы увидите, что все файлы были выведены в каталогах, которые мы ожидали.

Следующие шаги

Это была длинная статья, и мы пока лишь поверхностно коснулись того, что вы можете делать с Webpack. Я показал вам конфигурацию, которая поможет вам прямо сейчас начать как разработку, так и производство, и будет обрабатывать большинство вариантов использования для любого приложения среднего уровня. Если вы хотите использовать эту конфигурацию, вы можете изучить несколько других функций, таких как:

Встряхивание дерева - только код объединения, который фактически используется в базе кода. Устраняя неиспользуемый код, вы можете уменьшить размер пакета, который для большого приложения может быть приличным.

Ленивая загрузка. Ваш браузер может запрашивать только определенные пакеты в зависимости от текущего URL-адреса навигации. Если у вас есть большое приложение, вместо того, чтобы ждать, пока все ваши пакеты загрузятся в самом начале, вы должны запросить только те, которые будут отображать целевую страницу, а затем, когда пользователь будет перемещаться, вы будете запрашивать разные пакеты для визуализации страница или несколько страниц. Причина, по которой это полезно, заключается в том, что вы не знаете, будут ли пользователи нажимать мимо вашей целевой страницы, и если это так, почему мы загрузили код для 10 других страниц, замедляя время начальной загрузки приложения, когда они никогда не увидят те другие страницы.

Горячая перезагрузка модуля (HMR). Вы можете настроить webpack-dev-server на включение горячей перезагрузки, чтобы при обновлении кода этот браузер автоматически загружал изменения без необходимости обновления. Это будет использоваться только при разработке, но может помочь вам быстрее писать код.

Хорошо, хватит, чтобы я убил свою клавиатуру на день! Надеюсь, мне удалось каким-то образом пополнить вашу базу знаний. Я надеюсь, что вы его поразите, и я надеюсь, что этот Новый год станет для вас лучшим годом!

Если это вас заинтересовало, подумайте об аплодисментах ниже. Это помогает мне оставаться сгорбленным над этим ноутбуком, пишущим статьи, и помогает мне оценить, пишу ли я полезное дерьмо для наших людей. Ура!

Свяжитесь со мной в LinkedIn по адресу www.linkedin.com/in/accardosteven