正值前端组件化开发时代,那么必然离不开目前最火的构建工具——webpack(grunt,gulp等暂且不谈)。说到这里,刚好有几个问题:
- 为什么运行打包命令之后,
.vue 文件可以转成 .js 文件
- 为什么运行打包命令之后,
.less 文件可以转成 .css 文件
- 为什么运行打包命令之后,
ES6+ 语法可以转成 ES5 语法
上面这几个问题,就引出了我们的主角——【loader】。
loader 是 webpack 的一块很重要的组成部分。我们都知道 webpack 是用于资源打包的,里面的所有资源都是“模块”,内部实现了对模块资源进行加载的机制。但是 Webpack 本身只能处理 js 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。 Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接收文件源码作为参数,返回转换的结果,例如可以使用 loader 加载器可以快速编译预处理器 (less,sass,coffeeScript) 。Loader 可以在 require() 引用模块的时候添加,也可以在 webpack 全局配置中进行绑定,还可以通过命令行的方式使用。(本篇中的参数配置及使用方式均基于 webpack4.0 版本)
一、loader的特点
1、loader 的执行顺序和代码书写的顺序是相反的,即:从下至上,从右至左。
2、第一个执行的 loader 会接收源文件做为参数,下一次执行的 loader 会接收前一个 loader 执行的返回值做为参数
3、需要严格遵循“单一职责”原则,即每个 loader 只负责自己需要负责的事情
二、loader API
methods |
含义 |
this.request |
被解析出来的 request 字符串。例子:"/abc/loader1.js?xyz!/abc/node_modules/loader2/index.js!/abc/resource.js?rrr" |
this.loaders |
所有 loader 组成的数组。它在 pitch 阶段的时候是可以写入的。 |
this.loaderIndex |
当前 loader 在 loader 数组中的索引。 |
this.async |
告诉 loader-runner 这个 loader 将会异步地回调 |
this.callback |
一个可以同步或者异步调用的可以返回多个结果的函数 |
this.data |
在 pitch 阶段和正常阶段之间共享的 data 对象。 |
this.cacheable |
设置是否可缓存标志的函数 |
this.resource |
request 中的资源部分,包括 query 参数 |
this.resourcePath |
资源文件的路径。 |
this.resourceQuery |
资源的 query 参数 |
this.target |
编译的目标。从配置选项中传递过来的。 |
this.webpack |
如果是由 webpack 编译的,这个布尔值会被设置为真 |
this.sourceMap |
应该生成一个 source map。因为生成 source map 可能会非常耗时,你应该确认 source map 确实有必要请求。 |
this.emitWarning |
发出一个警告。 |
this.emitError |
发出一个错误。 |
this.loadModule |
解析给定的 request 到一个模块,应用所有配置的 loader ,并且在回调函数中传入生成的 source 、sourceMap 和 模块实例(通常是 NormalModule 的一个实例)。如果你需要获取其他模块的源代码来生成结果的话,你可以使用这个函数。 |
this.resolve |
像 require 表达式一样解析一个 request 。 |
this.emitFile |
产生一个文件。这是 webpack 特有的。 |
this.fs |
用于访问 compilation 的 inputFileSystem 属性。 |
this.value |
向下一个 loader 传值。如果你知道了作为模块执行后的结果,请在这里赋值(以单元素数组的形式)。 |
this.inputValue |
从上一个 loader 那里传递过来的值。如果你会以模块的方式处理输入参数,建议预先读入这个变量(为了性能因素)。 |
三、写loader之前的需求整理
现在有这样一个需求,使用 hxkj-loader 加载并处理名称为 *.hxkj.vip 的文件,将里面的哈希空间 全部替换为 www.hxkj.vip 。需要实现的转换如下:
转换前的内容:
<div>
<h1>欢迎访问哈希空间</h1>
<p>哎哟,终于等到你。这里就是让人流连忘返的哈希空间呀!</p>
</div>
转换后的内容:
<div>
<h1>欢迎访问www.hxkj.vip</h1>
<p>哎哟,终于等到你。这里就是让人流连忘返的www.hxkj.vip呀!</p>
</div>
四、编写loader
在与 webpack.config.js 同级目录下新建 hxkj-loader.js ,文件的内容如下:
module.exports = function(source){
var content="";
content = source.replace("/哈希空间/g","www.hxkj.vip");
return content;
}
接下来,需要在 webpack.config.js 文件中增加以下的配置:
const path = require("path"); // 引入 node 的 path 模块
...
module:{
rules:[{
test: /\.hxkj\.vip$/, // 正则匹配以 hxkj.vip 结尾的文件
use:[{
loader:path.resolve(__dirname, "hxkj-loader") // 使用 path 模块找到 hxkj-loader 的路径
}]
}]
}
好,到此,一个简易版的 loader 就已经写完了。目前 loader 是直接写在本地的,可以考虑将自己写好的 loader 发布到 npm ,这样就更加完善了。
At last,看完之后有什么不懂的,可以留言反馈。
转载请注明出处:https://www.jianshu.com/p/51b793f6fa0e
作者:TSY
个人空间:https://hxkj.vip
|