loader的基本概念
在webpack中,loader本质是一个函数,在我们执行文件操作时,会通过该函数对接收到的内容进行转换,返回转换后的结果。因为 Webpack 只支持 JavaScript 文件,所有有的时候,loader也对其他类型的文件进行转译处理,转换为 Webpack 支持的文件。
实现一个同步的 loader
在实现之前,我们先看一下什么是同步loader:
- 默认创建的Loader就是同步的Loader
 - 这个Loader必须通过return或者this.callback来返回结果,交给下一个loader来处理
 - 通常在有错误的情况下,会使用this.callback
- 第一个参数为ERR或者null
 - 返回的是 
string或者buffer 
 
在这里我们先初始化一个项目
1  | npm init -y  | 
再新建两个文件 index.js、webpack.config.js
具体结构如下图所示
其中index.js中的内容
1  | // index.js  | 
webpack.config.js 中的内容
1  | const path = require('path')  | 
接着,在根目录下新建一个同步loader syncLoader.js 
1  | // syncLoader.js  | 
修改 Webpack 打包配置
1  | const path = require('path')  | 
准备就绪,使用webpack进行打包,因为 package.json 已经声明了 "main": "index.js" 所以我们直接在根目录输入 webpack 即可,不出意料的话,会在终端输出以下内容:
1  | source: console.log('自己实现一个loader');  | 
很明显,第一行的打印内容中 source 是  syncLoader.js 中的内容,后面拼接的是 index.js 中的文本,如下:
1  | // index.js  | 
我们接着使用 syncLoader.js 对 index.js 中的内容作出一些处理,比如:
1  | // index.js  | 
输出结果为
1  | source: console.log('自己实现一个loader');同步loader  | 
当然,我们可以使用 loader-utils 来完成更多自定义的功能,我这里安装 loader-utils@1.2.3
先改写 webpack.config.js 的内容,主要再rules中给 syncLoader 增加了 options 属性,其中 options 的内容可以自定义
1  | rules: [  | 
然后我们就可以在 syncLoader.js 通过loader-utils 的 getOptions 获取到 options 配置项
1  | const loaderUtils = require('loader-utils')  | 
打包结果
1  | { message: '同步loader' }  | 
可以看到,在控制台输出了 syncLoader loader 新增的配置项内容 同步loader,跟之前的内容相同。
至此,我们就完成了一个同步 loader 
当然我们要尽可能的异步化 Loader,如果计算量很小,同步也可以,所以看看如何实现一个异步的 loader
实现一个异步的 loader
在实现之前,我们先看一下什么是异步loader:
- 使用Loader进行一些异步的操作
 - 我们希望在异步操作完成之后,再返回这个loader处理的结果
 - 使用 
this.async()实现 
在根目录新建一个js文件 asyncLoader.js
1  | module.exports = function (source) {  | 
修改 webpack.config.js ,在use中配置异步的loader,修改后的内容如下
1  | const path = require('path')  | 
由于loader的执行机制,所以我们预测 先执行 asyncLoader,再执行syncLoader
查看 dist/main.js 内容,确实如此,至此我们就简单实现了一个 异步loader
总结
- Loader本质是一个导出为函数的JavaScript模块
 - loader 的执行顺序是从下往上的,Loader runner库会调用这个函数,然后将上一个loader产生的结果或者资源文件传入进去
 - 我们可以通过 
loader-utils获取到 loader 的配置,再对原始文件进行对应操作 - 异步loader主要通过 
this.async()实现 
那么那么,为什么 loader 的执行是从下往上,从右往左的呢 ?。。。