平时写的vue都是单文件,所有的html/script/style都写在一个文件里,那么vue_loader是怎么处理的呢,就是通过vue-next/compiler-sfc/dist/compiler-sfc.cjs.js这个文件。
第一个对外暴露的接口compileStyle,用于处理style
先匹配预处理语言less,sass,scss,styl,stylus: styl,然后调用各种预处理器翻译成普通的css
const processors = {
less,
sass,
scss,
styl,
stylus: styl
};```
其中有一个很在意的modules选项,如果为真则使用postcss-modules将css变成js
处理的时候会根据
预处理之后调用
result = postcss(plugins).process(source, postCSSOptions)
依次调用插件处理css,这里返回的result是一个promise,然后在then里面把处理完的css返回。
Style上的scoped是使用vue-scoped插件实现的。该插件还会重写所有的selector,假如是@开头的,keyframes会被抽到一个对象中,并且重命名为node.params + '-' + id格式;media和support则会被进一步展开。这里还有很多对::v-slotted/::v-global/::v-deep的处理,但是没有用过,看不懂
第二个接口compileTemplate编译html模板
同样是先看预处理器,处理完之后丢到doCompileTemplate里面去,但是其实真正的编译是要看是否ssr,如果是ssr的话丢到compiler-ssr里面去,否则丢到compiler-dom里面去(有好长一段代码是讲sourceMap的)
最后一个接口parse
声明了一个结构体
filename是单文件文件名,然后分别是处理好的template/script/styles,最后一个没太看懂是干嘛的。
const descriptor = { filename, template: null, script: null, styles: [], customBlocks: [] };
首先是使用编译器生成ast树,然后分割template/script/style,还有很大一部分代码用于生成sourceMap