手写webpack plugin 和 loader

本文将介绍如何编写一个删除console语句的webpack plugin和loader。详细讲解了loader的实现,它接收源代码并根据配置进行处理,以及plugin的创建,包括构造函数接收配置对象,apply方法中利用compiler生命周期钩子进行资源处理。
摘要由CSDN通过智能技术生成

手写webpack plugin 和 loader

本文将简单写一个具有删除console语句功能的webpack的plugin和loader,示例代码参见delConsolePlugindelConsoleLoader


写一个loader

var loaderUtils = require('loader-utils');

module.exports = function(source) {
    var options = loaderUtils.getOptions(this) || {};
    // 删除console语句
    if(options.deleteConsole) {
        source = source.replace(/console\.(log|dir|info)\(.*?\);?/g, '');
    }
    return source;
};

loader直接导出一个方法,入参source为需要loader处理的代码,loader-utils用于获取调用loader时传入的配置对象,根据配置做完相应处理后返回处理后的source。

写一个pulgin

class DelConsole {
    constructor(options) {
        this.deleteConsole = options.deleteConsole;
    }
    apply(compiler) {
        let that = this;
        compiler.hooks.emit.tap('DelConsole',compilation=>{
            // 探索每个块(构建后的输出)
            compilation.chunks.forEach(function(chunk) {
              // 探索块生成的每个资源文件名
              chunk.files.forEach(function(filename) {
                var source = compilation.assets[filename].source();
                // 删除console语句
                if(that.deleteConsole){
                    source = source.replace(/console\.(log|dir|info)\(.*?\);?/g, '');
                }
                // 返回
                compilation.assets[filename]={
                    source() {
                        return source;
                    },
                    size() {
                        return source.length;
                    }
                }
              });
            });
        });
    }
}
module.exports = DelConsole;

plugin稍微比loader复杂一点点,每个plugin都是一个类,constructor接收plugin实例化的配置对象。

webpack会调用每个plugin的apply方法,并传入compiler

compiler暴露了和webpack相关的生命周期hooks,我们希望在生成的资源输出之前做处理,需要调用compiler.hooks.emit.tap(pluginName,compilation=>{})。

emit(c: Compilation) async

The Compiler begins with emitting the generated assets. Here plugins have the last chance to add assets to the c.assets array.

通过compilation,我们则可以拿到模块和依赖。

The Compilation instance extends from the compiler. ie. compiler.compilation It is the literal compilation of all the objects in the require graph. This object has access to all the modules and their dependencies (most of which are circular references). In the compilation phase, modules are loaded, sealed, optimized, chunked, hashed and restored, etc. This would be the main lifecycle of any operations of the compilation.

测试使用

目录结构

在这里插入图片描述

测试代码

var a = 1;
// 这是一句打印
console.log('12313')
/**
 * 这是一段注释
 */
var b = 2;
b = a;

plugin的使用

const DelConsole = require("../index");
module.exports = {
    mode: 'development',
    entry: './index.js',
    output: {
        filename: './bundle.js'
    },
    plugins: [
        new DelConsole({deleteConsole:true})
    ]
};

loader的使用

const path = require("path");
module.exports = {
    mode: 'development',
    entry: './index.js',
    output: {
        filename: './bundle.js'
    },
    module:{
        rules:[{
            test:/\.js$/,
            use:[{
                    loader:path.resolve(__dirname,'../index.js'),
                    options:{
                    deleteConsole:true
                    }
            }]
        }]
    }
};

使用plugin或loader前

在这里插入图片描述

使用plugin或loader后

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值