通过实例学习是最快的,让我们看一个最简单的例子,webpack-clear-console,这个插件是去除输出里的 console 调用,里面插件的写法是 webpack4 之前的写法,不过基本上是一致的,通过源码可以看到插件在 emit 这个钩子上(生成资源到output目录之前)触发,通过 compilation 对象的 assets 对象的 source 方法获取文件内容,然后进行正则匹配。 最后需要将 source 和 size 的变动归回原来的 compilation 对象中,否则这些变动是不会生效的
var WebpackClearConsole = function () {
};
WebpackClearConsole.prototype.apply = function (compiler) {
var self = this;
compiler.plugin("emit", function (compilation, callback) {
compilation.chunks.forEach(function (chunk) {
// Explore each asset filename generated by the chunk and replace the console.* methods:
chunk.files.forEach(function (filename) {
// Get the asset source for each file generated by the chunk:
var source = compilation.assets[filename].source();
var consoleName=["console","window.console"];
var consoleType= ["log", "info", "warn", "error" ,"assert" ,"count" ,"clear", "group" ,
"groupEnd", "groupCollapsed" ,"trace" ,"debug", "dir" ,"dirxml", "profile", "profileEnd" ,
"time" ,"timeEnd" ,"timeStamp" ,"table","exception"];
//Console.log|debug|info|warn|error regexp
rConsole = new RegExp("(" + consoleName.join("|") + ")" + ".(?:" + consoleType.join("|") + ")\\s{0,}\\([^;]*\\)(?!\\s*[;,]?\\s*\\/\\*\\s*NotClearConsole\\s*\\*\\/)\\s{0,};?", "gi");
//Regexp replace null
source = source.replace(rConsole, function() {
return source.replaceWith || "";
});
compilation.assets[filename] = {
source: function () {
return source;
},
size: function () {
return source.length;
}
}
});
});
callback();
});
};
module.exports = WebpackClearConsole;