To v5 from v4

Настройка Webpack с помощью файла webpack.config.js

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

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

Если в файле конфигурации изменить путь вывода на что-то вроде  , то при повторном выполнении команды пакетный файл будет помещён в  (Commit 5).

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

Загрузчик, который будет использоваться далее, — это Babel. Если вы не использовали его раньше, Babel — это инструмент, который берёт код JS, использующий современные функции, и преобразует его в эквивалент, совместимый со старыми версиями JavaScript. Это позволяет вашему приложению работать в старых браузерах или в браузерах, которые ещё не поддерживают некоторые новые функции JavaScript. В конце концов, некоторые ленивцы не обновляли свои браузеры с 2009 года. Некоторая часть написанного кода не будет работать в браузере 2009 года:

Здесь используется стрелочная функция и старые браузеры её не воспринимают. Поэтому используем загрузчик и отправим эту функцию в прошлое. Для начала выполним следующее:

Затем в файле добавим следующий код в :

Этот код добавит новое правило в ваш Webpack. Если в дереве зависимостей Webpack встречает файл, который заканчивается на (например, ), и этот файл отсутствует в папке (например, jQuery), то к этому файлу применяется данное правило.

Любой файл, который соответствует этому правилу, проходит через все загрузчики в блоке (в данном случае только через загрузчик babel). Таким образом, файлы и пройдут через загрузчик, что приведёт к удалению стрелочной функции в , а затем Webpack продолжит свой путь сборки. Тем временем, как только Webpack встречает jQuery, он просто загружает этот код как он есть без загрузчиков, поскольку jQuery находится в каталоге .

Теперь, если выполнить и посмотреть исходный код в , фрагмент, соответствующий вашей функции сортировки, использует ключевое слово , а не стрелочную функцию (Commit 6).

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

Обратите внимание на то, как выше мы используем стрелочную функцию, а ниже присутствует уже знакомое браузеру 2009 года ключевое слово

Теперь приложение готово к работе на устаревших браузерах. Чтобы этот код был поддерживаемым, следует написать несколько тестов для него.

optimize

Npm

Note that all plugins under namespace should only be used when set to . Otherwise you might get into trouble where plugins are applied twice.

LimitChunkCountPlugin

Merge chunks limit chunk count is lower than .

The overhead for each chunks is provided by or defaults to 10000. Entry chunks sizes are multiplied by (or 10).

Chunks that reduce the total size the most are merged first. If multiple combinations are equal the minimal merged size wins.

RealContentHashPlugin

When option is enabled, webpack will apply to compiler internally.

Hook

provides a 5.8.0+ hook for customizing hash updating:

iAziz786 EugeneHlushko ooflorent Legends chenxsan

Dynamic Imports

Two similar techniques are supported by webpack when it comes to dynamic code splitting. The first and recommended approach is to use the that conforms to the ECMAScript proposal for dynamic imports. The legacy, webpack-specific approach is to use . Let’s try using the first of these two approaches…

Before we start, let’s remove the extra and from our configuration in the above example as they won’t be needed for this next demonstration:

webpack.config.js

We’ll also update our project to remove the now unused files:

project

Now, instead of statically importing , we’ll use dynamic importing to separate a chunk:

src/index.js

The reason we need is that since webpack 4, when importing a CommonJS module, the import will no longer resolve to the value of , it will instead create an artificial namespace object for the CommonJS module. For more information on the reason behind this, read webpack 4: import() and CommonJs.

Let’s run webpack to see separated out to a separate bundle:

As returns a promise, it can be used with functions. Here’s how it would simplify the code:

src/index.js

Rule.enforce

Possible values:

Specifies the category of the loader. No value means normal loader.

There is also an additional category «inlined loader» which are loaders applied inline of the import/require.

There are two phases that all loaders enter one after the other:

  1. Pitching phase: the pitch method on loaders is called in the order . See for details.
  2. Normal phase: the normal method on loaders is executed in the order . Transformation on the source code of a module happens in this phase.

All normal loaders can be omitted (overridden) by prefixing in the request.

All normal and pre loaders can be omitted (overridden) by prefixing in the request.

All normal, post and pre loaders can be omitted (overridden) by prefixing in the request.

Inline loaders and prefixes should not be used as they are non-standard. They may be used by loader generated code.

Что такое 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-файл с тегами <script>), а webpack проанализирует файлы и объединит их в один выходной JavaScript-файл, содержащий все необходимое для запуска приложения.

Shimming Globals

Let’s start with the first use case of shimming global variables. Before we do anything let’s take another look at our project:

project

Remember that package we were using? For demonstration purposes, let’s say we wanted to instead provide this as a global throughout our application. To do this, we can use .

The makes a package available as a variable in every module compiled through webpack. If webpack sees that variable used, it will include the given package in the final bundle. Let’s go ahead by removing the statement for and instead provide it via the plugin:

src/index.js

webpack.config.js

What we’ve essentially done here is tell webpack…

If we run a build, we should still see the same output:

We can also use the to expose a single export of a module by configuring it with an «array path» (e.g. ). So let’s imagine we only wanted to provide the method from wherever it’s invoked:

src/index.js

webpack.config.js

This would go nicely with Tree Shaking as the rest of the library should get dropped.

output

JsonpTemplatePlugin

Chunks are wrapped into JSONP-calls. A loading algorithm is included in entry chunks. It loads chunks by adding a tag.

are the output options.

is the JSONP function.

is used as path for loading the chunks.

is the filename under that chunks are expected.

NodeTemplatePlugin

Chunks are wrapped into Node.js modules exporting the bundled modules. The entry chunks loads chunks by requiring them.

are the output options.

is the filename under that chunks are expected.

Chunks are loaded by . Else it’s similar to .

are the output options.

SourceMapDevToolPlugin

Decorates the templates by generating a SourceMap for each chunk.

the filename template of the SourceMap. , , , and are replaced. If this argument is missing, the SourceMap will be inlined as DataUrl.

HotModuleReplacementPlugin

Add support for hot module replacement. Decorates the templates to add runtime code. Adds API.

the filename for hot update chunks.

the filename for the hot update manifest.

JSON function name for the hot update.

Modules

The and statements have been standardized in ES2015. They are supported in most of the browsers at this moment, however there are some browsers that don’t recognize the new syntax. But don’t worry, webpack does support them out of the box.

Behind the scenes, webpack actually «transpiles» the code so that older browsers can also run it. If you inspect , you might be able to see how webpack does this, it’s quite ingenious! Besides and , webpack supports various other module syntaxes as well, see Module API for more information.

Note that webpack will not alter any code other than and statements. If you are using other ES2015 features, make sure to such as Babel or Bublé via webpack’s loader system.

Options

Name Type Default Description
Include all assets that pass test assertion
Include all assets matching any of these conditions
Exclude all assets matching any of these conditions
The compression algorithm/function
maximum available compression level, for gzip: Compression options for
Only assets bigger than this size are processed (in bytes)
Only assets that compress better than this ratio are processed ()
The target asset filename
Whether to delete the original assets or not

Type: Default:

Include all assets that pass test assertion.

webpack.config.js

Type: Default:

Include all assets matching any of these conditions.

webpack.config.js

Type: Default:

Exclude all assets matching any of these conditions.

webpack.config.js

Type: Default:

The compression algorithm/function.

The algorithm is taken from zlib.

webpack.config.js

Allow to specify a custom compression function.

webpack.config.js

Type: Default:

Compression options for .

You can find all options here .

webpack.config.js

Type: Default:

Only assets bigger than this size are processed. In bytes.

webpack.config.js

Type: Default:

Only assets that compress better than this ratio are processed (). Example: you have file with 1024b size, compressed version of file has 768b size, so equal . In other words assets will be processed when the value less value.

You can use value to process assets that are smaller than the original.

Use a value of to process all assets even if they are larger than the original size or their original size is bytes (useful when you are pre-zipping all assets for AWS).

Use a value of to process all assets even if they are larger than the original size, excluding assets with their original size is bytes.

webpack.config.js

Type: Default:

The target asset filename.

For example we have :

is replaced with the directories to the original asset, included trailing ().

is replaced with the path of original asset ().

is replaced with the base ( + ) of the original asset ().

is replaced with the name of the original asset ().

is replaced with the extension of the original asset, included ().

is replaced with the query of the original asset, included ().

is replaced with the fragment (in the concept of URL it is called ) of the original asset ().

webpack.config.js

webpack.config.js

Type: Default:

Whether to delete the original assets or not.

webpack.config.js

To exclude sourcemaps from compression

Changes to internals

The changes to webpack internals such as: adding types, refactoring code and methods renaming are listed here for anyone interested. But they are not intended as a part of common use-case migration.

Module.nameForCondition, Module.updateCacheModule and Module.chunkCondition are no longer optional.

getOptions method for Loaders

webpack 5 ships with built-in method available in loader context. This is a breaking change for loaders that had been using method from previously preferred schema-utils:

  • is available since webpack 5
  • Instead of JSON5 it supports JSON as a query string: → . Using JSON5 should be considered and documented as deprecated in favor of JSON in the respective Loader’s documentation.
  • has specific behavior for parsing query strings (, and won’t be parsed as but as a primitive value). This is no longer the case for the new built-in method, which uses native parsing (ships with Node.js). It is still possible to add custom behavior for these cases in the Loader’s code after getting the options by using method.
  • Schema argument is optional for the new method, but we strongly advise to add schema validation for your Loader’s options. The field in the schema, can be used to customize the validation error message e.g. will result in displaying errors this way:

Запуск Webpack при помощи npm-скриптов

Запускать Webpack мы будем при помощи так называемых npm-скриптов — это стандартная рекомендованная практика. При чём в нашем случае мы вместо npm будет пользоваться Yarn. Надеюсь, вы уже освоили этот пакетный менеджер. Если нет — посмотрите соответствующее видео на лофтскул.

PHP

{
«scripts»: {
«start»: «webpack»
},
«devDependencies»: {
«webpack»: «^2.2.1»
}
}

1
2
3
4
5
6
7
8

{

«scripts»{

«start»»webpack»

},

«devDependencies»{

«webpack»»^2.2.1»

}
}

Npm-скрипты работают очень просто. В блоке scripts файла package.json мы пишем в формате «ключ» — «значение» слева — название скрипта (оно может быть любое, на наш вкус), а справа то, что должно быть запущено.

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

PHP

yarn run start

1 yarn run start

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

Introduction

webpack is a bundler for modules. The main purpose is to bundle JavaScript
files for usage in a browser, yet it is also capable of transforming, bundling,
or packaging just about any resource or asset.

TL;DR

  • Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
  • Dependencies are resolved during compilation, reducing the runtime size.
  • Loaders can preprocess files while compiling, e.g. TypeScript to JavaScript, Handlebars strings to compiled functions, images to Base64, etc.
  • Highly modular plugin system to do whatever else your application requires.

Работа со скриптами

Мы рассмотрим, как перенести ES6 в ES5-совместимый код, который работает во всех браузерах. Начнем с выполнения приведенной ниже команды:

npm run dev -- --devtools false

Затем откроем файл main.bundle.js:

/***/ "./src/component.js":
/*!**************************!*
  !*** ./src/component.js ***!
  **************************/
/*! обеспечение экспорта: по умолчанию */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* экспорт по умолчанию */ __webpack_exports__ = ((text = "Hello webpack") => {
  const element = document.createElement("p");

  element.innerHTML = text;

  return element;
});

/***/ })

Современные функции из стандарта JavaScript ES6 (стрелочная функция и объявление const) из модуля component.js по умолчанию не преобразованы в ES5-совместимый код. Чтобы код работал в более старых браузерах, необходимо добавить загрузчик Babel:

npm install babel-loader @babel/core @babel/preset-env --save-dev

Затем в файле webpack.config.js добавьте module после свойства output:

module: {
  rules: [
    {
      test: /.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
},

При определении правил для загрузчика webpack нужно установить три основных свойства:

  • test – описывает, какие файлы следует трансформировать.
  • exlude – определяет, какие файлы из загрузчика не следует обрабатывать.
  • use – указывает, какой загрузчик следует использовать для сопоставленных модулей.

Еще раз введите приведенную ниже команду:

npm run dev -- --devtools false

На этот раз код в файле main.bundle.js компилируется в следующий:

/***/ "./src/component.js":
/*!**************************!*
  !*** ./src/component.js ***!
  **************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* экспорт по умолчанию */ __webpack_exports__ = (function () {
  var text = arguments.length > 0 && arguments !== undefined ? arguments : "Hello webpack";
  var element = document.createElement("p");
  element.innerHTML = text;
  return element;
});

/***/ })

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

Specify the Mode

Many libraries will key off the variable to determine what should be included in the library. For example, when is not set to some libraries may add additional logging and testing to make debugging easier. However, with set to they might drop or add significant portions of code to optimize how things run for your actual users. Since webpack v4, specifying automatically configures for you:

webpack.prod.js

If you’re using a library like , you should actually see a significant drop in bundle size after adding . Also, note that any of our local code can key off of this as well, so the following check would be valid:

src/index.js

Добавление тестовых сценариев в сборку

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

Затем создайте новый каталог и новый файл , содержащий следующий фрагмент:

Теперь у вас есть тестовые сценарии для функций и , устанавливающие, что вычисляет формулу расстояния, а сортирует массивы координат с помощью формулы расстояния, используя наборы тестов Mocha и установки Chai. Довольно стандартная тестовая настройка.

Однако, если выполнить , будет ошибка «Код JavaScript недопустим», потому что он содержит ключевое слово , которое Node в данный момент не поддерживает. Но что если обойти это ограничение, используя Webpack для управления зависимостями тестового кода?

Прим.: это можно легко исправить, просто используя вместо в тестовых файлах. Но тестовый код также будет проходить через процесс сборки, если вы тестируете JavaScript-код типа Flow, который использует аннотации, или веб-приложения Vue.js, которые используют файлы . Все они должны быть преобразованы в обычный JavaScript.

Список тестовых инструкций:

  1. Webpack строит граф зависимостей, начинающийся с тестовых файлов, а не с файлов приложения.
  2. Webpack создаёт файл JavaScript, содержащий весь тестовый код и его зависимости без ключевого слова .
  3. Выполняются тесты, запуская Mocha для этого JavaScript-файла.

Всё это будет выглядеть следующим образом:

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

Давайте разберёмся, что этот код делает. В строке 4 есть оператор , который  выполняется, если системная переменная имеет непустое значение. Так что, если вы выполните , то вам придётся вводить оператор , но это не потребуется, если просто выполнить .

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

Новая точка входа и выходной путь передаются в объект , затем запускается Webpack для создания тестовой сборки. Конфигурация Webpack представляет собой обычный код JavaScript, поэтому можно использовать стандартную библиотеку Node и операторы для её настройки. Если выполнить , то можно увидеть каталог . А если запустить , то можно увидеть, как выполняются ваши тесты.

Наконец, в разделе вашего добавьте следующую строку:

Это означает, что когда вы выполняете , создаётся каталог (каталог сборки тестирования) с помощью Webpack, затем запускается Mocha для этой сборки, и, наконец, код удаляет каталог , поскольку он больше не используется (Commit 7).

Webpack 2.2.1

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

Будьте осторожны при просмотре видеоуроков и прочтении статей, посвященных первой версии Webpack. Техники, описанные в них, могут быть не только устаревшими, но и ошибочными (применительно ко второй версии Webpack).

Несовместимость

Некоторые плагины Webpack могут быть полностью или частично несовместимы с Webpack 2. Некоторые — с node.js_7. Внимательно читайте документацию!

ES6-модули в Webpack 2

В Webpack 2 встроена поддержка ES6-модулей. Поэтому если мы используем babel, нужно его предупредить, что ES6-модули Webpack не нужно переделывать в CommonJS.

PHP

{
presets:
]
}

1
2
3
4
5

{

presets

«es2015»,{«modules»false}

}

На этом первый видеоурок курса по изучению Webpack 2 завершится.

Приятного всем просмотра! Учитесь с удовольствием!

ツПолезные ссылки к видеоуроку:
Исходники на GitHub
Видеоурок по Yarn
Получить профессию «Веб-разработчик»
Прокачаться на «Продвинутом курсе по веб-разработке»
Подписывайтесь на канал, новые видео выходят каждую неделю.

Loading Data

Another useful asset that can be loaded is data, like JSON files, CSVs, TSVs, and XML. Support for JSON is actually built-in, similar to NodeJS, meaning will work by default. To import CSVs, TSVs, and XML you could use the csv-loader and xml-loader. Let’s handle loading all three:

webpack.config.js

Add some data files to your project:

project

src/data.xml

src/data.csv

Now you can any one of those four types of data (JSON, CSV, TSV, XML) and the variable you import, will contain parsed JSON for consumption:

src/index.js

Re-run the command and open . If you look at the console in your developer tools, you should be able to see your imported data being logged to the console!

Customize parser of JSON modules

It’s possible to import any , or files as a JSON module by using a instead of a specific webpack loader.

Let’s say you have a , a and a files under folder:

src/data.toml

src/data.yaml

src/data.json5

Install , and packages first:

And configure them in your webpack configuration:

webpack.config.js

src/index.js

Re-run the command and open . You should be able to see your imported data being logged to the console!

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

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