话不多说,直接进入正题: 当webpack遇到.vue结尾的文件时,此时会去module的rules里面查找vue相关正则,如下图所示:  此时会从下到上调用loader,第一个就是vue-loader,会把当前.vue里面的内容传给此loader,如图所示:  53行以前都是设置常量,看看53行做了些什么:   可以看到,将source分解成了三块,script、styles、template内容全部分离了出来。接下来直到102行,咱们直接看重点:    最终生成的代码如图所示:  这是vue-loader第一次解析得出的结果:  此时返回的值为normalizer函数的exports和一堆的import和export,很多人就蒙圈了,返回这么一段代码,那webpack会怎么处理呢?以第一行为例,webpack会返回.App.vue的内容并且再次通过vue-loader,这里和inline-loader不一样,inline-loader会以自己的loader为准,不会被module.rules里面设置的loader正则匹配,而是直接用inline-loader去处理 
然后我们继续来分析normalizer干了些什么。直接看输出,内容如下:   可以看出render就是我们的模板渲染函数,scriptExports就是我们下图部分:  所以normalizer只是把我们的app.vue模版文件解析成一个普通的vue组件。用到的loader有:  第二次解析,用到的loader有:  此时多出一个picher函数,会先从上到下执行picher方法,再从下到上执行loader,如果当前的picher方法有返回值,则执行当前loader前面的loader 详情请看https://zhuanlan.zhihu.com/p/360421184。   此时可以看到又引入了App.vue,此时webpack又第二次使用vue-loader,在引用前会执行pitch.js loader的pitch方法,返回值如下:  看到这个返回值有的小伙伴可能又有点疑惑了,返回这个么老长一段代码,webpack又将怎么处理呢?这里可以看到返回的是inline-loader,此时还是以.App.vue结尾,但是此时不会再走vue-loader,而是从左到右加载cache-loader、babel-loader、。。。的pitch方法,如果pitch方法都没有返回值,那么将从右往左加载各个loader,同时每个loader的返回值将传递给下一个loader,直到执行完inline-loader上的所有loader。 返回刚刚的话题,经过pitch方法后新增的处理的loader,然后又加载了App.vue,此时由于有了incomingQuery.type,所以直接返回selectBlock的函数返回值:  此时进入selectBlock:  将我们的template的内容给了callback函数,loaderContext.callback是将vue-loader的处理结果交给下一个loader,下一个loader是templateLoader,如下图所示:  最终转换为render渲染函数。type为style和script转换过程类似。
|