Plugins expose the full potential of the webpack engine to third-party developers. ----------- Webpack
По сравнению с загрузчиками плагины более гибкие, потому что они имеют доступ к компилятору webpack и ядру компиляции. Это позволяет плагину перехватывать выполнение веб-пакета через некоторые функции ловушек, и даже вы можете запускать подкомпилятор последовательно с загрузчиком, напримерMiniCssExtractPluginВот что он делает.
Образец кода:link
базовая структура плагина webpack
кhtml-webpack-pluginНапример, он используется следующим образом
plugins: [
new HtmlWebpackPlugin({
...
}),
],
Нетрудно заметить, что основная форма плагина webpack — это конструктор.new function(), и в то же время, чтобы получить компилятор, нужно выставить интерфейс для плагина (дляapplyфункция). Итак, его базовая структура выглядит следующим образом:
- именованный объект функции JavaScript;
- В своем
prototypeвыше, определитеapplyметод.
Есть много способов реализовать эту форму в JavaScript, в этой статье используетсяclassдобиться следующим образом
module.exports = class DemoPlugin {
apply() {
console.log('applying')
}
}
Настроить среду разработки
Чтобы иметь возможность запускать этот плагин, нам нужно создать среду
mkdir webpack-demo-plugin
cd webpack-demo-plugin
npm init
webpack.plugin.js
const path = require("path");
const PATHS = {
lib: path.join(__dirname, "index.js"),
build: path.join(__dirname, "build"),
};
module.exports = {
entry: {
lib: PATHS.lib,
},
output: {
path: PATHS.build,
filename: "[name].js",
},
};
index.js
console.log("hello world")
в то же время, чтобыpackage.jsonдобавлено в
"scripts": {
"build:plugin": "webpack --config webpack.plugin.js --mode production",
...
}
Реализовать демонстрацию веб-пакета
Создайтеplugins/demo-plugin.jsфайл, содержимое представляет собой предыдущую демо-версию плагина webpack, и оно импортируется вwebpack.plugin.jsВнутри.
webpack.plugin.js
const DemoPlugin = require("./plugins/demo-plugin.js");
module.exports = {
...
// 引入 plugin
plugins: [new DemoPlugin()],
};
попробуй убежатьnpm run build:plugin, который распечатывается на терминале
applying
Hash: 98c8997160aa995a58a4
Version: webpack 4.12.0
Time: 93ms
Built at: 2019-04-29 14:34:31
Asset Size Chunks Chunk Names
lib.js 956 bytes 0 [emitted] lib
[0] ./index.js 26 bytes {0} [built]
Удивительно обнаружил приложение, указывающее на то, что плагин успешно запущен.
передать параметры
При применении плагина иногда необходимо передать параметры, чтобы сообщить плагину, что делать. когдаnew DemoPlugin()вызоветclass DemoPluginизconstructorтак
plugins/demo-plugin.js
module.exports = class DemoPlugin {
constructor(options) {
this.options = options
}
apply() {
console.log('apply', this.options)
}
}
При этом необходимо модифицироватьwebpack.plugin.jsпередать соответствующие параметры
module.exports = {
...
plugins: [new DemoPlugin({ name: 'demo' })],
}
бегатьnpm run build:plugin, его можно найтиapply { name: 'demo' }. Вот обычный плагинschema-utilsМожет использоваться для проверки параметров.
Понимание компилятора и компиляции webpack
Представленный в предыдущей базовой структуре плагина webpack,applyФункции можно использовать для доступа к ядру webpack. Конкретно,applyПараметры функцииcompiler
plugins/demo-plugin.js
module.exports = class DemoPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
console.log(compiler)
}
}
бежать сноваnpm run build:plugin, вы обнаружите, что терминал выводитcompilerвся информация о которомhooksПоля составляют подавляющее большинство.
Контрастофициальная документация, вы обнаружите, что каждый хук соответствует определенному этапу. Например, практика emit выполняется перед отправкой ресурсов в выходной каталог. Таким образом, вы можете контролировать процесс компиляции, слушая хук.
plugins/demo-plugin.js
module.exports = class DemoPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
compiler.plugin('emit', (compilation, next) => {
console.log(compilation)
next()
})
}
}
Не забудьте вызвать next, иначе webpack не продолжит связывание.
бегатьnpm run build:pluginпокажет больше информации, чем раньше, потому что скомпилированный объект содержит весь граф зависимостей, через который проходит webpack. Вы можете получить доступ ко всему, что с этим связано, включая записи, фрагменты, модули, активы и т. д.
Запись в файл через компиляцию
в состоянии пройтиcompilationизassetsобъект для записи нового файла или изменения уже созданного файла. Чтобы лучше писать файлы, мы вводим пакет npm
npm install webpack-sources --save-dev
plugins/demo-plugin.js
const { RawSource } = require("webpack-sources");
module.exports = class DemoPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
const { name } = this.options;
compiler.plugin('emit', (compilation, next) => {
compilation.assets[name] = new RawSource("demo");
next()
})
}
}
запустить в терминалеnpm run build:plugin
Hash: 98c8997160aa995a58a4
Version: webpack 4.12.0
Time: 95ms
Built at: 2019-04-29 16:08:52
Asset Size Chunks Chunk Names
lib.js 956 bytes 0 [emitted] lib
demo 4 bytes [emitted]
[0] ./index.js 26 bytes {0} [built]
В столбце «Актив» появится наш пользовательский демонстрационный файл.
Дополнительные функции ловушек см.the official compilation reference.
Управление предупреждениями и ошибками
проведите эксперимент, если выapplyВставить в функциюthrow new Error("Message"), что происходит, терминал печатаетUnhandled rejection Error: Message. Затем webpack прерывает выполнение.
Для того, чтобы не влиять на выполнение вебпака, для предупреждения или сообщений об ошибках пользователю во время компиляции, следует использоватьcompilation.warningsа такжеcompilation.errors.
compilation.warnings.push("warning");
compilation.errors.push("error");
Суммировать
Когда вы начинаете разрабатывать плагин, обязательно найдите время для изучения существующих плагинов того же типа. Разрабатывайте плагины один за другим, чтобы проверять только один плагин за раз. Если у вас возникнут проблемы, вы можете проверить исходный код веб-пакета, это улучшит вашу интуицию в отладке.
Ссылаться на: