webpack系统学习(十四)如何编写一个loader
1. 创建一个简单的loader
所谓 loader 只是一个导出为函数的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。函数的 this 上下文将由 webpack 填充。
假设我们现在有一个index.js:
//index.js
console.log("hello world")
在不对js文件进行额外处理时对其进行打包,得到/dist/main.js
//main.js
...
/***/ (function(module, exports) {eval("console.log(\"hello world\")\n\n//# sourceURL=webpack:///./src/index.js?");
/***/ })
...
我们希望借助loader使js文件中要输出的hello world
转换为hello js
,像上文所说,一个loader就是一个导出为函数的JavaScript模块。
创建replaceLoader.js,现在的文件目录结构:
//replaceLoader.js
//使用声明式函数而不是箭头函数,因为在该函数中我们需要使用this
module.exports = function (source){return source.replace('world','js')
}
然后我们使用replaceLoader对js文件进行处理。
修改webpack.config.js:
...module: {rules: [{test: /\.js/,use: [path.resolve(__dirname,'./loader/replaceLoader')]}]}
...
重新打包,查看此时生成的 main.js:
...
/***/ (function(module, exports) {eval("console.log(\"hello js\")\n\n//# sourceURL=webpack:///./src/index.js?");
/***/ })
...
不难发现,此时运行main.js,控制台的输出就从hello world
转换成了hello js
。
这个replaceLoader就是一个简单的loader,它的作用就是在打包js文件时,将js文件中的world
替换成js
。
2. 设置resolveLoader简化自定义loader的加载路径
修改webpack.config.js:
...resolveLoader: {modules: ['node_modules', './loader']}
...
这样设置resolveLoader,webpack在打包文件时,如果需要使用loader,它将首先在node_modules
中查找该loader,如果找不到,就会在./loader
文件夹下面查找。
3. 向Loader传入参数
我们在使用Loader时,可以向其传递一些参数,比如我们在使用url-loader 时:
{test:/\.(png|jpg|gif)$/,use:{loader: 'url-loader',options: {name: '[name].[ext]',//placeholder占位符outputPath:'image/',limit: 2048 //2kb}}}
我们为url-loader设置了options,这里面的配置是如何被url-loader获取并使用呢?
查看webpack官网上Loader API对options的使用,我们发现:
this.query
如果这个 loader 配置了 options 对象的话,this.query 就指向这个 option 对象。
如果 loader 中没有 options,而是以 query 字符串作为参数调用时,this.query 就是一个以 ? 开头的字符串。
使用 loader-utils 中提供的 getOptions 方法 来提取给定 loader 的 option。
修改webpack.config.js:
...
{test: /\.js/,use: [{loader: 'replaceLoader',options: {from: 'world',to: 'js'}}]
}
...
我们现在修改replaceLoader,查看一下this.query的内容:
//使用声明式函数而不是箭头函数,因为在该函数中我们需要使用this
module.exports = function (source){console.log(this.query)return source.replace('world','js')
}
打包时的输出:
{ from: 'world', to: 'js' }
...
所以this.query就是一个对象,里面包含了我们出入的options信息。
修改replaceLoader,使用options传入的配置信息。
//使用声明式函数而不是箭头函数,因为在该函数中我们需要使用this
module.exports = function (source){return source.replace(this.query.from,this.query.to)
}
但是我们注意到,webpack官网建议我们使用 loader-utils 中提供的 getOptions 方法 来提取给定 loader 的 option。
npm i loader-util -s
修改replaceLoader.js:
const loaderUtils = require('loader-utils')
module.exports = function (source){const options = loaderUtils.getOptions(this)return source.replace(options.from, options.to)
}
在返回转换后的content
时,可以使用this.callback()
,this.callback
方法更加灵活,因为它允许传递多个参数,而不仅仅是content
。
this.callback(err: Error | null,content: string | Buffer,sourceMap?: SourceMap,meta?: any
);
第一个参数必须是 Error 或者 null
第二个参数是一个 string 或者 Buffer。
可选的:第三个参数必须是一个可以被这个模块解析的 source map。
可选的:第四个选项,会被 webpack 忽略,可以是任何东西(例如一些元数据)。
使用this.callback 返回处理结果,修改replaceLoader.js:
const loaderUtils = require('loader-utils')module.exports = function (source){const options = loaderUtils.getOptions(this)this.callback(null,source.replace(options.from, options.to))return
}
4. 在Loader中使用异步处理
异步处理需要使用this.async
告诉 loader-runner 这个 loader 将会异步地回调。返回 this.callback。
新创建一个replaceLoaderAsync.js:
//replaceLoaderAsync和replaceLoader的异步版本
const loaderUtils = require('loader-utils')module.exports = function (source){const options = loaderUtils.getOptions(this)const callBack = this.async()setTimeout(()=>{const result = source.replace(options.from, options.to)callBack(null, result)},5000)
}
我们先不使用这个异步loader,查看打包信息:
...
Time: 124ms
...
打包时间为124ms。
现在我们更改webpack.config.js,使用replaceLoaderAsync
{test: /\.js/,use: [{loader: 'replaceLoader',options: {from: 'world',to: 'js'}},{loader: 'replaceLoaderAsync',options: {from: 'hello',to: 'hi'}}]}
现在再次打包:
...
Time: 5254ms
...
打包时间增加到了5254ms。
同时查看打包后生成的main.js:
...
/***/ (function(module, exports) {eval("console.log(\"hi js\")\n\n//# sourceURL=webpack:///./src/index.js?");/***/ })
...
两个loader都生效了。
结语:
loader中还有很多配置,更多配置可以前往webpack官网查看。
webpack系统学习(十四)如何编写一个loader相关推荐
- C语言试题二十四之编写一个函数unsigned function(unsigned w),w使一个大于10的无符号整数,若w是n(n≥2)位的整数,则函数求出w后n-1位的数作为函数值返回。
1. 题目 请编写一个函数unsigned function(unsigned w),w使一个大于10的无符号整数,若w是n(n≥2)位的整数,则函数求出w后n-1位的数作为函数值返回. 比如:w是1 ...
- linux中ftp的工作原理,Linux系统学习 十二、VSFTP服务—简介与原理
1.简介与原理 互联网诞生之初就存在三大服务:WWW.FTP.邮件 FTP主要针对企业级,可以设置权限,对不同等级的资料针对不同权限人员显示. 但是像网盘这样的基本没有权限划分. 简介: FTP(Fi ...
- 2021年春季学期-信号与系统-第十四次作业参考答案-第六小题参考答案
本文是 2021年春季学期-信号与系统-第十四次作业参考答案 中各小题的参考答案. §06 第六小题 6.已知序列x[n]x\left[ n \right]x[n]的长度为128,h[n]h\left ...
- 2021年春季学期-信号与系统-第十四次作业参考答案-第五小题参考答案
本文是 2021年春季学期-信号与系统-第十四次作业参考答案 中各小题的参考答案. §05 第五小题 5.有一FFT处理器,用来估计实数信号的频谱.要求指标: (1) 频率间的分辨率为 f1≤5Hzf ...
- 2021年春季学期-信号与系统-第十四次作业参考答案
▓ 第十四次作业各小题参考答案: 2021年春季学期-信号与系统-第十四次作业参考答案-第一小题参考答案 2021年春季学期-信号与系统-第十四次作业参考答案-第二小题参考答案 2021年春季学期-信 ...
- PyTorch框架学习十四——学习率调整策略
PyTorch框架学习十四--学习率调整策略 一._LRScheduler类 二.六种常见的学习率调整策略 1.StepLR 2.MultiStepLR 3.ExponentialLR 4.Cosin ...
- 基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验
基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验 用ESP8266做MQTT客户端 一些前期的准备 第一步 设置ESP8266开发板的BSP的搜索引擎链接 第二步 下载安装 ...
- C1认证学习十四、十五(算法常识、HTML Head 头)
C1认证学习十四.十五(算法常识.HTML Head 头) 文章目录 C1认证学习十四.十五(算法常识.HTML Head 头) 十四(算法常识) 任务背景 任务目标 查找算法 1.顺序查找 2.二分 ...
- unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect
unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect<7/10/2017> 1.因为要实现声音的交互,首先你得给目标对象添加一个B ...
- VLSI数字信号处理系统——第十四章冗余运算
VLSI数字信号处理系统--第十四章冗余运算 作者:夏风喃喃 参考: (1) VLSI数字信号处理系统:设计与实现 (美)Keshab K.Parhi/著 (2) socvista https://w ...
最新文章
- fiddler无法抓取chrome浏览器请求的解决方案之关闭代理软件
- ASP.NET 程序中常用的三十三种代码(9)
- 打开python环境_windows下切换Python运行环境。
- 上海公布第二阶段自动驾驶开放测试道路,近90家企业申请牌照
- win10误删的注册表能还原吗_如何恢复修改过的win10注册表?win10注册表修改后恢复方法...
- 一个普通java程序员的10年...泪奔 o(╥﹏╥)o o(╥﹏╥)o
- PO BO VO DTO POJO DAO概念及其作用
- 使用SQL对淘宝用户行为进行分析
- PD3.0协议开发经验
- 明日之后 找不到服务器,明日之后登录服务器错误怎么办 登录服务器错误请重试解决方法...
- SnnGrow快讯:Apple Books上线AI读书功能、有声书市场将迎来颠覆时刻、刚过7岁生日的OpenAI估值达到290亿美元、跻身全球独角兽排行榜前20、中国航天2023全年发射将再破60次
- 通过Js来设置页面样式
- 解决linux的-bash: ./xx: Permission denied/tensorflow 运行cpu还是gpu的方法
- python上机编程报告_Python程序设计实验报告六:函数
- 博士申请 | 美国乔治梅森大学计算机系招收机器学习方向全奖博士生
- SSL基础:20:使用x509子命令为其他证书签名
- x265 1.8版本更新
- eclipse如何用Debug调试程序
- 亲测源码小旋风蜘蛛池站群X8.51+自带30套模板
- 安装Docker,在本机上跑一个‘2048’小游戏(脉冲云在线体验)
热门文章
- 氮化镓充电器哪家做得好_多款充电器横评,氮化镓充电器值得买吗?怎么避坑?...
- 英特尔530和535哪个好_游戏在哪个硬盘安家更好?HDD+SSD搭档依旧合理
- html图片有角度,CSS3:扔在桌子上的照片(transform 属性)带旋转角度
- 用for循环语句计算8+88+888+8888+...前十项之和 Java(long类型)
- 个人所得税App开启办理2020年度汇算:你是退税还是补缴
- JavaScript函数录入成绩
- 1英寸CMOS到底多大?
- [国家集训队2011]稳定婚姻(无向图定向)
- python正式发布年份_python输入年份打印全年日历-女性时尚流行美容健康娱乐mv-ida网...
- Tomcat定时重启脚本