手写一个webpack loader

news/2024/11/29 1:50:45/

loader的本质

loader 本质上是导出为函数的 JavaScript 模块。当webpack解析资源时,会调用相应的 loader 去处理,然后将上一个 loader 产生的结果或者资源文件传入进去。loader 有三个入参:资源文件的内容(content)、可以被 Source Map 使用的 SourceMap 数据(map)、数据,可以是任何内容(meta)。

loader 有同步 Loaders、异步 Loaders 、Raw Loader 、Pitching Loader ,更详细的可以参考 Loader Interface。

具体步骤

下面写一个去除 console.log 的 loader

  • 创建一个新的文件作为你的 Loader,例如 clean-log-loader.js 。
  • 在文件中,导出一个函数,该函数以源代码作为输入。
  • 在函数内部,根据需要操纵源代码进行转换。
  • 返回转换后的源代码。

同步 Loaders

例如,假设你想创建一个 Loader,去除每个 JavaScript 文件的中的 console.log ,Loader 所示如下:
同步 loader 有两种写法,如果有多个处理结果,则必须调用 this.callback(),当调用 callback() 函数时,总是返回 undefined,代码如下:

module.exports = function (content, map, meta) {this.callback(null, someSyncOperation(content), map, meta);return;
};
function someSyncOperation(content) {return content.replace(/console\.log\(.*\);?/g, "");
}

如果只有一个处理结果,可以调用 this.callback(),也可以不用,代码如下:

module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};

在 webpack.prod.js 中使用

{test: /\.jsx?$/,include: [path.resolve(__dirname, "../src")],use: [{loader: "./loaders/clean-log-loader",},],
},

异步 Loaders

对于异步 loader,使用 this.async 来获取 callback 函数。

module.exports = function(source) {const callback = this.async();// 在 `setTimeout` 等异步方法中完成处理,然后通过回调函数将结果返回给 WebpacksetTimeout(() => {callback(null, someSyncOperation(content), map, meta);}, 1000);
};
function someSyncOperation(content) {return content.replace(/console\.log\(.*\);?/g, "");
}

在 webpack.prod.js 中使用与同步一样。

Raw Loader

默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw 为 true ,loader 可以接收原始的 Buffer 。大多数情况下都是图片或字体使用 Raw Loader,毕竟js还是想看具体内容的, 添加 module.exports.raw = true 就可以了。

module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};
module.exports.raw = true;

Pitching Loader

在文件中导出一个函数并添加 pitch 属性,该函数在模块被处理之前执行。 pitch 函数的输入是请求的数据,包括请求的路径、请求的上下文以及使用的其它 Loader。

module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};
module.exports.pitch = function(request) { // pitch函数在模块被处理之前执行 // request 参数包括请求的路径,请求的上下文和使用的其它 Loader 
};

对于以下配置,执行顺序

a-loader-'pitch'
b-loader-'pitch'
c-loader-'pitch'
c-loader-'normal'
b-loader-'normal'
a-loader-'normal'
module.exports = {//...module: {rules: [{//...use: ['a-loader', 'b-loader', 'c-loader'],},],},
};

结束语

纯属个人总结,不喜勿喷。


http://www.ppmy.cn/news/109708.html

相关文章

SpringBoot框架理解

1 SpringBoot入门 1.2 什么是SpringBoot 1 官网的解释 ​ Spring在官方首页是这么说的:说使用SpringBoot可以构造任何东西,SpringBoot是构造所有基于Spring的应用程序的起点,SpringBoot在于通过最少的配置为你启动程序。 2 我的理解 SpringBoot是Sp…

Quartz组成部分和实现案例

Quartz 是一个功能强大且广泛使用的开源任务调度框架,它的组成部分包括: Job(任务):Job 是需要被调度执行的具体任务逻辑。开发者需要实现 Job 接口,并编写具体的任务逻辑代码。JobDetail(任务…

ElasticSearch安装部署——超详细

ElasticSearch安装部署 简介 全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 es)是目前全文搜索引擎的首选。 它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。 Elasticsearch简称es&…

2023年9月数学建模:最小二乘优化、曲线拟合与函数逼近

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 1. 最小二乘优化 1.1 最小二乘优化的原理 1.2 最小二乘优化的方法 1.2.1 线性最小二乘法 1.2.1.1 正规方程 1.2.1.2 梯度下降法 2. …

C++ map类成员介绍 (map与multimap)

目录 🤔map模板介绍: 🤔特点: 🤔map容器与哈希表: 🤔map的成员函数: 🙂map构造函数: 代码示例: 运行结果: 🙂map赋…

陕西省养老服务人才培训基地申报条件范围、认定材料流程

今天为大家整理了陕西省养老服务人才培训基地申报条件范围、奖励措施等内容,感兴趣的朋友们可以了解一下! 如果想要申报西安市、宝鸡市、铜川市、咸阳市、渭南市、延安市、汉中市、榆林市、安康市、商洛市的项目政策,详情见下图 目标任务 陕…

spdk记录

spdk记录 hello_bdev命令行参数 往期文章: spdk环境搭建 hello_bdev 代码路径:examples/bdev/hello_world/hello_bdev.c 可执行文件路径:build/examples/hello_bdev 刚开始直接执行hello_bdev显示找不到Malloc0 ./build/examples/hello_b…

C++ vector模板和deque的简单应用

目录 🤔vector模板和deque的简单介绍: 🤔vector和deque的主要不同之处: 🤔今天我们用vector模板和deque模板实现以下简单的功能: 代码实现: 🤔讲解: 🤔vector模板和d…