Новая функция, поддерживаемая webpack4, — это нулевая конфигурация, которую можно запаковать без конфига, что очень заманчиво для ленивых больных раком, но это также означает, что мы не знаем, что случилось с нулевой конфигурацией, и мы не знаем упакованных файлов. соответствует нашим намерениям, все они упакованы по буддийской системе. Однако, как мать и отец проекта, вы по-прежнему несете ответственность за своих детей, и каждый процесс упаковки должен быть контролируемым. В этой статье подробно объясняется, что происходит с упаковкой webpack в разных режимах.
Давайте посмотрим на параметр MODE, который имеет три параметра.production
,development
,none
, первые два - это плагины с пресетами, а последний - ничего, то есть настроен наnone
Если это так, веб-пакет выглядит так, как он выглядит в начале, без каких-либо предустановок, и его необходимо настроить с нуля.
В конфигурации вебпака другие конфигурации могут отсутствовать! Но мод нужен, если не добавить мод, хотя официальный пакет будет запакован, он тоже выдаст предупреждение:
WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: Веб-пакет. Просто .org/concepts/mo…
Смысл очень простой, то есть если режим не установлен, система выдаст вам дефолтныйproduction
модель.
Конфигурация режима очень проста, есть только 3 значения, которые вы можете выбрать.none
Этот параметр, думаю, всем понятен, далее будем изучать два другихproduction
а такжеdevelopment
, почему существуют эти два состояния, и что они оба делают в упаковке webpack.
Как отличить в упаковкеproduction
а такжеdevelopment
положение дел
в режиме какproduction
илиdevelopment
В состоянии, чтобы учесть работу программы в двух состояниях, webpack создает глобальную переменнуюprocess.env.NODE_ENV
, что эквивалентно добавлению в плагин pluginsnew webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development|production") })
, используется для различения различных состояний и может различать состояния программы в программе.
Итак, как мы различаем при кодировании? потому чтоprocess.env.NODE_ENV
является глобальным изменением, поэтому вы можете ссылаться на это значение, предполагая, чтоmode:production
:
if ("development" === process.env.NODE_ENV){
....
}else{
....
}
После компиляции:
if ("development" === "production"){
....
}else{
....
}
То есть в итоге process.env.NODE_ENV будет заменен на константу. Эта небольшая функция может помочь нам отличить онлайн-версию от версии для разработки при написании бизнес-JS.
none
Упаковка модулей в режиме
Без какой-либо оптимизации, а как быть с модулями, упакованными webpack по умолчанию? Ниже приведен простой пример, мы видим, что он упаковывает модуль в массив, при вызове модуля он напрямую вызывает серийный номер модуля в этом массиве. Тогда нет такой оптимизации, как сжатие и обфускация, и даже комментарии помогают нам хорошо нацеливаться, например importing /* импорт гармонии/, /экспорт гармонии по умолчанию */.
[
/* 0 */
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _page2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
console.log(_page2_js__WEBPACK_IMPORTED_MODULE_0__["default"])
}),
/* 1 */
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
let str="page1"
/* harmony default export */ __webpack_exports__["default"] = (str);
})
]
Однако, будь то в среде разработки или в формальной среде производства, этого кода недостаточно, для среды разработки читабельность этого кода слишком плохая, а для формальной среды код недостаточно лаконичен. Таким образом, чтобы сократить некоторые повторяющиеся операции, разработка|производство, предоставляемая webpack4, может в значительной степени помочь нам сделать многое, что нам нужно сделать, так это добавить функции на основе этих вещей.
В режиме разработки webpack выполняет упаковку.
development
Он сообщает программе, что я сейчас нахожусь в состоянии разработки, то есть упакованный контент должен быть дружественным к разработке. В этом режиме выполняются следующие плагины и больше ничего не делается, поэтому эти плагины можно не использовать.
// webpack.development.config.js
module.exports = {
+ mode: 'development'
- devtool: 'eval',
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.NamedChunksPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}
Давайте посмотримNamedModulesPlugin
а такжеNamedChunksPlugin
Что делают эти два плагина?Изначально наш веб-пакет не добавлял имя упакованным модулям.Как правило, он основан на серийном номере, начиная с 0, и затем загружая первые несколько модулей. Машине это не важно, поиск загружается быстро, но для человеческого мозга это катастрофа, поэтому в это время добавляйте названия каждому модулю, чтобы облегчить поиск при разработке.
нетNamedModulesPlugin
, модуль представляет собой массив, и ссылки также указываются в порядке в массиве.Добавление или вычитание модулей приведет к изменению серийного номера, что по умолчанию является случаем упаковки веб-пакета, см. предыдущий раздел.
имеютNamedModulesPlugin
, все модули имеют имена, и все они являются уникальными ключами.Независимо от того, сколько модулей добавляется или вычитается, ключи модулей фиксированы.
{
"./src/index.js": (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
var _page2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/page2.js");
console.log(_page2_js__WEBPACK_IMPORTED_MODULE_0__["default"])
}),
"./src/page2.js": (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
let str="page1"
__webpack_exports__["default"] = (str);
})
}
КромеNamedModulesPlugin
, есть еще одинNamedChunksPlugin
, это чтобы назвать каждый сконфигурированный чанк, исходные чанки также являются массивами без имен.
Asset Size Chunks Chunk Names
index.js 4.04 KiB 0 [emitted] index
page2.js 3.75 KiB 1 [emitted] page2
Asset Size Chunks Chunk Names
index.js 4.1 KiB index [emitted] index
page1.js 4.15 KiB page1 [emitted] page1
NamedChunksPlugin
На самом деле, он предоставляет функцию, с помощью которой вы можете настроить имена чанков.Что делать, если у меня есть одно и то же имя чанка в разных пакетах? В настоящее время необходимо различать, что мы можем использовать все имена зависимых модулей, чтобы добавить имя модуля в эту книгу. потому чтоChunk.modules
Устарело, теперь заменено другими методамиchunk.mapModules
, а затем переименуйте фрагмент:
new webpack.NamedChunksPlugin((chunk) => {
return chunk.mapModules(m => {
return path.relative(m.context, m.request)
}).join("_")
}),
Взглянув на эффект от выполнения этой строки кода, мы увидим, что чанки были переименованы, что может во многом решить проблему с одинаковыми именами чанков:
Asset Size Chunks Chunk Names
index.js 4.1 KiB index.js_page2.js [emitted] index
page2.js 3.78 KiB page2.js [emitted] page2
Резюме: разработка также опускает процесс именования для нас, а остальные все равно должны быть добавлены нами самими.
production
В официальной версии пропущенные плагины, как показано ниже, будут анализироваться один за другим.
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- plugins: [
- new UglifyJsPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}
UglifyJsPlugin
Первое, с чем нам нужно разобраться, это обфускация и сжатие JS, сейчас мы попросим об этом.UglifyJs
теперь в вебпаке его зовутconst UglifyJsPlugin = require('uglifyjs-webpack-plugin');
, так что вы можете использовать его.
ноnew UglifyJsPlugin()
, этот плагин мы можем использовать вoptimize
Средняя конфигурация, эффект тот же, тогда нам не нужно импортировать новый плагин, который замедлит скорость упаковки webpack.
optimization:{
minimize: true,
},
Удалите плагин, обфусцируйте сжатие и вставьте его вoptimization
Так что скорость WebPack лета. Только первый пакет замедлит, после перепаковки быстро.
ModuleConcatenationPlugin
webpack.optimize.ModuleConcatenationPlugin()
Какова роль этого плагина? Официальный документ описывается так:
Помните, что этот плагин работает только с модулями ES6, которые обрабатываются непосредственно webpack. При использовании транспилятора необходимо отключить обработку модулей (например, опцию modules в Babel).
NoEmitOnErrorsPlugin
Последний плагинwebpack.NoEmitOnErrorsPlugin()
, это используется, чтобы программа не сообщала об ошибках.Даже если есть ошибка, она будет продолжать компилироваться для меня, что очень жестоко.
others
Есть также некоторые конфигурации плагинов по умолчанию, на которые нельзя ссылаться в плагинах:
flagIncludedChunks
flagIncludedChunks
Роль этой конфигурации заключается в том, чтобы увидеть результаты:
Не включено
Asset Size Chunks Chunk Names
index.js 1.02 KiB 0 [emitted] index
page1.js 970 bytes 1 [emitted] page1
Когда включено, если только два файла появляются не очевидно, поэтому я добавил три документа, страницу 1, вызов страницы 2, индекс вызова страницы 1, так что здесь ясно, что все фрагменты идентификатора справочного модуля.
Asset Size Chunks Chunk Names
index.js 1.08 KiB 0, 1, 2 [emitted] index
page1.js 1.01 KiB 1, 2 [emitted] page1
page2.js 971 bytes 2 [emitted] page2
OccurrenceOrderPlugin
webpack.optimize.OccurrenceOrderPlugin
Цель этого плагина — упорядочить порядок вхождений в соответствии с количеством ссылок на чанки, потому что это позволяет часто используемым модулям и чанкам иметь меньшие идентификаторы. Запуск приведенного выше примера с этой конфигурацией выглядит следующим образом.
Asset Size Chunks Chunk Names
page2.js 969 bytes 0 [emitted] page2
page1.js 1.01 KiB 1, 0 [emitted] page1
index.js 1.08 KiB 2, 0, 1 [emitted] index
SideEffectsFlagPlugin
webpack.optimize.SideEffectsFlagPlugin()
Чтобы этот плагин вступил в силу, необходимы два условия: одно — импортированный модуль помечен sideEffect, то есть свойство sideEffects в package.json равно false, а второе — текущий модуль ссылается на модуль. без побочных эффектов, и нет никакого побочного эффекта. Тогда при упаковке модуль не будет упакован в файл.
Суммировать
На самом деле, в рабочем режиме, по сравнению с официальной документацией, его конфигурация более эквивалентна следующей конфигурации:
module.exports = {
mode:"none",
optimization:{
flagIncludedChunks:true,
minimize: true,
},
plugins: [
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.SideEffectsFlagPlugin()
]
}
Справочная документация по производственным подключаемым модулям
name | effect |
---|---|
FlagDependencyUsagePlugin | Отметьте неиспользуемые зависимости.Этот плагин нельзя получить через webpack.Я могу только импортировать его, принудительно импортировав файл класса в webpack/lib. |
SideEffectsFlagPlugin | Используется для обработки тряски деревьев,tree shaking,sideEffectФункция этого плагина заключается в том, что если на текущий модуль нет ссылки, а sideEffects в package.json имеет значение false, пакет можно удалить при упаковке.Полезные ответы на stackoverflow |
FlagIncludedChunksPlugin | Добавьте чанкид, содержащийся в текущем чанке, к имени чанка |
ModuleConcatenationPlugin | повышение масштаба |
NoEmitOnErrorsPlugin | предотвратить любую ошибку |
OccurrenceOrderPlugin | Сортировка чанков по количеству звонков |
UglifyJsPlugin | запутанное сжатие |