Cleanwebpackplugin что это
Перейти к содержимому

Cleanwebpackplugin что это

  • автор:

Настройка Webpack 5 с нуля

Если вы раньше использовали вебпак 4, вот некоторые отличия от 5 версии:

  • команда «webpack-dev-server» теперь выглядит как «webpack-serve»
  • отдельная установка file-loader, raw-loader и url-loader больше не требуется, вы можете использовать встроенные загрузчики ресурсов (asset modules)
  • полифилы для Node.js больше не поддерживаются, поэтому если, например, вы получили ошибку для stream, необходимо добавить пакет «stream-browserify» в качестве зависимости и < stream: «stream-browserify» >в качестве алиаса в настройки вебпака

Что такое вебпак?

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

Вебпак — это сборщик модулей. Он служит для упаковки кода для использования браузером. Он позволяет использовать последние возможности JavaScript с помощью Babel или использовать TypeScript и компилировать его в кроссбраузерный минифицированный код. Он также позволяет импортировать статические ресурсы в JavaScript.

Для разработчиков вебпак также предоставляет сервер для разработки, который умеет обновлять модули и стили на лету при сохранении файла. Инструменты командной строки, такие как «vue create» и «react-create-app» используют вебпак за сценой, но вы легко можете создать собственную настройку вебпака для указанных фреймворков.

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

Установка

Создаем директорию проекта и инициализируем его:

mkdir webpack-tutorial cd !$ // или cd webpack-tutorial yarn init -yp // создает стандартный приватный файл "package.json" // или npm init -y 

Устанавливаем webpack и webpack-cli в качестве зависимостей для разработки:

yarn add -D webpack webpack-cli // или npm i -D webpack webpack-cli 
  • webpack — сборщик модулей и ресурсов
  • webpack-cli — интерфейс командной строки для вебпака
console.log("Как интересно!") 

Отлично, у нас имеется Node.js-проект с установленными основными пакетами и файл «index.js». Займемся настройкой вебпака.

Базовая настройка

Приступим к настройке сборщика. Создаем файл «webpack.config.js» в корневой директории проекта.

Точка входа

Прежде всего, необходимо определить точку входа приложения, т.е. то, какие файлы вебпак будет компилировать. В приведенном примере мы определяем точку входа как «src/index.js»:

// webpack.config.js const path = require('path') module.exports = < entry: < main: path.resolve(__dirname, './src/index.js'), >, > 
Точка выхода

Точка выхода — это директория, в которую помещаются скомпилированные вебпаком файлы. Установим точку выхода как «dist». Префикс «[name]» соответствует названию файла в src:

// webpack.config.js module.exports = < // . output: < path: path.resolve(__dirname, './dist'), filename: '[name].bundle.js', >, > 

Минимальная настройка для сборки проекта готова. Добавляем скрипт «build» в файл «package.json», запускающий команду «webpack»:

// package.json "scripts":
yarn build // или npm run build 
asset main.bundle.js 19 bytes [emitted] [minimized] (name: main) ./src/index.js 18 bytes [built] [code generated] webpack 5.1.0 compiled successfully in 152 mss 

В директории «dist» создается файл «index.bundle.js». Файл не изменился, но мы успешно осуществили сборку проекта.

Плагины

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

Плагин создания HTML на основе шаблона

У нас есть готовая сборка, но она бесполезна без разметки, которая загрузит сборку в качестве скрипта. Поскольку мы хотим, чтобы такой HTML-файл генерировался автоматически, используем html-webpack-plugin.

  • html-webpack-plugin — создает HTML-файл на основе шаблона
yarn add -D html-webpack-plugin 

Создаем файл «template.html» в директории «src». Мы можем добавить в шаблон переменные и другую информацию. Добавим переменную «title», в остальном шаблон будет выглядеть как обычный HTML-файл с контейнером с идентификатором «root»:

Добавляем в настройки вебпака свойство «plugins», где определяем плагин, название выходного файла (index.html) и шаблон:

// webpack.config.js const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = < // . plugins: [ new HtmlWebpackPlugin(< title: 'webpack Boilerplate', template: path.resolve(__dirname, './src/template.html'), // шаблон filename: 'index.html', // название выходного файла >), ], > 

Запускаем сборку. Директория «dist» теперь содержит файл «index.html» с подключенным в нем скриптом. Круто! Если вы откроете этот файл в браузере, то увидите сообщение «Как интересно!» в консоли.

Добавим немного контента в DOM. Изменим содержимое файла «index.js» и перезапустим сборку.

// index.js // создаем элемент заголовка const heading = document.createElement('h1') heading.textContent = 'Как интересно!' // добавляем заголовок в DOM const root = document.querySelector('#root') root.append(heading) 

Перейдите в директорию «dist» и запустите сервер (для этого необходимо глобально установить http-server: yarn global add http-server или npm i -g http-server).

http-server 

В открывшейся вкладке браузера вы должны увидеть заголовок, гласящий «Как интересно!». Также обратите внимание на уменьшение размера файла.

Очистка

Установим clean-webpack-plugin, очищающий директорию «dist» при каждой сборке проекта. Это позволяет автоматически удалять старые файлы, ставшие ненужными.

  • clean-webpack-plugin — удаляет/очищает директорию сборки проекта
// webpack.config.js const HtmlWebpackPlugin = require('html=webpack-plugin') const < CleanWebpackPlugin >= require('clean-webpack-plugin') module.exports = < // . plugins: [ // . new CleanWebpackPlugin(), ], >

Модули и загрузчики

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

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

  • Компиляция новейших возможностей JavaScript в код, совместимый со всеми или большинством браузеров
  • Импорт стилей и преобразование SCSS в CSS
  • Импорт изображений и шрифтов
  • Настройка React или Vue (опционально)
Babel (JavaScript)

Babel — это инструмент, позволящий использовать будущий JavaScript сегодня.

Мы собираемся определить правило, согласно которому все файлы с расширением «js» в проекте (кроме файлов, содержащихся в директории «node_modules») будут транспилироваться с помощью babel-loader. Для работы Babel требуется несколько зависимостей:

  • babel-loader — транспиляция файлов с помощью Babel и вебпака
  • @babel/core — транспиляция ES2015+ в обратно совместимый JavaScript
  • @babel/preset-env — полезные стандартные настройки Babel
  • @babel/plugin-proposal-class-properties — пример кастомной конфигурации Babel (установка свойств экземпляров в теле класса, а не в его конструкторе)
yarn add -D babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-class-properties 
// webpack.config.js module.exports = < // . module: < rules: [ // JavaScript < test: /\.js$/, exclude: /node_modules/, use: ['babel-loader'], >, ], > > 

Если вы настраиваете TypeScript-проект, то вместо babel-loader следует использовать typescript-loader для всех JavaScript-файлов, нуждающихся в транспиляции. Вы проверяете файлы с расширением «ts» и используете ts-loader.

Итак, Babel настроен, но плагин еще нет. Вы можете убедиться в этом, добавив следующий код в начало index.js:

// index.js // создание свойства класса без конструктора class Game < name = 'Violin Charades' >const myGame = new Game() // создаем параграф const p = document.createElement('p') p.textContent = `I like $.` // создаем элемент заголовка const heading = document.createElement('h1') heading.textContent = 'Как интересно!' // добавляем параграф и заголовок в DOM const root = document.querySelector('#root') root.append(heading, p) 
ERROR in ./src/index.js Module build failed (from ./node_modules/babel-loader/lib/index.js): SyntaxError: /Users/you/webpack-tutorial/src/index.js: Support for the experimental syntax 'classProperties' isn't currently enabled (3:8): 1 | // Create a class property without a constructor 2 | class Game < >3 | name = 'Violin Charades' | ^ 4 | > 

Для того, чтобы это исправить, создаем файл «.babelrc» в корне проекта:

// .babelrc < "presets": ["@babel/preset-env"], "plugins": ["@babel/plugin-proposal-class-properties"] >

Запускаем сборку с помощью yarn build. Теперь все работает.

Изображения

Мы хотим импортировать изображения в JavaScript-файл, но JavaScript не умеет этого делать. Чтобы убедиться в этом, создаем директорию «src/images», помещаем туда изображение и пытаемся импортировать его в файле «index.js»:

// index.js import example from './images/example.png' // . 

При запуске сборки будет выброшено исключение:

ERROR in ./src/images/example.png 1:0 Module parse failed: Unexpected character '�' (1:0) 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 

Как отмечалось ранее, вебпак обладает некоторыми встроенными загрузчиками для работы со статическими файлами. Для изображений следует использовать тип «asset/resource». Обратите внимание, что речь идет именно о типе (type), а не о загрузчике (loader):

// webpack.config.js module.exports = < // . module: < rules: [ // изображения < test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource', >, ], >, > 

В директории «dist» появляется новый файл.

Шрифты и другие встраиваемые данные

Вебпак также имеет встроенный модуль для обработки некоторых встраеваемых данных, таких как шрифты и SVG. Для этого достаточно указать тип «asset/inline»:

// index.js import example from './images/example.svg' // . 
// webpack.config.js module.exports = < // . module: < rules: [ // шрифты и SVG < test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: 'asset/inline', >, ], >, > 
Стили

Использование загрузчиков стилей является необходимым условием использования строк наподобие «import ‘file.css’» в скрипте.

Многие люди используют CSS-in-JS, стилизованные компоненты (styled components) и другие инструменты, позволяющие использовать стили в JavaScript.

Порой мы можем ограничиться загрузкой одного CSS-файла. Но, возможно, вы хотите использовать PostCSS, позволяющий использовать последние возможности CSS в браузере. Или вы хотите использовать препроцессор Sass.

Я хочу использовать все три — писать код на Sass, обрабатывать его с помощью PostCSS и компилировать в CSS.

  • sass-loader — загружает SCSS и компилирует его в CSS
  • node-sass — Node Sass
  • postcss-loader — обработка CSS с помощью PostCSS
  • postcss-preset-env — полезные настройки PostCSS
  • css-loader — загрузка стилей
  • style-loader — применение стилей к элементам DOM
yarn add -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass 

Как и для Babel, для PostCSS требуется отдельный файл настроек:

// postcss.config.js module.exports = < plugins: < 'postcss-preset-env': < browsers: 'last 2 versions', >, >, > 

Для проверки работоспособности названных инструментов создадим файл «src/styles/main.scss», содержащий переменные Sass и пример использования PostCSS (lch):

// src/styles/main.css $font-size: 1rem; $font-color: lch(53 105 40); html

Импортируем этот файл в index.js и добавляем 4 загрузчика. Загрузчики используются вебпаком справа налево, так что последним должен быть sass-loader, затем PostCSS, затем CSS и, наконец, style-loader, который применяет скомпилированные стили к элементам DOM:

// index.js import './styles/main.css' // . 
// webpack.config.js module.exports = < // . module: < rules: [ // CSS, PostCSS, Sass < test: /\.(scss|css)$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'], >, ], >, > 

После сборки вы заметите, что Sass и PostCSS применились к DOM.

Обратите внимание, что мы установили настройки для режима разработки. Для продакшна следует использовать MiniCssExtractPlugin вместо style-loader, который экспортирует минифицированный CSS.

Разработка

Каждый раз набирать команду yarn build (npm run build) при необходимости повторной сборки проекта может быть утомительным. Чем больше проект, тем дольше он будет собираться. Поэтому необходимо иметь два файла настроек вебпака:

  • Настройки для продакшна, включающие минификацию, оптимизацию и удаление всех карт ресурсов (source maps)
  • Настройки для разработки, включая запуск сервера, обновление при каждом изменении и карты ресурсов

Для этого необходимо установить webpack-dev-server.

  • webpack-dev-server — это сервер для разработки
yarn add -D webpack-dev-server 

В целях демонстрации принципов использования сервера для разработки мы можем определить соответствующие настройки в файле «webpack.config.js». На практике лучше иметь два файла настроек: один с mode: production и другой с mode: development. В специально подготовленной для вас webpack 5 boilerplate я использую webpack-merge для получения базовых настроек в виде одного файла, а специальные требования содержатся в файлах «webpack.prod.js» и «webpack.dev.js».

// webpack.config.js const webpack = require('webpack') module.exports = < // . mode: 'development', devServer: < historyApiFallback: true, contentBase: path.resolve(__dirname, './dist'), open: true, compress: true, hot: true, port: 8080, >, plugins: [ // . // применять изменения только при горячей перезагрузке new webpack.HotModuleReplacementPlugin(), ], > 

Мы добавили mode: development и свойство «devServer». В данном свойстве содержится несколько стандартных настроек — номер порта (8080), автоматическое открытие браузера, использование hot-module-replacement, для которого нужен webpack.HotModuleReplacement(). Это позволит модулям обновляться без полной перезагрузки страницы, т.е. если изменятся отдельные стили, только они будут обновлены, вам не потребуется перезагружать JavaScript, что очень сильно ускоряет разработку.

Для запуска сервера используется команда «webpack serve»:

// package.json "scripts":
yarn start 

После запуска этой команды браузер откроется по адресу localhost:8080. Теперь вы можете изменять Sass и JavaScript и они будут обновляться на лету.

Заключение

Надеюсь, данная статья помогла вам начать знакомство с вебпаком. Для облегчения решения ваших повседневных задач мной разработан webpack 5 boilerplate с Babel, Sass, PostCss, оптимизацией для продакшна и сервером для разработки. Взяв его за основу, вы легко сможете настроить вебпак для работы с React, Vue или TypeScript.

  • Веб-разработка
  • JavaScript
  • Программирование

Как в webpack 5 исключить удаление некоторых файлов?

Прочел оф. доку. npm — clean-webpack-plugin github — clean-webpack-plugin Вроде это то, что надо Но это не работает. Где-то нашел свойство exclude: [] но на оф. сайте про такое не нашел ни какой информации. Подскажите как исключить удаление этих файлов .git && README.md ?

Отслеживать
задан 11 июл 2021 в 6:30
14.5k 6 6 золотых знаков 33 33 серебряных знака 70 70 бронзовых знаков

А как так вообще получлилось, что в выходной папке присутствуют эти два файла? Обычно выходная папка подразумевается быть полностью пустой.

Что такое Webpack?

Webpack — это инструмент, позволяющий скомпилировать, например, JavaScript модули в единый JS-файл. Webpack также известен как сборщик модулей.

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

Он также способен выполнять множество иных операций:

  • помогает собрать воедино ваши ресурсы
  • следит за изменениями и повторно выполняет задачи
  • может выполнить транспиляцию JavaScript следующего поколения до более старого стандарта JavaScript (ES5) с помощью Babel, что позволит использовать новейшие функции JavaScript, не беспокоясь о том, поддерживает их браузер или нет
  • может выполнить транспиляцию CoffeeScript в JavaScript
  • может конвертировать встроенные изображения в data:URI
  • позволяет использовать require() для CSS файлов
  • может запустить webpack-dev-server (в нём встроен локальный сервер и livereload (“живая перезагрузка браузера”))
  • может работать с Hot Module Replacement (замена горячего модуля)
  • может разделить выходной файл (output file) на несколько файлов, чтобы избежать медленной загрузки страницы из-за большого размера JS-файла
  • может выполнить Tree Shaking

Webpack не ограничивается одним лишь фронтендом, его также успешно применяют в бэкенд разработке на Node.js.

У Webpack есть предшественники, у которых он перенял многие идеи. Основное различие заключается в том, что те инструменты известны как task runners (такс-раннеры), в то время как Webpack ничто иное, как сборщик модулей.

Webpack — это более целенаправленный инструмент. Вам достаточно указать точку входа в ваше приложение (это может быть даже HTML-файл с тегами ), а webpack проанализирует файлы и объединит их в один выходной JavaScript-файл, содержащий все необходимое для запуска приложения.

Установка Webpack

Webpack может быть установлен глобально или локально для каждого проекта.

Глобальная установка

Глобальная установка с помощью Yarn:

yarn global add webpack webpack-cli
npm i -g webpack webpack-cli

Теперь мы можем запустить webpack:

webpack-cli

Локальная установка

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

Установка с помощью Yarn:

yarn add webpack webpack-cli -D
npm i webpack webpack-cli --save-dev

После этого добавьте эти строчки в свой package.json файл:

 < 
//.
"scripts": <
"build": "webpack"
>
>

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

yarn build

в корневом каталоге проекта.

Настройка Webpack

По умолчанию, Webpack (начиная с 4-й версии) не требует никакой настройки, если вы соблюдаете эти правила:

  • точкой входа вашего приложения является ./src/index.js
  • вывод (output) размещается в ./dist/main.js
  • Webpack работает в production mode (режим производства)

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

Точка входа

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

module.exports = /*. */ 
entry: './index.js'
/*. */
>

Вывод (output)

По умолчанию, вывод размещается в ./dist/main.js . В нижеприведенном примере, результат работы в Webpack генерируется в файле app.js :

module.exports = /*. */ 
output: path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
>
/*. */
>

С помощью Webpack можно использовать оператор import или require в своем JavaScript коде для того, чтобы подключать файлы любого типа (например, CSS).

В Webpack загрузчики являются аналогами задач (tasks) в Grunt и Gulp. Они принимают содержимое файлов, а затем преобразуют его необходимым образом и включают результат преобразования в общую сборку. Например, они могут компилировать TypeScript, загружать компоненты Vue.js и многое другое.

Например, в своем коде вы можете использовать:

import 'style.css' 

указав конфигурацию данного загрузчика в файле webpack.config.js :

module.exports = /*. */ 
module: rules: [
< test: /\.css$/, use: 'css-loader' >,
>]
>
/*. */
>

Регулярное выражение применяет данный загрузчик только к CSS файлам.

У загрузчика есть параметры:

module.exports = /*. */ 
module: rules: [
test: /\.css$/,
use: [
loader: 'css-loader',
options: modules: true
>
>
]
>
]
>
/*. */
>

Для одной и той же задачи может потребоваться несколько загрузчиков:

module.exports = /*. */ 
module: rules: [
test: /\.css$/,
use:
[
'style-loader',
'css-loader',
]
>
]
>
/*. */
>

В этом примере css-loader интерпретирует директиву import ‘style.css’ в CSS. Затем style-loader внедряет этот CSS в DOM, используя тег .

Порядок выполнения перевернут (последнее выполняется первым).

Так сколько всего существует загрузчиков? Очень много! Здесь вы сможете найти полный список.

Самым часто используемым загрузчиком является Babel — он используется для транспиляции современного JavaScript в ES5:

module.exports = /*. */ 
module: rules: [
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: loader: 'babel-loader',
options: presets: ['@babel/preset-env']
>
>
>
]
>
/*. */
>

Данный пример заставляет Babel предварительно обрабатывать все наши React/JSX файлы:

module.exports = /*. */ 
module: rules: [
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
>
]
>,
resolve: extensions: [
'.js',
'.jsx'
]
>
/*. */
>

Здесь вы можете увидеть параметры babel-loader .

Плагины

Плагины — это почти то же самое, что и загрузчики, но под стероидами. Они могут сделать то, что не могут загрузчики. Ко всему прочему, Webpack построен на системе плагинов, которые вы используете в своем файле конфигурации.

Рассмотрим следующий пример:

module.exports = /*. */ 
plugins: [
new HTMLWebpackPlugin()
]
/*. */
>

Плагин HTMLWebpackPlugin автоматически создает HTML-файл с уже подключенным скриптом.

Здесь доступно множество плагинов.

Еще один полезный плагин, CleanWebpackPlugin , мы можем использовать перед перегенерацией файлов, чтобы очистить нашу папку dist/ и получить аккуратный файл с конфигурацией.

module.exports = /*. */ 
plugins: [
new CleanWebpackPlugin(['dist']),
]
/*. */
>

Режимы Webpack

Данные режимы (появившиеся в 4-й версии Webpack) настраивают среду, в которой будет работать Webpack. Режим может быть настроен на development или production (по умолчанию стоит production ).

module.exports = entry: './index.js', 
mode: 'development',
output: path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
>
>
  • менее оптимизирован, чем production
  • работает быстрее
  • не удаляет комментарии
  • предоставляет более подробные сообщения об ошибках и способы их решения
  • сильно облегчает отладку

Режим production работает медленнее, чем development , так как ему нужно создать более оптимизированный бандл. Полученный JavaScript файл меньше по размеру, поскольку многое из режима development в нем отсутствует.

Я написал небольшое приложение, которое выводит содержимое console.log .

Вот бандл production :

Вот бандл development :

Запуск Webpack

Если Webpack установлен глобально, его можно вручную запустить из командной строки. Но, обычно, вы прописываете скрипт внутри файла package.json , который затем запускаете через npm или yarn .

Например, эти package.json скрипты, которые мы использовали ранее:

"scripts": "build": "webpack"
>

позволяют запускать webpack , набрав:

npm run build
yarn run build
yarn build

Просмотр изменений

Webpack может автоматически перестраивать бандл, когда в вашем приложении происходят изменения. Для этого добавьте данный скрипт:

"scripts": "watch": "webpack --watch"
>

и запустите данную функцию:

npm run watch
yarn run watch
yarn watch

Одной из приятных особенностей watch mode (режима просмотра) является то, что бандл изменяется только в том случае, если в сборке нет ошибок. Если ошибки присутствуют, watch продолжит следить за изменениями и будет пытаться перестраивать бандл, но текущий, рабочий бандл не зависит от проблемных бандлов.

Обработка изображений

С помощью Webpack можно очень удобно работать с изображениями, используя загрузчик file-loader .

Эта простая конфигурация:

module.exports = /*. */ 
module: rules: [
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
>
]
>
/*. */
>

Позволяет импортировать изображения в ваш JavaScript:

import Icon from './icon.png'const img = new Image()
img.src = Icon
element.appendChild(img)

Где img — это HTMLImageElement. Ознакомьтесь с документацией по Image().

file-loader может обрабатывать и другие типы ассетов, например, шрифты, CSV-файлы, XML и т.д.

Еще одним приятным инструментом для работы с изображениями является url-loader загрузчик.

В этом примере загружается любой PNG-файл размером менее 8 КБ в качестве data:URL.

module.exports = /*. */ 
module: rules: [
test: /\.png$/,
use: [
loader: 'url-loader',
options: limit: 8192
>
>
]
>
]
>
/*. */
>

Обработайте SASS код и преобразуйте его в CSS

Используйте sass-loader , css-loader и style-loader :

module.exports = /*. */ 
module: rules: [
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
>
]
>
/*. */
>

Генерация Source Maps

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

Source Maps можно сгенерировать, используя свойство конфигурации devtool :

module.exports = /*. */ 
devtool: 'inline-source-map',
/*. */
>

devtool имеет множество возможных значений, из которых наиболее часто используемые:

  • none : не добавляет Source Maps
  • source-map : идеально подходит для режима production , предоставляет отдельную Source Map, которую можно свернуть и добавляет ссылку в бандл, чтобы инструменты разработки знали о том, что Source Map доступна
  • inline-source-map : идеально подходит для режима development , встраивает Source Maps в качестве data:URL

Webpack. Начало работы, часть 1 из 2

По большей части, сайты больше не пишутся на чистом HTML с небольшим количеством JavaScript — часто они создаются только с помощью JavaScript. Поэтому возникает необходимость в сборке, минификации и транспиляции кода. Вот здесь webpack и приходит на помощь разработчику.

Вебпак — это сборщик модулей. Он служит для упаковки кода для дальнейшего использования браузером. Позволяет использовать последние возможности JavaScript с помощью Babel или использовать TypeScript и преобразовывать его в кроссбраузерный минифицированный код. Он также позволяет импортировать статические ресурсы в JavaScript.

Для разработчиков webpack также предоставляет сервер для разработки, который умеет обновлять модули и стили на лету при сохранении файла. Инструменты командной строки, такие как «vue create» и «create-react-app» используют вебпак за сценой, но можно создать собственную настройку webpack для указанных фреймворков.

Создание проекта

Создаем директорию проекта и инициализируем его:

$ mkdir webpack-config-example $ cd webpack-config-example $ npm init -y

Немного подредактируем файл package.json :

 "name": "webpack-config-example", "version": "1.0.0", "description": "Webpack config file example", "private": true, "scripts":  "build": "webpack" >, "keywords": ["webpack", "config", "javascript", "frontend"], "author": "Evgeniy Tokmakov", "license": "ISC" >

Устанавливаем два пакета как зависимости для разработки:

$ npm install webpack webpack-cli --save-dev

Создаем директорию src , а внутри нее — директории js , css , img , font , data . Внутри src/js создаем файл index.js .

console.log('Webpack config file example')

Создаем файл webpack.config.js в корневой директории проекта. Файл экспортирует объект, который содержит все настройки сборщика.

module.exports = >

Точка входа

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

const path = require('path') module.exports =  entry:  main: path.resolve(__dirname, 'src/js/index.js'), >, >
const path = require('path') module.exports =  // для одной точки входа код можно сократить entry: path.resolve(__dirname, 'src/js/index.js'), >

Точка выхода

Точка выхода — это директория, в которую помещаются сформированные вебпаком файлы.

const path = require('path') module.exports =  entry:  main: path.resolve(__dirname, 'src/js/index.js'), >, output:  path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', >, >

Значение по умолчанию точки входа — ./src/index.js , значение по умолчанию точки выхода — ./dist/main.js .

Когда есть несколько точек входа, то файл dist/bundle.js будет перезаписан, потому что имя одинаковое. В этом случае можно использовать шаблон, чтобы использовать ключ объекта entry в имени выходного файла.

module.exports =  entry:  app: '. ', admin: '. ', >, output:  filename: '[name].bundle.js', path: __dirname + '/dist', >, > // выходные файлы ./dist/app.js и ./dist/admin.js

В принципе, минимальная конфигурация готова, так что можно запустить сборку:

$ npm run build

Мы получим предупреждение, что не установлен режим — development или production .

module.exports =  mode: 'development', /* . */ >

Наблюдение за файлами

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

module.exports =  mode: 'development', watch: true, watchOptions:  ignored: /node_modules/, // не отслеживать node_modules poll: 1000, // проверять изменения каждую секунду >, /* . */ >

Чаще всего нет необходимости в использовании опции watchOptions.poll для наблюдения за файлами. Эта опция помогает решить проблемы с наблюдением при спользовании NFS, VirtualBox и Docker.

Плагины

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

1. Плагин html-webpack-plugin

У нас есть готовая сборка, но она бесполезна без html-разметки, которая загрузит сборку в качестве скрипта. Поскольку нам нужно, чтобы такой html-файл генерировался автоматически, используем плагин html-webpack-plugin .

$ npm install html-webpack-plugin --save-dev

Создаем файл фаблона index.html в директории src . В шаблон добавляем две переменные, которые определим в настройках плагина.

 lang="ru"> charset="UTF-8"> http-equiv="X-UA-Compatible" content="IE=edge"> name="viewport" content="width=device-width, initial-scale=1.0">  htmlWebpackPlugin.options.title %>     htmlWebpackPlugin.options.title %>   htmlWebpackPlugin.options.content %>   
const path = require('path') const fs = require('fs') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports =  mode: 'development', entry:  main: path.resolve(__dirname, 'src/js/index.js'), >, output:  path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js', >, plugins: [ new HtmlWebpackPlugin( title: 'Webpack config example', content: fs.readFileSync('webpack.config.js', 'utf8'), template: path.resolve(__dirname, 'src/index.html'), // файл шаблона filename: 'index.html', // выходной файл >), ], >

Запускаем сборку. Директория dist теперь содержит файл index.html с подключенным в нем скриптом main.bundle.js и подставленными значениями переменных.

2. Плагин clean-webpack-plugin

Установим clean-webpack-plugin , очищающий директорию dist при каждой сборке проекта. Это позволяет автоматически удалять старые файлы, ставшие ненужными.

$ npm install clean-webpack-plugin --save-dev
/* . */ const  CleanWebpackPlugin > = require('clean-webpack-plugin') module.exports =  /* . */ plugins: [ /* . */ new CleanWebpackPlugin(), ], >

Но этот плагин уже устарел, потому что вебпак сам умеет очищать директорию dist с помощью опции output.clean :

module.exports =  /* . */ output:  path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js', clean: true, >, /* . */ >

3. Плагин copy-webpack-plugin

Копирует отдельные файлы и целые директории, которые уже существуют, в выходную директорию проекта. Давайте разместим в директории src иконку favicon.png , добавим в html-шаблон ссылку на эту иконку, и скопируем файл при сборке в директорию dist .

$ npm install copy-webpack-plugin --save-dev
/* . */ const  CleanWebpackPlugin > = require('clean-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports =  /* . */ plugins: [ /* . */ new CleanWebpackPlugin(), new CopyWebpackPlugin( patterns: [  from: path.resolve(__dirname, 'src/favicon.png'), to: path.resolve(__dirname, 'dist') >, ], >), ], >
 lang="ru"> charset="UTF-8"> http-equiv="X-UA-Compatible" content="IE=edge"> name="viewport" content="width=device-width, initial-scale=1.0">  htmlWebpackPlugin.options.title %>  rel="icon" href="favicon.png" type="image/png">    htmlWebpackPlugin.options.title %>   htmlWebpackPlugin.options.content %>   

Модули и загрузчики

По умолчанию, при создании графа зависимостей на основе import или require , вебпак способен обрабатывать только javascript и json файлы. Для работы с css-стилями, изображениями, шрифтами — предназначены модули и загрузчики. Загрузчики описывают, как обрабатывать те файлы, с которыми webpack не умеет работать — и включать их в конечную сборку.

1. Загрузчик raw-loader

Позволяет импортировать файл как строку. Давайте создадим файл src/data/webpack.txt и запишем в него строку «Это пример файла конфигурации Webpack». Установим загрузчик raw-loader , пропишем его в файле конфигурации, потом в файле src/js/index.js импортируем файл как строку и покажем на странице.

$ npm install raw-loader --save-dev
module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст use: 'raw-loader', type: 'javascript/auto' >, ], > >
import data from '../data/webpack.txt' document.body.insertAdjacentHTML('beforeend', `

$

`
)

Обратите внимание на type в значении javascript/auto — в пятой версии Webpack нет необходимости использовать внешние загрузчики raw-loader , file-loader , url-loader . При использовании этих устаревших загрузчиков нужно установить type в значение javascript/auto , чтобы избежать повторной обработки встроенными загрузчиками вебпака.

И давайте посмотрим, как импортировать строку с использованием встроенного загрузчика, без установки raw-loader :

module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >, ], > >

2. Загрузчик file-loader

Позволяет импортировать файл (возвращая URL этого файла) и отправляет этот файл в выходной каталог. Давайте поместим файл логотипа logo.png в директории src/img , установим загрузчик file-loader , пропишем его в файле конфигурации, а потом покажем изображение на странице.

$ npm install file-loader --save-dev
module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >,  test: /\.(png|jpe?g|gif|webp)$/i, // изображение use: [  loader: 'file-loader', options:  outputPath: 'img' // все изображения в dist/img >, >, ], type: 'javascript/auto' >, ], > >
import data from '../data/webpack.txt' import logo from '../img/logo.png' document.body.insertAdjacentHTML('beforeend', `

$

`
) document.body.insertAdjacentHTML('afterbegin', `$ " alt="">`)

И давайте посмотрим, как импортировать строку с использованием встроенного загрузчика, без установки file-loader :

module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >,  test: /\.(png|jpe?g|gif|webp)$/i, // изображение type: 'asset/resource', generator:  filename: 'img/[hash][ext][query]' > >, ], > >

3. Загрузчик url-loader

Загрузчик url-loader работает как file-loader , но может возвращать DataURL вместо URL , если размер файла меньше заданного ограничения в байтах. Давайте поместим маленькое изображение icon.png в директорию src/img , установим загрузчик url-loader , пропишем его в файле конфигурации, а потом покажем это изображение на странице.

module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >,  test: /\.(png|jpe?g|gif|webp)$/i, // изображение use: [  loader: 'url-loader', options:  limit: 8192, outputPath: 'img', // все изображения в dist/img >, >, ], type: 'javascript/auto' >, ], > >
import data from '../data/webpack.txt' import logo from '../img/logo.png' import icon from '../img/icon.png' document.body.insertAdjacentHTML('beforeend', `

$

`
) document.body.insertAdjacentHTML('afterbegin', `$ " alt="">`) document.body.insertAdjacentHTML('beforeend', `$ " alt="">`)

Загрузчик file-loader больше не нужен, поскольку его работу теперь выполняет url-loader . В результате на странице у нас будут два изображения:

src="/img/56ee55657feb4c5d509da1359ac4a419.png" alt=""> . src="data:image/png;base64,iVBORw0KGgoAAAAN. " alt="">

И давайте посмотрим, как импортировать изображение с использованием встроенного загрузчика, без установки url-loader :

module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >,  test: /\.(png|jpe?g|gif|webp)$/i, // изображение type: 'asset', generator:  filename: 'img/[hash][ext][query]' > >, ], > >
src="/img/56ee55657feb4c5d509d.png" alt=""> . src="data:image/png;base64,iVBORw…" alt="">

При использовании asset , если размер файла больше 8кб, то применяется asset/resource (изображение в директории dist/img ), в противном случае — asset/inline (изображение в атрибуте src=»https://tokmakov.msk.ru/blog/item/%E2%80%A6″ ). Ограничение на размер файла можно задать самому, если значение по умолчанию не подходит.

module.exports =  /* . */ module:  rules: [  test: /\.txt$/i, // простой текст type: 'asset/source' >,  test: /\.(png|jpe?g|gif|webp)$/i, // изображение type: 'asset', generator:  filename: 'img/[hash][ext][query]' > parser:  dataUrlCondition:  maxSize: 4096 // ограничение 4kb > > >, ], > >
src="/img/56ee55657feb4c5d509d.png" alt=""> . src="/img/cb1ea424ee012d4721cf.png" alt="">

Если использовать встроенный загрузчик asset/inline — то все изображения будут DataURL , но это не слишком удачное решение.

4. Загрузчики style-loader и css-loader

Загрузчик css-loader позволяет импортировать css-файл, а загрузчик style-loader динамически добавляет в выходной html-файл тег . Давайте установим эти два загрузчика, пропишем их в файле конфигурации, создадим css-файл style.css в директории src/css и импортируем стили в файле src/js/index.js .

$ npm install css-loader --save-dev
$ npm install style-loader --save-dev
body
module.exports =  /* . */ module:  rules: [ /* . */  test: /\.css$/, // файл css-стилей use: ['style-loader', 'css-loader'] > ], > >
import data from '../data/webpack.txt' import logo from '../img/logo.png' import icon from '../img/icon.png' import '../css/style.css' document.body.insertAdjacentHTML('beforeend', `

$

`
) document.body.insertAdjacentHTML('afterbegin', `$ " alt="">`) document.body.insertAdjacentHTML('beforeend', `$ " alt="">`)

5. Загрузчик postcss-loader

Загрузчик postcss-loader использует процессор PostCSS для трансформации css-стилей. Сам PostCSS никаких трансформаций не делает, только создает из css-стилей js-объекты, а потом из js-объектов — обратно css-стили. Трансформацией занимаются плагины для PostCSS — в момент, когда созданы js-объекты из входных стилей, но до момента, когда еще не созданы выходные стили. Трансформации могут быть самые разные, например — добавление префиксов к css-правилам с помощью плагина autoprefixer .

Устанавливаем postcss-loader и postcss-preset-env (полезные настройки для процессора postcss):

$ npm install postcss-loader postcss-preset-env --save-dev
module.exports =  /* . */ module:  rules: [ /* . */  test: /\.css$/, // файл css-стилей use: [ 'style-loader', 'css-loader',  loader: 'postcss-loader', options:  postcssOptions:  plugins:  'postcss-preset-env':  browsers: 'last 3 versions', >, >, >, >, >, ], >, ], > >
/* входные стили */ body
/* выходные стили */ body
  • Webpack. Начало работы, часть 2 из 2
  • Расширение «ESLint» для VS Code, часть 2 из 2
  • Расширение «ESLint» для VS Code, часть 1 из 2
  • Расширение «Prettier — Code formatter» для VS Code
  • Магазин на JavaScript, часть 19 из 19. Редактирование характеристик и рефакторинг приложения
  • Магазин на JavaScript, часть 18 из 19. Панель управления: редактирование категорий и брендов
  • Магазин на JavaScript, часть 17 из 19. Панель управления: список заказов, категорий и брендов

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *