写在前面
最近遇到了一个很特殊的需求,业务代码打包后需要运行在两个不同的环境中,而两个环境中的属性有非常多的差异,我想在打包阶段来处理这些差异,所以就需要自定义一个loader来处理设计到的相关文件,在此之前,得先学习一下loader相关的知识点。
loader是什么
loader本质上是一个导出为函数的JavaScript模块,loader runner库会调用这个函数,然后将上一个loader产生的结果或者资源文件传入进去,并返回处理后的资源给下一个资源。
接收参数
Loader函数会接收三个参数
- content:需要处理的资源文件内容
- map:sourcemap相关的数据
- meta:一些元数据
module.exports = function(content,map,meta){
//函数处理代码....
return content
}
返回值
loader有两种方式来返回处理后的数据
- 直接将处理之后的数据通过
return
返回 - 通过
this.callback
来返回处理之后的数据
this.callback
this.callback接收两个参数
- 第一个参数必须是 Error 或者 null,来代表loader的处理是否出错
- 第二个参数是一个 string或者Buffer
所以,通常在有错误的情况下,我们会使用 this.callback
代码语言:javascript复制module.exports.pitch = function(content,map,meta){
//函数处理代码....
this.callback(null,content)
//return content
}
this.async
如果loader里面的处理是异步的,我们需要调用 this.async
方法来获取 callback
函数
module.exports = function(content) {
var callback = this.async();
setTimeout(function() {
callback(null, content "-async-simple");
}, 50);
};
配置自定义loader
假如我们写了一个关于txt
文本文件的loader,需要在webpack中使用的话,我们需要在loader字段中进行配置
//...
rules:[
//...
{
test: /.txt?$/,
use:[{
// loader文件的相对路径
loader:'./txt_loader.js',
}]
}
]
或者通过resolveLoader字段,配置resolveLoader属性,可以告诉webpack可以直接去哪个文件夹内寻找loader文件。
代码语言:javascript复制module.exports = {
module: {
rules: [
{
test: /.js$/,
//直接写loader函数的文件名称
use: ['myLoader']
}
]
}
resolveLoader: {
//此处配置从哪里找loader
modules: ['./loaders','node_modules']
}
}
获取配置传参
很多情况下,我们是需要传递一些参数,在打包的流程中对loader进行配置
代码语言:javascript复制//...
rules:[
//...
{
test: /.txt?$/,
use:[{
loader:'./txt_loader.js',
// 加入loader配置
options:{
isChinese:false
//.....
}
}]
}
]
然后我们可以在loader中通过getOptions
方法来进行获取
const { getOptions } = require('loader-utils')
modules.exports = function(content){
//...
const options = getOptions(this) //处理函数...
return content
}
loader的分类
NormalLoader
定义
代码语言:javascript复制module.exports = function(content,map,meta){
//函数处理代码....
return content
}
PitchLoader
定义
代码语言:javascript复制module.exports.pitch = function(content,map,meta){
//函数处理代码....
return content
}
联系
pitch loader的整体执行顺序都在normal loader之前,并且可以通过meta来将数据传递到对应的normal loader上
webpack对loader的分类
在 Webpack 中,loader 可以被分为 4 类:
- pre 前置:可以通过enforce设置
- post 后置:可以通过enforce设置
- normal 普通:默认所有的loader都是normal
- inline 行:在行内设置的loader是inline(如:
import 'loader1!loader2!./test.js'
)
其中 pre 和 post loader,可以通过 rule
对象的 enforce
属性来指定
执行顺序
- PitchingLoader的执行顺序:post, inline, normal, pre;
- NormalLoader的执行顺序:pre, normal, inline, post;
最后
感谢你能看到这里,本文总结了loader
的一些基础知识,希望对你有用,下一篇文章,笔者将详细介绍解决业务需求的loader,如果可以的话,不妨留个赞再走呢。