Рубрики
Без рубрики

Как создать добычу производства WebPack 4 Config с нуля

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

Автор оригинала: FreeCodeCamp Community Member.

WebPack является мощным менеджером Bundler и зависимостями, используемым многими компаниями на уровне предприятия, в качестве инструмента для их интерфейса.

Как правило, WebPack настроен, когда проект сначала настроен, и затем небольшие настройки выполняются в файлы конфигурации по мере времени для времени. Из-за этого многие разработчики не имеют большого опыта работы с WebPack.

В этой практическом руководстве мы пройдемся по основам настройки вашего собственного самого производственного веб-папата конфигурации с использованием WebPack 4. Мы обсудим управление выводами, управление активами, разработку и конфигурации DEV и PROD, Babel, Mining, Cache Busting , и больше.

Давайте начнем!

Демо-приложение

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

Если вы хотите следовать, весь код в этой статье можно найти в GitHub. Начальная точка найдена здесь и Готовый результат найден здесь Отказ

Отправная точка

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

webpack-demo
 |_ src
    |_ index.js
 |_ .gitignore
 |_ index.html
 |_ package.json
 |_ README.md
 |_ yarn.lock

index.html Файл приятный и простой, просто заголовок страницы и A Сценарий ярлык:




  
    Webpack Training 1
  
  
    

Webpack Training 1

Сценарий Теги ссылки наше ./src/index.js Файл, который имеет всего несколько строк JavaScript в нем, что выводит текст, «Привет из WebPack!»:

const p = document.createElement('p')
p.textContent = 'Hello from webpack!'
document.body.append(p)

Если вы перетащите index.html Файл в ваш браузер, вы сможете просмотреть нашу простую веб-страницу:

Установка зависимостей

Я включил WebPack и WebPack-Cli как DevDependonds В Package.json файл.

Чтобы установить их, запустить:

yarn install

Тестовый пробег WebPack

WebPack 4 устанавливается в виде инструмента «нулевой конфигурации», что означает, что вы можете запустить его из коробки без какой-либо начальной конфигурации. Теперь для любого реального проекта вы Будет ли Нужно сделать некоторую конфигурацию, но приятно, что вы можете, по крайней мере, сделать быструю проверку здравоохранения, чтобы убедиться, что WebPack может работать без необходимости проходить через кучу начальных шагов конфигурации.

Итак, давайте проверим это. Запустить:

yarn webpack

Теперь вы должны увидеть Dist каталог, созданный в вашем каталоге проекта. И внутри этого вы должны увидеть main.js Файл, который является нашим минимумом.

Большой! WebPack, кажется, работает.

Ссылка выходной код

Хорошо, теперь, когда у нас есть код JavaScript в нашем Dist каталог, давайте наш index.html Ссылка на файл это. Вместо Сценарий Тег выглядит так:

Давайте изменим это к этому:

Теперь обновите страницу в своем браузере, и вы все равно должны увидеть тот же самый вывод, только на этот раз «Привет из WebPack!» Текст генерируется ./dist/main.js файл сейчас.

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

Теперь, когда у нас установлено WebPack и прошла через быструю проверку проверки здравоохранения, давайте создадим фактический файл конфигурации WebPack. Создайте файл под названием webpack.config.js и поместите следующий код внутри него:

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  }
}

Вход Собственность говорит WebPack, где находится наш исходный код. Это «точка входа» для нашего приложения.

Выход Свойство сообщает WebPack, что позвонить на выходной файл и какой каталог его размещать его.

Достаточно просто, верно?

Теперь давайте создадим сценарий NPM в нашем Package.json файл:

"scripts": {
  "build": "webpack --config=webpack.config.js"
}

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

Измените имя выходного файла

Теперь, просто для удовольствия, давайте изменим имя вывода файла. Чтобы сделать это, мы откроем наш webpack.config.js Файл и изменить Выход Недвижимость от этого:

output: {
  filename: 'main.js',
  path: path.resolve(__dirname, 'dist')
}

К этому:

output: {
  filename: 'tacos.js',
  path: path.resolve(__dirname, 'dist')
}

Сейчас беги пряжа строит снова для генерации вывода. Вы должны увидеть Tacos.js Файл в вашем Dist каталог сейчас.

Но ждать! Мы также видим старый main.js Файл в нашем Dist Каталог тоже! Не было бы неплохо, если WebPack может удалить старый ненужный вывод каждый раз, когда мы делаем новую сборку?

Для этого должна быть плагин.

Плагины WebPack

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

CleanWebpackplugin.

ОК, вернемся к нашей проблеме. Было бы здорово, если бы мы могли убрать Dist каталог перед каждой новой сборкой. Для этого есть плагин!

Мы можем использовать CleanWebpackplugin чтобы помочь нам здесь. Во-первых, нам нужно установить его в наш проект:

yarn add --dev clean-webpack-plugin

Чтобы использовать его, мы просто требуется плагин в нашем webpack.config.js файл, а затем включите его в плагины Массив в нашей настройке конфигурации:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin()
  ]
}

Сейчас беги пряжа строит Опять же, и вы должны увидеть только один выходной файл в вашем Dist каталог. Задача решена!

Htmlwebpackplugin.

Еще одна вещь, которая немного раздражает нашей настройке, это то, что в любое время мы меняем Выход Имя файла в нашем webpack.config.js Файл, мы также должны изменить это имя файла, которое мы ссылаемся в нашу Сценарий Тег в нашем index.html файл. Разве это не было бы здорово, если WebPack может управлять этим для нас?

Для этого есть плагин! Мы можем использовать Htmlwebpackplugin Чтобы помочь нам управлять нашим HTML-файлом. Давайте устанавливаем его в наш проект сейчас:

yarn add --dev html-webpack-plugin

Теперь давайте переместим наше index.html Файл внутри нашего SRC каталог, так что это брат к index.js файл.

webpack-demo
 |_ src
    |_ index.html
    |_ index.js
 |_ .gitignore
 |_ package.json
 |_ README.md
 |_ yarn.lock

Мы также можем удалить Сценарий Тег в нашем index.html Файл, поскольку у нас будет ручка WebPack, вставив подходящую Сценарий Тег для нас. Удалить эту строку, чтобы ваш index.html Файл выглядит так:




  
    Webpack Training 1
  
  
    

Webpack Training 1

Теперь давайте требуется Этот плагин в нашем webpack.config.js файл, а затем включите его в плагины Массив в нашей настройке конфигурации, как мы сделали для первого плагина:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ]
}

В этих вариантах для Htmlwebpackplugin Мы указываем Имя файла Для того, что мы хотели бы, чтобы выводимый файл был вызван.

Мы указываем для вставлять Что мы хотели бы, чтобы наш файл JavaScript вводится в Тело Тег, устанавливая значение для правда Отказ

И, наконец, для Шаблон Мы поставляем место нашего index.html Файл в SRC каталог.

Санитарная проверка

Хорошо, давайте убедитесь, что все все еще работает должным образом. Беги пряжа строит И убедитесь, что вы видите два файла в вашем Dist Каталог: index.html и main.js Отказ

Если вы внимательно посмотрите в свой index.html Файл, вы увидите main.js Файл ссылается.

Теперь откройте ./dist/index.html Файл в вашем браузере, чтобы убедиться, что ваша страница правильно загружается. Если вы правильно соблюдали эти шаги, ваша страница все еще должна работать:

Создать сервер разработки

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

Для этого мы будем использовать WebPack-Dev-Server Отказ Во-первых, нам нужно будет установить его:

yarn add --dev webpack-dev-server

Теперь давайте расстаемся на наших одиноких webpack.config.js Файл на два отдельных файла конфигурации, один для производства и один для разработки. Мы позвоним файл для производства webpack.config.prod.js и файл для разработки webpack.config.dev.js Отказ

Разработка webpack config.

Вот наш файл конфигурации разработки:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
  },
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ]
}

Обратите внимание, что мы указали Режим как Развитие Теперь, и мы указали, что мы хотели бы Inline-Source-Map Для наших файлов JavaScript означает, что исходная карта включена в конце каждого файла JavaScript. Для нашего сервера Dev мы указывали, что наш контент будет найден в Dist каталог.

Вся остальная часть разработки конфигурация осталась прежней.

Production WebPack Config

Теперь вот наш файл производственного конфигурации:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'production',
  devtool: 'source-map',
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ]
}

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

Производство и разработка сценариев NPM

Наконец, давайте добавим еще несколько сценариев NPM в нашем Package.json Файл, чтобы мы могли работать с нашим разработчиком и производственным WebPack Configs:

"scripts": {
  "build": "webpack --config=webpack.config.prod.js",
  "build-dev": "webpack --config=webpack.config.dev.js",
  "start": "webpack-dev-server --config=webpack.config.dev.js --open"
}

Теперь давайте попробуем каждый из этих сценариев.

Беги пряжа строит Чтобы увидеть продукцию производства. Вы должны увидеть, что main.js Файл в вашем Dist каталог домиден и что у него есть сопроводительное main.js.map Файл карты источника.

Сейчас беги пряжа build-dev Чтобы увидеть вывод сборки разработки. Вы должны увидеть main.js Файл в вашем Dist каталог, но теперь обратите внимание, что это не заминирован.

Наконец, беги Пряжа начать Чтобы запустить сервер разработки. Это откроет приложение на http://localhost: 8080/ Отказ Больше не нужно просматривать файлы напрямую, просто потянув их в браузер! Теперь у нас есть настоящий живой сервер развития!

Выход вы видите, должен все еще выглядеть так же, как у него всегда есть:

Внесение изменений во время развития

Теперь, когда у нас есть рабочий сервер Dev, давайте экспериментируем с простыми изменениями нашего ./src/index.js файл. Вместо того, чтобы выводить «Привет из WebPack!», Давайте изменим его, чтобы сказать «Привет от DEV Server!».

Сохраните файл, а затем увидите страницу на вашем сервере DEV Автоматически перезагрузить и обновить для вас! Это будет приятным повышением вашей производительности вашего разработчика.

Не повторяйте себя (сухой)

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

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

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

Webpackmerge.

Мы можем использовать WebPack-Merge Плагин для управления общим кодом, на который полагаются несколько файлов конфигурации. Для этого мы впервые установте пакет:

yarn add --dev webpack-merge

Теперь мы создадим третий файл конфигурации веб-паката webpack.config.common.js Отказ Это где мы сохраним наш общий код. Прямо сейчас наши файлы конфигурации разработки и производства имеют одинаковую точку входа, вывод и плагины. Все, что отличается между двумя файлами, являются режимом, исходной картой и сервером Dev.

Итак, содержание нашего webpack.config.common.js Файл будет:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ]
}

И теперь, мы можем объединить этот общий объект конфигурации в нашу конфигурацию разработки, как это:

const merge = require('webpack-merge')
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
  },
})

И мы можем объединить общий объект конфигурации в наш конфигурацию по производству, как это:

const merge = require('webpack-merge')
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'production',
  devtool: 'source-map',
})

Посмотрите, насколько более коротким и уборщиком эти два файла выглядят! Красивый!

Укажите наше приложение

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

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

В нашем SRC каталог, давайте создадим index.csss Файл и поместите следующие строки CSS внутри него:

body {
  background: deeppink;
  color: white;
}

Тогда в нашем ./src/index.js Файл, давайте импортируем этот файл CSS:

import './index.css'

Теперь запустите Пряжа начать Чтобы снова запустить наш сервер разработки.

О, нет! Мы получаем ошибку!

ERROR in ./src/index.css 1:5
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> body {
|   background: deeppink;
|   color: white;
 @ ./src/index.js 1:0-20

Каковы эти «погрузчики» это говорит о?

WebPack погрузчики

Ранее мы обсудили плагины WebPack, которые позволяют расширить процесс сборки WebPack. Существует также экосистема WebPack « погрузчики », которые помогают WebPack знать, как понимать и загрузить разные типы файлов. Вне коробки, WebPack понимает, как обрабатывать наши файлы JavaScript, но он не знает, что делать с файлами CSS. Давайте исправить это.

Стиль загрузчик и CSS-погрузчик

В частности, есть два погрузчика, которые будут полезны для нас здесь: Стиль-погрузчик и CSS-Loader Отказ Давайте получим те, которые включены в наш проект, а затем обсудить, как они работают.

Для начала, как всегда, нам нужно установить эти две зависимости:

yarn add --dev style-loader css-loader

Тогда мы можем добавить их в нашу webpack.config.common.js Файл в разделе «Правила модуля» вниз внизу:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

Этот раздел устанавливает правила для WebPack, чтобы он знал, что делать с каждым файлом, который он встречается. Тест Свойство – это регулярное выражение, что WebPack проверяет на имя файла. В этом случае мы хотим обрабатывать файлы с .css расширение.

Тогда использовать Свойство сообщает WebPack, какой загрузчик или погрузчики использовать для обработки файлов, соответствующих критериям. Обратите внимание, что заказ здесь имеет значение!

Загрузчики WebPack читаются справа налево. Итак, сначала CSS-Loader будет применяться, а затем Стиль-погрузчик будет применяться.

Теперь, что эти погрузчики на самом деле делают для нас?

CSS-Loader Интерпретирует и решает импортированные файлы CSS, которые вы ссылаетесь в ваш JavaScript. Так что в этом случае CSS-Loader Помогает сделать эту линию работу:

import './index.css'

Далее Стиль-погрузчик вводит CSS в домо. По умолчанию Стиль-погрузчик берет CSS, который он встречается и добавляет его в дом внутри Стиль ярлык.

Давайте перезапустим наш Dev Server, убив текущий процесс (если у вас все еще есть запуск), а затем начать его снова с Пряжа начать Отказ Теперь в веб-браузере вы должны увидеть это на https://localhost: 8080/ :

Ооо, так красочно!

Примечание на других погрузчиков WebPack

Мы не будем покрывать погрузчики для других типов файлов в этой статье, но знайте, что есть погрузчик для всего, что можно сделать! Вы можете использовать файловой погрузчик или URL-погрузчик Для загрузки изображений и других активов. Вы можете использовать Sass-Loader Чтобы обрабатывать преобразование файлов SASS/SCSS в CSS перед трубопроводом, который выводится на CSS-Loader и Стиль-погрузчик Отказ WebPack может обрабатывать меньше файлов с Менее погрузчик Если это ваше предпочтение.

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

Babel Loader

ОК, вернемся в наше демонстрационное приложение. До сих пор мы написали всего несколько строк JavaScript. Было бы здорово, если бы мы могли написать наш JavaScript с помощью новых функций, которые еще не поддерживаются в каждом браузере. Бабел Является ли компилятор JavaScript, который может включить код ES6 + в код ES5.

И (вы уже догадались), для этого есть погрузчик: Babel-Loader Отказ

Настроить Babel-Loader Мы будем следовать инструкциям по их руководству по установке, связанным выше.

Во-первых, мы устанавливаем наши зависимости:

yarn add --dev babel-loader @babel/core

Далее мы добавим новое правило на наш массив правил модуля в нашем webpack.config.common.js файл:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /[\\/]node_modules[\\/]/,
        use: {
          loader: 'babel-loader',
        },
      },
    ]
  }
}

Это скажет WebPack, когда он встречается .js или .jsx Файлы для использования Babel, чтобы преобразовать код. Мы используем Исключить Недвижимость, чтобы убедиться, что Babel не пытается преобразовать файлы JavaScript в нашем node_modules каталог. Это сторонние зависимости, которые уже должны были позаботиться о своих создателях.

Далее мы добавим еще одну зависимость для предустановки Babel:

yarn add --dev @babel/preset-env

И тогда мы создадим .babelrc Файл, где мы можем сделать другую конфигурацию Babel по мере необходимости. Мы сохраним наш файл довольно простым и просто укажите предустановку Babel, которые мы хотим использовать:

{
  "presets": ["@babel/preset-env"]
}

И, наконец, давайте напишем какой-то код ES6 в нашем ./src/index.js файл:

import './index.css'

const p = document.createElement('p')
p.textContent = 'Hello from webpack!'
document.body.appendChild(p)

const p2 = document.createElement('p')
const numbers1 = [1, 2, 3, 4, 5, 6]
const numbers2 = [7, 8, 9, 10]
const numbers3 = [...numbers1, ...numbers2]
p2.textContent = numbers3.join(' ')
document.body.appendChild(p2)

Это действительно тривиальный пример, но мы используем Распространение оператора здесь, чтобы объединить две массивы.

Теперь, если мы убьем наш рабочий процесс и запустите Пряжа начать Опять же, мы должны увидеть это в браузере:

Большой! Все работает красиво.

Временно пропустить стили

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

Это поведение результатов от того, как Стиль-погрузчик работает. Как упоминалось выше, Стиль-погрузчик берет CSS и помещает его в Стиль Тег в вашем HTML. Из-за этого есть краткий период времени, в котором Стиль Тег еще не добавлен!

Теперь это нормально для среды развития, но мы определенно не захотете такого рода поведения, происходящего в производстве. Давайте исправить это.

Minicssextractplugin.

А не впрыскивая CSS в наш HTML как Стиль Теги, мы можем использовать Minicssextractplugin Для создания отдельных файлов CSS для нас. Мы будем использовать это в нашем производстве, пока все еще просто используя Стиль-погрузчик На нашем конфиге развития.

Во-первых, давайте установим зависимость в нашем проекте:

yarn add --dev mini-css-extract-plugin

Сейчас в нашем webpack.config.common.js Файл Давайте удалим правило CSS, поскольку мы будем обращаться с этим по-разному в развитии и производстве. Мы остались с этим в нашей общую конфигурацию:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /[\\/]node_modules[\\/]/,
        use: {
          loader: 'babel-loader',
        },
      },
    ]
  }
}

Теперь, в нашем webpack.config.dev.js Файл, давайте добавимся обратно в Стиль-погрузчик и CSS-Loader что мы только что удалили с нашего общего конфигурации:

const merge = require('webpack-merge')
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './dist',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
    ]
  }
})

И, наконец, в нашем webpack.config.prod.js Файл, давайте добавим в нашу новую Мини-CSS-экстракт-плагин :

const merge = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'production',
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ]
})

Этот немного отличается, потому что он на самом деле является плагином и Погрузчик, поэтому он идет в правилах модуля и в разделах плагинов.

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

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

Обратите внимание, что на самом деле он на самом деле генерирует файл CSS, и содержимое HASH включено в имя файла.

Хорошо, проблема решена! Нет больше Blip, когда страница нагружает в производство, так как у нас есть стили, включены как ссылка Тег на фактический файл CSS.

Cache Busting

Поскольку мы включили HASH CHASH в сгенерированном файле CSS, сейчас самое время, чтобы поговорить о растрате кэша. Почему, вы спрашиваете, мы хотели бы, чтобы содержание было включено в наши имена файлов? Чтобы помочь браузеру понять, когда файл изменился!

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

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

Итак, в чем проблема здесь? Представьте, что если у нас был файл под названием main.js используется в нашем приложении. Затем пользователь посещает ваше приложение и их браузер кэширует main.js файл.

Теперь в более позднем моменте во времени вы выпустили новый код для вашего приложения. Содержание main.js Файл изменился. Но, когда этот же пользователь снова посещает ваше приложение, браузер видит, что ему нужно main.js Файл, отмечает, что у него есть кэшированный main.js Файл и просто использует кэшированную версию. Пользователь не получает свой новый код!

Чтобы решить эту проблему, обычная практика – включить хеш контента в имя каждого файла. Как обсуждалось ранее, содержимое HASH является строковым представлением содержимого файла. Если содержимое файла не меняется, содержимое HASHH не меняется. Но если содержимое файла сделать Изменить, то контент хэш Также изменения.

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

В том числе хеш контента

Чтобы включить хеш контента в наших именах файлов JavaScript, мы модифицируем только одну строку кода в нашем webpack.config.common.js файл. Эта линия:

filename: 'main.js'

Изменится на эту строку:

filename: '[name].[contenthash].js'

Так что весь файл выглядит так:

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].[contenthash].js', // this line is the only difference
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: true,
      template: path.resolve(__dirname, 'src', 'index.html'),
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /[\\/]node_modules[\\/]/,
        use: {
          loader: 'babel-loader',
        },
      },
    ]
  }
}

Теперь, если вы запустите пряжа строит , вы увидите, что ваш JavaScript, и ваши CSS имеют Content Hashes включены:

Если вы запустите пряжа строит Опять же и сравните свой новый вывод на свой старый вывод, вы заметите, что контент-хеши находятся точно так же время.

Но, если вы редактируете свой ./src/index.js файл любым способом, а затем запустить пряжа строит Опять же, вы получите новый хеш контента, потому что контент изменился! Попробуй!

Министерству CSS.

Последнее, но не менее важное, мы можем захотеть министерзировать наши CSS. Мы уже оформляем наш JavaScript для производственной сборки, но мы еще не добываем наши CSS. Давайте сделаем это.

Мы можем минимизировать наши CSS, используя Оптимизация-CSS-Assets-WebPack-Plugin Отказ Давайте установим эту зависимость сейчас:

yarn add --dev optimize-css-assets-webpack-plugin

Теперь мы можем добавить это в раздел оптимизации нашего webpack.config.prod.js файл:

const merge = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'production',
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
  optimization: {
    minimizer: [
      new OptimizeCssAssetsPlugin({
        cssProcessorOptions: {
          map: {
            inline: false,
            annotation: true,
          },
        },
      }),
    ],
  },
})

Теперь, если мы запустим пряжа строит а затем посмотрите содержимое нашего Dist Каталог, мы видим, что полученные CSS министерны. Хороший!

body{background:#ff1493;color:#fff}
/*# sourceMappingURL=main.66e0d6aeae6f3c6fb895.css.map */

Но ждать! Если мы посмотрим на наш полученный файл JavaScript, он не будет заминирован! Хм. Это был домифицировано раньше, так что случилось здесь?

Выпуск в том, что мы теперь вручную настроили раздел минимизатора оптимизации нашего конфигурации WebPack. Когда этот раздел не находится в файле конфигурации WebPack, WebPack по умолчанию для использования собственных предпочтений минимизатора, который включает в себя Minificing JavaScript, когда Режим установлен на Производство Отказ

Поскольку теперь мы переоцениваем эти по умолчанию, добавив в наши предпочтения для Minifific Actsets CSS, нам понадобится также явно включать инструкции для того, как мы хотим, чтобы WebPack понимать активы JavaScript.

Terser WebPack Plugin

Мы можем минимузировать наши файлы JavaScript, используя TerserWebpackplugin Отказ Давайте начнем с установки этой зависимости:

yarn add --dev terser-webpack-plugin

Тогда в нашем webpack.config.prod.js Файл, давайте добавим Terser-WebPack-Plugin Для нашей оптимизации настроек минимизатора в нижней части файла:

const merge = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const commonConfig = require('./webpack.config.common')

module.exports = merge(commonConfig, {
  mode: 'production',
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
  optimization: {
    minimizer: [
      new OptimizeCssAssetsPlugin({
        cssProcessorOptions: {
          map: {
            inline: false,
            annotation: true,
          },
        },
      }),
      new TerserPlugin({
        // Use multi-process parallel running to improve the build speed
        // Default number of concurrent runs: os.cpus().length - 1
        parallel: true,
        // Enable file caching
        cache: true,
        sourceMap: true,
      }),
    ],
  },
})

Теперь, если мы запустим пряжа строит и посмотрите на вывод в Dist Каталог, мы должны увидеть, что наши файлы CSS, так и наши файлы JavaScript Mailified. Там мы идем!

Обертывание

Если вы следили по этому далеко, я высоко оцениваю!

Давайте рассмотрим то, что мы узнали до сих пор:

  • WebPack – это инструмент сборки для совместного использования активов и управления зависимостью.
  • WebPack можно настроить файл конфигурации.
  • Плагины изменяют и расширяют процесс сборки WebPack.
  • Погрузчики проводят WebPack, как обрабатывать разные типы файлов.
  • Clean-Webpack-Plugin Может использоваться для удаления старых артефактов сборки из Dist каталог.
  • html-webpack-plugin Помогает управлять файлом HTML, включая JavaScript JavaScript в файл через Сценарий Теги.
  • WebPack-Dev-Server Создает SEV Server, чтобы облегчить локальное развитие.
  • Полезно иметь отдельную конфигурацию WebPack для разработки и производства. Вы можете поделиться и объединять файлы конфигурации, используя WebPack-Merge плагин.
  • Мы можем обрабатывать укладку нашего приложения, включая погрузчики, такие как CSS-Loader , Стиль-погрузчик , Sass-Loader , Менее погрузчик и Мини-CSS-экстракт-плагин (который функционирует как плагин, так и погрузчик).
  • Мы можем включить новый синтаксис JavaScript и функции, используя Babel и Babel-Loader Отказ
  • Мы можем включить контент Hasthes в наших именах файлов, чтобы помочь с растрамированием кэша и управление новыми версиями нашего выпущенного кода.
  • Мы можем минимурить наши CSS с Оптимизация-CSS-Assets-WebPack-Plugin Отказ
  • Мы можем минимузировать наш JavaScript с Terser-WebPack-Plugin Отказ

Что дальше?

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

Но еще еще больше! Другие расширенные темы WebPack включают Код расщепления , ленивая загрузка , Встряхивание дерева , и больше!

Если вы заинтересованы в изучении WebPack больше самостоятельно, я бы очень рекомендую читать через официальный Гиды WebPack Отказ

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

Спасибо за чтение, и счастливое кодирование!