vue-loader源码解读
调试
新增script调试脚本

npm run debug后打开chrome://inspect/,即可看到对应位置断点

初始化
webpack的插件要求是一个包含了apply方法的对象,将被其自动回调
为loader打标记
当编译对象创建后,读取loader并标记vue-loader为true,表示用户通过plugin方式注入webpack而不是直接作为loader使用

格式化
借用webpack的工具类,对用户定义的rules做校验并格式化处理

处理后的形式统一为

校验
校验是否在rules中配置了vue-loader以及配置的合法性

扩展loader
最后将vue-loader扩展成多个子loader,比如专门处理template模版的

最终给到webpack的loader数要远远超过用户定义的5个

loader的调用
当匹配到.vue文件后,将执行dist/index文件,即入口

另外,loader的调用一定是伴随着require发生的,就像浏览器中的script标签会相对应的发起一次ajax请求一样,这是一次重复的动作,那也就意味着在apply中对编译对象的监听会不断被调用

.vue文件的处理
当webpack首次加载到app.vue时,读取到的源代码如下

调用vue提供的模板编译能力,对字符串做解析

这将提取出三个核心属性:script、style和template

针对这三个属性,将被包装成三个import

结果如下

此时只需要再分别定义三个具体的loader来拦截处理即可

script
对于上一步loader转换的结果,将被webpack在沙箱中执行,这将唤起新一轮的require、compile、runLoader、build过程

本次将进入script loader作处理,这里最核心的就是调用了下vue的compileScript函数

结果如下

template
与script逻辑一致,只不过调用的是compileTemplate,结果如下

style
与前两个稍微有点不同,它会在css-loader之前插入其自己实现的style-loader以解决cssVar以及scoped等问题

结果如下

最后
将作为render设置到script配置中并导出

如此,在vue中其实就省略了编译阶段了
