Что такое плагин? Функциональные модули, которые фокусируются на конкретной задаче в процессе компиляции webpack, можно назвать плагинами.
Плагин является расширителем, который обогащает сам веб-пакет.Во всем процессе упаковки веб-пакета после завершения загрузчика он не манипулирует файлами напрямую, а работает на основе механизма событий.Он отслеживает определенные узлы в процессе упаковки веб-пакета и выполняет широкий спектр задач.
Особенности плагина
- это отдельный модуль
- Модуль предоставляет функцию js внешнему миру.
- прототип функции
(prototype)
определяет инъекцию наcompiler
объектapply
методapply
Функция должна пройтиcompiler
установленный объектwebpack
Хук события, текущая скомпилированная версия может быть получена в обратном вызове хукаcompilation
Объект, если это плагин асинхронной компиляции, вы можете получить обратный вызовcallback
- Завершите процесс пользовательской субкомпиляции и обработайте
complition
внутренние данные объекта - Если плагин скомпилирован асинхронно, он будет выполнен после завершения обработки данных.
callback
Перезвоните.
Вот 18 часто используемых плагинов для веб-пакетов.
Эта статья была включена в github:GitHub.com/Майкл-Ли Чжиган…
HotModuleReplacementPlugin
Плагин горячего обновления модуля.Hot-Module-Replacement
Горячее обновление зависит отwebpack-dev-server
, последний - обновить файл пакета или перезагрузить, чтобы обновить всю страницу при изменении файла пакета,HRM
заключается в обновлении только измененной части.
HotModuleReplacementPlugin
даwebpack
Модуль поставляется с ним, так что импортируйте егоwebpack
после, вplugins
Его можно использовать непосредственно в элементе конфигурации.
const webpack = require('webpack')
plugins: [
new webpack.HotModuleReplacementPlugin(), // 热更新插件
]
html-webpack-plugin
Создание html-файлов. в вебпакеentry
Запись, связанная с конфигурациейchunk
а такжеextract-text-webpack-plugin
Извлеченный стиль CSS, предоставляемый вилкой, вставленной вtemplate
илиtemplateContent
Создайте HTML-файл на основе содержимого, указанного в элементе конфигурации. Конкретный метод вставки заключается в вставке стиляlink
вставить вhead
элемент,script
вставить вhead
илиbody
середина.
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, '/index.html'),
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
inject: true,
}),
]
inject имеет четыре значения параметра
- правда: значение по умолчанию,
script
метка наhtml
документbody
Нижний - тело:
script
этикетка наhtml
документbody
внизу (то же самое, что и правда) - голова:
script
этикетка наhead
внутри этикетки - false: не вставляйте сгенерированный файл js, просто сгенерируйте
html
документ
Многостраничная упаковка приложения
Иногда наше приложение не обязательно одностраничное, а многостраничное, так как использовать webpack для упаковки.
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: {
index: './src/index.js',
login: './src/login.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash:6].js',
},
//...
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html', //打包后的文件名
}),
new HtmlWebpackPlugin({
template: './public/login.html',
filename: 'login.html', //打包后的文件名
}),
],
}
Если вам нужно настроить несколькоHtmlWebpackPlugin
,Такfilename
Поле не может быть задано по умолчанию, в противном случае будет сгенерировано значение по умолчанию.index.html
.
Но существует проблема,index.html
а такжеlogin.html
Выяснится, что оба введены одновременно.index.f7d21a.js
а такжеlogin.f7d21a.js
, обычно это не то, что мы хотим, мы хотимindex.html
только импортindex.f7d21a.js
,login.html
только импортlogin.f7d21a.js
.
HtmlWebpackPlugin
предоставилchunks
Параметр может принимать массив, конфигурация массива этого параметра будет указана только введенная в html файл js
module.exports = {
//...
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html', //打包后的文件名
chunks: ['index'],
}),
new HtmlWebpackPlugin({
template: './public/login.html',
filename: 'login.html', //打包后的文件名
chunks: ['login'],
}),
],
}
сделай этоnpm run build
, можно увидетьindex.html
Вводится только файл индекса js, иlogin.html
Также представлен только js-файл входа в систему.
clean-webpack-plugin
clean-webpack-plugin
Используется для очистки файла пакета, созданного последним проектом перед упаковкой, он будет основан наoutput.path
Автоматически очищать папки; этот плагин очень часто используется в производственной среде, потому что производственная среда часто генерирует множество файлов пакетов посредством хеширования.Если его не очистить, каждый раз будут генерироваться новые, в результате чего папка будет очень большой.
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'),
}),
new CleanWebpackPlugin(), // 所要清理的文件夹名称
]
extract-text-webpack-plugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
plugins: [
// 将css分离到/dist文件夹下的css文件夹中的index.css
new ExtractTextPlugin('css/index.css'),
]
mini-css-extract-plugin
sourceMap
Этот плагин следует использовать только в производственной конфигурации и вloaders
не используется в цепочкеstyle-loader
, и этот плагин в настоящее время не поддерживает HMR
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.(le|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'less-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[id].[contenthash:8].css',
}),
],
}
purifycss-webpack
Иногда мы пишем слишком много или дублируем CSS, что приводит к избыточному коду, который мы хотим удалить в рабочей среде.
const path = require('path')
const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件
const glob = require('glob') // 引入glob模块,用于扫描全部html文件中所引用的css
module.exports = merge(common, {
plugins: [
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, 'src/*.html')),
}),
],
})
optimize-css-assets-webpack-plugin
Мы хотим уменьшить объем упакованного css, который можно использоватьoptimize-css-assets-webpack-plugin
.
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") // 压缩css代码
optimization: {
minimizer: [
// 压缩css
new OptimizeCSSAssetsPlugin({})
]
UglifyJsPlugin
uglifyJsPlugin
даvue-cli
Метод кода сжатия по умолчанию используется для сжатия файла js, тем самым уменьшая размер файла js и ускоряя скорость загрузки. Он использует однопоточный код сжатия, а время упаковки медленное, поэтому его можно отключить в среде разработки и снова включить при развертывании рабочей среды.
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
plugins: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: true, //是否启用文件缓存
parallel: true //使用多进程并行运行来提高构建速度
})
ParallelUglifyPlugin
Откройте несколько подпроцессов и разделите работу по сжатию нескольких файлов на несколько подпроцессов для завершения, каждый подпроцесс фактически передаетUglifyJS
Чтобы сжать код, но в параллельное выполнение.
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
plugins: [
new ParallelUglifyPlugin({
//cacheDir 用于配置缓存存放的目录路径。
cacheDir: '.cache/',
sourceMap: true,
uglifyJS: {
output: {
comments: false,
},
compress: {
warnings: false,
},
},
}),
]
terser-webpack-plugin
Webpack4.0 по умолчанию используетterser-webpack-plugin
Этот плагин сжатия, ранее использовавшийсяuglifyjs-webpack-plugin
, разница между ними в том, что последний не очень хорош для сжатия ES6, и мы можем включитьparallel
параметр для использования многопроцессорного сжатия для ускорения сжатия.
const TerserPlugin = require('terser-webpack-plugin') // 压缩js代码
optimization: {
minimizer: [
new TerserPlugin({
parallel: 4, // 开启几个进程来处理压缩,默认是 os.cpus().length - 1
cache: true, // 是否缓存
sourceMap: false,
}),
]
}
NoErrorsPlugin
Сообщить об ошибке, не выходя из процесса webpack. При составлении ошибок используйтеNoEmitOnErrorsPlugin
чтобы пропустить выходной каскад. Это гарантирует, что выходной ресурс не будет содержать ошибок.
plugins: [new webpack.NoEmitOnErrorsPlugin()]
compression-webpack-plugin
Все современные браузеры поддерживаютgzip
сжатие, включитьgzip
Сжатие может значительно уменьшить размер ресурсов передачи, тем самым сокращая время загрузки ресурсов, уменьшая время первого белого экрана и улучшая взаимодействие с пользователем.
gzip лучше всего работает с текстовыми форматами файлов (например, CSS, JavaScript и HTML), часто достигая 70–90% сжатия при сжатии больших файлов, а также для уже сжатых ресурсов (например, изображений). очень плохой.
const CompressionPlugin = require('compression-webpack-plugin')
plugins: [
new CompressionPlugin({
// gzip压缩配置
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false, // 是否删除原文件
}),
]
Конечно, этот метод также требует поддержки конфигурации бэкэнда.
DefinePlugin
мы можем пройтиDefinePlugin
Некоторые глобальные переменные могут быть определены, и мы можем использовать эти переменные прямо в модуле без какого-либо объявления.DefinePlugin
даwebpack
Встроенный плагин.
plugins: [
new webpack.DefinePlugin({
DESCRIPTION: 'This Is The Test Text.',
}),
]
// 直接引用
console.log(DESCRIPTION)
ProvidePlugin
Автоматически загружать модули. в любое время, когдаidentifier
модуль автоматически загружается, когда рассматривается как неназначенная переменная, иidentifier
будет назначен выходом этого модуля. Это плагин, который поставляется с webpack.
module.exports = {
resolve: {
alias: {
jquery: './lib/jquery',
},
},
plugins: [
//提供全局的变量,在模块中使用无需用require引入
new webpack.ProvidePlugin({
$: 'jquery',
React: 'react',
}),
],
}
DLLPlugin
Это создает dll только в дополнительной автономной настройке веб-пакета.bundle(dll-only-bundle)
. Этот плагин создаст файл с именемmanifest.json
файл, этот файл используется для созданияDLLReferencePlugin
Сопоставлены со связанными зависимостями.
Шаги использования следующие
1, создать в разделе "Сборка"webpack.dll.config.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
vendor: [
'vue-router',
'vuex',
'vue/dist/vue.common.js',
'vue/dist/vue.js',
'vue-loader/lib/component-normalizer.js',
'vue',
'axios',
'echarts',
],
},
output: {
path: path.resolve('./dist'),
filename: '[name].dll.js',
library: '[name]_library',
},
plugins: [
new webpack.DllPlugin({
path: path.resolve('./dist', '[name]-manifest.json'),
name: '[name]_library',
}),
// 建议加上代码压缩插件,否则dll包会比较大。
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
}),
],
}
2, вwebpack.prod.conf.js
Добавьте конфигурацию после плагина
new webpack.DllReferencePlugin({
manifest: require('../dist/vendor-manifest.json'),
})
3.package.json
Добавить ярлыки команд к файлам(build:dll)
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
"build": "node build/build.js",
"build:dll": "webpack --config build/webpack.dll.conf.js"
}
При упаковке производственной среды сначалаnpm run build:dll
Команда будет сгенерирована в каталоге пакетаvendor-manifest.json
файл с файлом vendor.dll.js. потомnpm run build
Подготовьте другие документы.
4, вход корневого каталогаindex.html
добавить цитату
<script type="text/javascript" src="./vendor.dll.js"></script>
HappyPack
HappyPack
Это позволяет веб-пакету разбивать задачи на несколько подпроцессов для одновременного выполнения, а затем отправлять результаты в основной процесс после обработки подпроцессов. Быть осторожнымHappyPack
правильноfile-loader
,url-loader
Поддержка не дружелюбная, поэтому не рекомендуется использовать этот загрузчик.
1. Установка плагина HappyPack
npm i -D happypack
2,webpack.base.conf.js
файл для настройки module.rules
module: {
rules: [
{
test: /\.js$/,
use: ['happypack/loader?id=babel'],
include: [resolve('src'), resolve('test')],
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.vue$/,
use: ['happypack/loader?id=vue'],
},
]
}
3. В производственной средеwebpack.prod.conf.js
файл для настройки
const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
new HappyPack({
// 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
id: 'babel',
// 如何处理.js文件,用法和Loader配置中一样
loaders: ['babel-loader?cacheDirectory'],
threadPool: HappyPackThreadPool,
}),
new HappyPack({
id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
loaders: [
{
loader: 'vue-loader',
options: vueLoaderConfig,
},
],
threadPool: HappyPackThreadPool,
}),
]
Обратите внимание, что если проект небольшой, многопоточная упаковка может замедлить процесс упаковки.
copy-webpack-plugin
мы вpublic/index.html
Вводятся статические ресурсы, но webpack не поможет нам скопировать в директорию dist при упаковке, поэтомуcopy-webpack-plugin
Это может помочь мне сделать копию работы очень хорошо.
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: 'public/js/*.js',
to: path.resolve(__dirname, 'dist', 'js'),
flatten: true,
},
],
}),
],
}
IgnorePlugin
Это встроенный плагин webpack, его функция заключается в игнорировании указанных каталогов сторонних пакетов и предотвращении упаковки этих указанных каталогов.
Например, мы хотим использоватьmoment
Эта сторонняя зависимая библиотека в основном форматирует время и поддерживает несколько национальных языков. Хотя язык я поставил китайский, при упаковке будут запакованы все языки. Это приводит к большой упаковке и низкой скорости упаковки. Для этого мы можем использоватьIgnorePlugin
Игнорирует указанный каталог, ускоряя упаковку и уменьшая размер файлов.
const Webpack = require('webpack')
plugins: [
//moment这个库中,如果引用了./locale/目录的内容,就忽略掉,不会打包进去
new Webpack.IgnorePlugin(/\.\/locale/, /moment/),
]
Хотя мы игнорируем включение’./locale/'
Файловый каталог пути поля, но он также делает невозможным отображение китайского языка, когда мы его используем, поэтому в это время мы можем вручную импортировать каталог китайского языка.
import moment from 'moment'
//手动引入所需要的语言包
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
let r = moment().endOf('day').fromNow()
console.log(r)