通过实例学习是最快的,让我们看一个最简单的例子,webpack-clear-console,这个插件是去除输出里的 console 调用,里面插件的写法是 webpack4 之前的写法,不过基本上是一致的,通过源码可以看到插件在 emit 这个钩子上(生成资源到output目录之前)触发,通过 compilation 对象的 assets 对象的 source 方法获取文件内容,然后进行正则匹配。 最后需要将 source 和 size 的变动归回原来的 compilation 对象中,否则这些变动是不会生效的
    image.png

    1. var WebpackClearConsole = function () {
    2. };
    3. WebpackClearConsole.prototype.apply = function (compiler) {
    4. var self = this;
    5. compiler.plugin("emit", function (compilation, callback) {
    6. compilation.chunks.forEach(function (chunk) {
    7. // Explore each asset filename generated by the chunk and replace the console.* methods:
    8. chunk.files.forEach(function (filename) {
    9. // Get the asset source for each file generated by the chunk:
    10. var source = compilation.assets[filename].source();
    11. var consoleName=["console","window.console"];
    12. var consoleType= ["log", "info", "warn", "error" ,"assert" ,"count" ,"clear", "group" ,
    13. "groupEnd", "groupCollapsed" ,"trace" ,"debug", "dir" ,"dirxml", "profile", "profileEnd" ,
    14. "time" ,"timeEnd" ,"timeStamp" ,"table","exception"];
    15. //Console.log|debug|info|warn|error regexp
    16. rConsole = new RegExp("(" + consoleName.join("|") + ")" + ".(?:" + consoleType.join("|") + ")\\s{0,}\\([^;]*\\)(?!\\s*[;,]?\\s*\\/\\*\\s*NotClearConsole\\s*\\*\\/)\\s{0,};?", "gi");
    17. //Regexp replace null
    18. source = source.replace(rConsole, function() {
    19. return source.replaceWith || "";
    20. });
    21. compilation.assets[filename] = {
    22. source: function () {
    23. return source;
    24. },
    25. size: function () {
    26. return source.length;
    27. }
    28. }
    29. });
    30. });
    31. callback();
    32. });
    33. };
    34. module.exports = WebpackClearConsole;