作者:焦传锴来源:微医大前端技术
一、Loader
1.1loader干啥的?
webpack只能理解JavaScript和JSON文件,这是webpack开箱可用的自带能力。**loader**让webpack能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
也就是说,webpack把任何文件都看做模块,loader能import任何类型的模块,但是webpack原生不支持譬如css文件等的解析,这时候就需要用到我们的loader机制了。我们的loader主要通过两个属性来让我们的webpack进行联动识别:
test属性,识别出哪些文件会被转换。use属性,定义出在进行转换时,应该使用哪个loader。
那么问题来了,大家一定想知道自己要定制一个loader的话需要怎么做呢?
1.2开发准则
俗话说的好,没有规矩不成方圆,编写我们的loader时,官方也给了我们一套用法准则(Guidelines),在编写的时候应该按照这套准则来使我们的loader标准化:
简单易用。使用链式传递。(由于loader是可以被链式调用的,所以请保证每一个loader的单一职责)模块化的输出。确保无状态。(不要让loader的转化中保留之前的状态,每次运行都应该独立于其他编译模块以及相同模块之前的编译结果)充分使用官方提供的loaderutilities。记录loader的依赖。解析模块依赖关系。
根据模块类型,可能会有不同的模式指定依赖关系。例如在CSS中,使用
import和url(...)语句来声明依赖。这些依赖关系应该由模块系统解析。可以通过以下两种方式中的一种来实现:通过把它们转化成require语句。使用this.resolve函数解析路径。提取通用代码。避免绝对路径。使用peerdependencies。如果你的loader简单包裹另外一个包,你应该把这个包作为一个peerDependency引入。
1.3上手
一个loader就是一个nodejs模块,他导出的是一个函数,这个函数只有一个入参,这个参数就是一个包含资源文件内容的字符串,而函数的返回值就是处理后的内容。也就是说,一个最简单的loader长这样:
module.exports=function(content){//content就是传入的源内容字符串returncontent}
当一个loader被使用的时候,他只可以接收一个入参,这个参数是一个包含包含资源文件内容的字符串。是的,到这里为止,一个最简单loader就已经完成了!接下来我们来看看怎么给他加上丰富的功能。
1.4四种loader
我们基本可以把常见的loader分为四种:
同步loader异步loader"Raw"LoaderPitchingloader
①同步loader与异步loader
一般的loader转换都是同步的,我们可以采用上面说的直接return结果的方式,返回我们的处理结果:
module.exports=function(content){//对content进行一些处理constres=dosth(content)returnres}
也可以直接使用this.callback()这个api,然后在最后直接**returnundefined**的方式告诉webpack去this.callback()寻找他要的结果,这个api接受这些参数:
this.callback(err:Error
null,//一个无法正常编译时的Error或者直接给个nullcontent:string
Buffer,//我们处理后返回的内容可以是string或者Buffer()sourceMap?:SourceMap,//可选可以是一个被正常解析的sourcemapmeta?:any//可选可以是任何东西,比如一个公用的AST语法树);
接下来举个例子:
这里注意[this.getOptions()](