简单实现一个自定义loader

2023-12-25 17:09:34

webpack定义的loader需要遵循单一功能原则,也就是一个loader只实现一个功能。在实现开发中,我们会直接使用诸如蓝湖等生成的样式,比如

button{
    background: rgb(255, 85, 46);
}

但为了考虑主题换肤,我们实现的想要的可能是

button{
    background: var(--jobb_primary_color);
}

所以在这里我们要实现一个vue文件中内容替换的loader

首页,创建webpack-replace-loader.js

我们通过在loaders/webpack-replace-loader.js中定义一个函数(我们知道loader就是一个函数),实现代码如下:

module.exports = function (source) {
    //source就是读取文件的内容
    //可以在此处对source进行替换
    ...
    this.callback(null, source);
}
使用loader,以vue.config.js配置为例
module.exports = {
    chainWebpack: (config) => {
        config.module
            .rule('vue')
            .test(/\.vue/)
            .use('webpack-replace-loader')
            .loader('webpack-replace-loader')
            .options(loader参数)
            .end();
    },
    configureWebpack: (config) => { 
	//加载本地loader
 	config.resolveLoader.modules.push('./loaders/');	
    }
}
loader传入参数考虑

内容替换实现方式,一般是通过正则

new RegExp(pattern[, flags])
// eg.
str.replace(new RegExp('rgb(255, 85, 46', 'ig'), 'var(--jobb_primary_color)');

所以,我们需要设置三个参数

let options = {search: '正则表达式的文本', flags: '标志', replace: '替换结果'}

考虑到会存在多个变量替换,因此

let options = [{search: 'rgb(255, 85, 46', flags: 'ig', replace: 'var(--jobb_primary_color)'}]

image.png
而loader参数只支持string | object, 因此我们需要支持两个写法

//1.考虑多个变量
let options = {
   multi: [{search: 'rgb(255, 85, 46', flags: 'ig', replace: 'var(--jobb_primary_color)'}]
}
//2.单个变量
let options = {search: 'rgb(255, 85, 46', flags: 'ig', replace: 'var(--jobb_primary_color)'}
步入正题,loader编写
//loaders/webpack-replace-loader.js
const { getOptions } = require('loader-utils');
module.exports = function (source) {
    //通过loader-utils获取参数
    let options = getOptions();
    //分情况考虑
    if(Array.isArray(options.multi)){
        options.multi.forEach(item)=> {
            //替换
            source = replaceFunction(item, source)
        }
    }else{
		//替换
		source = replaceFunction(options, source)
    }
    this.callback(null, source);
}
替换逻辑
//错误提示
const errTip = '[webpack-replace-loader: Error] The property "search" and "replace" is essential';

const replaceFunction = (data, source)=>{
    let { search, flags, replace} = data;
    if(!search || !replace){
        throw new Error(errTip);
    }
    return source.replace(new RegExp(search, flags), replace);
}

文章来源:https://blog.csdn.net/m0_37285193/article/details/135201187
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。