Для целей этой статьи реализуйте проект, который можно удалить изconsole.logПлагин веб-пакета. Возьми это, мы можем научиться писать плагин WebPack.
Во-первых, нам нужно инициализировать среду
yarn init -y
yarn add webpack webpack-cli -D
webpack.config.js настраивается следующим образом:
module.exports = {
entry: './index.js',
plugins: []
}
Создайте новый в корневом каталогеindex.js, содержание следующее:
console.log('hello world');
добавить в package.jsonbuildЗаказ
"scripts": {
"build": "yarn webpack"
}
В этот момент мы бежимyarn buildMain.js будет упакован в каталог dist. Мы используем узел для выполнения этого файла, и он выведет hello world
node dist/main.js
Если вывод успешен, значит, среда настроена.
Структура каталогов выглядит следующим образом (у вас может не быть README.md, но это нормально):
Для удобства наш пользовательский плагин помещен в файл webpack.config.js.
Переключитесь на webpack.config.js, и мы создадим новый класс в качестве нашего пользовательского плагина.
class RemoveLogs {
constructor(options) {
this.options = options
}
apply(compiler) {
console.log("Hello from the custom plugin")
};
}
module.exports = {
entry: './index.js',
plugins: [ new RemoveLogs()]
}
бежать сноваyarn build, вы увидите предложение Hello от пользовательского плагина в консоли. Это показывает, что наш пользовательский плагин был успешно добавлен.
Что нам нужно сделать дальше, так это поставитьconsole.logЗаявление удалено, мы можем выбрать много раз, чтобы сделать это. Например, когда компиляция вот-вот начнется, и мы решили поставить ее после завершения компиляции.
class RemoveLogs {
constructor(options) {
this.options = options
}
apply(compiler) {
compiler.hooks.done.tap("RemoveLogs", stats => {
console.log('我将要移除所有的 console')
removeAllLogs(stats)
});
};
}
compiler.hooks.doneПодобно нашей манипуляции с DOMdocument.addEventListener('click', ()=>{}). То есть мы хотим что-то сделать после завершения компиляции. На самом деле жизненных циклов много, можно нажатьэта ссылка
компилятор.hooks.done.tap Первым параметром этой функции является строка, в данном случае RemoveLogs. Он более полезен при отладке, вы можете назвать его произвольно, и он не должен соответствовать имени класса, второй параметр — это функция, которая будет выполняться в этом жизненном цикле.
Для кнопки мы можем использоватьaddEventListenerДобавьте несколько событий кликов, здесь вы можете добавить столько событий, сколько хотите. Однако здесь мы просто добавляем один.
Далее мы улучшаемremoveAllLogsЭта функция:
removeAllLogs(stats) {
const { path, filename } = stats.compilation.options.output;
let filePath = path + "/" + filename;
fs.readFile(filePath, "utf8", (err, data) => {
const rgx = /console.log\(['|"](.*?)['|"]\)/;
const newData = data.replace(rgx, "");
if (err) console.log(err);
fs.writeFile(filePath, newData, function (err) {
if (err) {
return console.log(err)
}
console.log("Logs Removed");
});
});
}
Но в это время будет сообщено об ошибке, т.к. имя файла в это время получает альтернативное значение, а именно строку '[имя]', можете попробовать сами. Нам также нужно добавить функцию ловушки, чтобы получить реальное имя файла в это время.
compiler.hooks.compilation.tap('GetFileNamePlugin', compilation => {
compilation.hooks.chunkIds.tap('GetFileNamePlugin', (c) => {
this.filename = Array.from(c)[0].name
});
});
В это время нашremoveAllLogsТакже измените способ получения filePath соответственно:
let filePath = (path + "/" + filename).replace(/\[name\]/g, this.filename);
На этом мы закончили. попробуй убежатьnode dist/main.js, вы обнаружите, что у нас больше нет вывода.
Таким образом, мы реализовали один из самых простых плагинов вебпака, как вы думаете, это не сложно :)
Некоторые студенты в комментариях сказали, что обычное сопоставление используется для удаленияconsoleЭтот способ сделать это не очень хорошо, и рекомендуется делать это в Babel, я нашел плагин для Babel, который делает это по его предложению:babel-plugin-transform-remove-console
При этом его исходный код находится здесь:исходный код
Поскольку это не тема данной статьи, здесь она не будет распространяться, а заинтересованные студенты могут изучить ее самостоятельно~
Весь код для этой статьи выглядит следующим образом:
const fs = require('fs')
class RemoveLogs {
constructor(options) {
this.options = options
}
apply(compiler) {
console.log(compiler.options.output);
compiler.hooks.done.tap("RemoveLogs", stats => {
try {
this.removeAllLogs(stats);
} catch (e) {
console.log(e);
}
});
compiler.hooks.compilation.tap('HelloCompilationPlugin', compilation => {
compilation.hooks.chunkIds.tap('HelloCompilationPlugin', (c) => {
this.filename = Array.from(c)[0].name
});
});
};
removeAllLogs(stats) {
const { path, filename } = stats.compilation.options.output;
let filePath = (path + "/" + filename).replace(/\[name\]/g, this.filename);
try {
fs.readFile(filePath, "utf8", (err, data) => {
const rgx = /console.log\(['|"](.*?)['|"]\)/;
const newData = data.replace(rgx, "");
if (err) console.log(err);
fs.writeFile(filePath, newData, function (err) {
if (err) {
console.log(err)
}
console.log("all logs Removed");
});
});
} catch (e) {
console.error(e)
}
}
}
module.exports = {
entry: './index.js',
plugins: [new RemoveLogs()]
}