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 APIoptions的使用,我们发现:

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相关推荐

  1. 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 ...

  2. linux中ftp的工作原理,Linux系统学习 十二、VSFTP服务—简介与原理

    1.简介与原理 互联网诞生之初就存在三大服务:WWW.FTP.邮件 FTP主要针对企业级,可以设置权限,对不同等级的资料针对不同权限人员显示. 但是像网盘这样的基本没有权限划分. 简介: FTP(Fi ...

  3. 2021年春季学期-信号与系统-第十四次作业参考答案-第六小题参考答案

    本文是 2021年春季学期-信号与系统-第十四次作业参考答案 中各小题的参考答案. §06 第六小题 6.已知序列x[n]x\left[ n \right]x[n]的长度为128,h[n]h\left ...

  4. 2021年春季学期-信号与系统-第十四次作业参考答案-第五小题参考答案

    本文是 2021年春季学期-信号与系统-第十四次作业参考答案 中各小题的参考答案. §05 第五小题 5.有一FFT处理器,用来估计实数信号的频谱.要求指标: (1) 频率间的分辨率为 f1≤5Hzf ...

  5. 2021年春季学期-信号与系统-第十四次作业参考答案

    ▓ 第十四次作业各小题参考答案: 2021年春季学期-信号与系统-第十四次作业参考答案-第一小题参考答案 2021年春季学期-信号与系统-第十四次作业参考答案-第二小题参考答案 2021年春季学期-信 ...

  6. PyTorch框架学习十四——学习率调整策略

    PyTorch框架学习十四--学习率调整策略 一._LRScheduler类 二.六种常见的学习率调整策略 1.StepLR 2.MultiStepLR 3.ExponentialLR 4.Cosin ...

  7. 基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验

    基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验 用ESP8266做MQTT客户端 一些前期的准备 第一步 设置ESP8266开发板的BSP的搜索引擎链接 第二步 下载安装 ...

  8. C1认证学习十四、十五(算法常识、HTML Head 头)

    C1认证学习十四.十五(算法常识.HTML Head 头) 文章目录 C1认证学习十四.十五(算法常识.HTML Head 头) 十四(算法常识) 任务背景 任务目标 查找算法 1.顺序查找 2.二分 ...

  9. unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect

    unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect<7/10/2017> 1.因为要实现声音的交互,首先你得给目标对象添加一个B ...

  10. VLSI数字信号处理系统——第十四章冗余运算

    VLSI数字信号处理系统--第十四章冗余运算 作者:夏风喃喃 参考: (1) VLSI数字信号处理系统:设计与实现 (美)Keshab K.Parhi/著 (2) socvista https://w ...

最新文章

  1. fiddler无法抓取chrome浏览器请求的解决方案之关闭代理软件
  2. ASP.NET 程序中常用的三十三种代码(9)
  3. 打开python环境_windows下切换Python运行环境。
  4. 上海公布第二阶段自动驾驶开放测试道路,近90家企业申请牌照
  5. win10误删的注册表能还原吗_如何恢复修改过的win10注册表?win10注册表修改后恢复方法...
  6. 一个普通java程序员的10年...泪奔 o(╥﹏╥)o o(╥﹏╥)o
  7. PO BO VO DTO POJO DAO概念及其作用
  8. 使用SQL对淘宝用户行为进行分析
  9. PD3.0协议开发经验
  10. 明日之后 找不到服务器,明日之后登录服务器错误怎么办 登录服务器错误请重试解决方法...
  11. SnnGrow快讯:Apple Books上线AI读书功能、有声书市场将迎来颠覆时刻、刚过7岁生日的OpenAI估值达到290亿美元、跻身全球独角兽排行榜前20、中国航天2023全年发射将再破60次
  12. 通过Js来设置页面样式
  13. 解决linux的-bash: ./xx: Permission denied/tensorflow 运行cpu还是gpu的方法
  14. python上机编程报告_Python程序设计实验报告六:函数
  15. 博士申请 | 美国乔治梅森大学计算机系招收机器学习方向全奖博士生
  16. SSL基础:20:使用x509子命令为其他证书签名
  17. x265 1.8版本更新
  18. eclipse如何用Debug调试程序
  19. 亲测源码小旋风蜘蛛池站群X8.51+自带30套模板
  20. 安装Docker,在本机上跑一个‘2048’小游戏(脉冲云在线体验)

热门文章

  1. 氮化镓充电器哪家做得好_多款充电器横评,氮化镓充电器值得买吗?怎么避坑?...
  2. 英特尔530和535哪个好_游戏在哪个硬盘安家更好?HDD+SSD搭档依旧合理
  3. html图片有角度,CSS3:扔在桌子上的照片(transform 属性)带旋转角度
  4. 用for循环语句计算8+88+888+8888+...前十项之和 Java(long类型)
  5. 个人所得税App开启办理2020年度汇算:你是退税还是补缴
  6. JavaScript函数录入成绩
  7. 1英寸CMOS到底多大?
  8. [国家集训队2011]稳定婚姻(无向图定向)
  9. python正式发布年份_python输入年份打印全年日历-女性时尚流行美容健康娱乐mv-ida网...
  10. Tomcat定时重启脚本