持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
前言
小伙伴们好,这是村长《Vue经典面试题源码级详解》系列文章第32题,前面已完成题目合集在此: 历时一个月,2.6W字!50+Vue经典面试题源码级详解,你值得收藏!
学习群
我组织了一个面试学习群,关注村长公众号村长学前端
,回复“加群”,大家一起卷~
相关学习资源
本系列有配套视频
,思维导图
和开源项目
,大家学习同时千万不要忘了三连
+ 关注
+ 分享
,有道是喝水不忘挖井人~
- 视频教程:56道经典Vue面试题详解
- 思维导图:Vue面试专题
- 配套代码:vue-interview
分析
这是一道工具类的原理题目,相当有深度,具有不错的人才区分度。
体验
使用官方提供的SFC playground可以很好的体验vue-loader。
有了vue-loader加持,我们才可以以SFC的方式快速编写代码。
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!',
}
},
}
</script>
<style>
.example {
color: red;
}
</style>
复制代码
思路
vue-loader
是什么东东vue-loader
是做什么用的vue-loader
何时生效vue-loader
如何工作
回答范例
vue-loader
是用于处理单文件组件(SFC,Single-File Component)的webpack loader- 因为有了
vue-loader
,我们就可以在项目中编写SFC格式的Vue组件,我们可以把代码分割为<template>
、<script>
和<style>
,代码会异常清晰。结合其他loader我们还可以用Pug编写<template>
,用SASS编写<style>
,用TS编写<script>
。我们的<style>
还可以单独作用当前组件。 - webpack打包时,会以loader的方式调用
vue-loader
vue-loader
被执行时,它会对SFC中的每个语言块用单独的loader链处理。最后将这些单独的块装配成最终的组件模块。
知其所以然
vue-loader
会调用@vue/compiler-sfc
模块解析SFC源码为一个描述符(Descriptor),然后为每个语言块生成import代码,返回的代码类似下面:
// source.vue被vue-loader处理之后返回的代码
// import the <template> block
import render from 'source.vue?vue&type=template'
// import the <script> block
import script from 'source.vue?vue&type=script'
export * from 'source.vue?vue&type=script'
// import <style> blocks
import 'source.vue?vue&type=style&index=1'
script.render = render
export default script
复制代码
- 我们想要script块中的内容被作为js处理(当然如果是
<script lang="ts">
被作为ts处理),这样我们想要webpack把配置中跟.js匹配的规则都应用到形如source.vue?vue&type=script
的这个请求上。例如我们对所有*.js配置了babel-loader
,这个规则将被克隆并应用到所在Vue SFC的<script>
块上。内部的请求如下:
import script from 'source.vue?vue&type=script'
复制代码
将被展开为:
import script from 'babel-loader!vue-loader!source.vue?vue&type=script'
复制代码
类似的,如果我们对.sass文件配置了style-loader
+ css-loader
+ sass-loader
,下面的代码:
<style scoped lang="scss">
复制代码
vue-loader
将会返回给我们下面请求:
扫描二维码关注公众号,回复:
14247274 查看本文章

import 'source.vue?vue&type=style&index=1&scoped&lang=scss'
复制代码
然后webpack会展开如下:
import 'style-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
复制代码
- 当处理展开请求时,
vue-loader
将被再次调用。这次,loader将会关注那些有查询串的请求,且仅针对特定块,它会选中特定块内部的内容并传递给后面匹配的loader。 - 对于
<script>
块,处理到这就可以了,但是<template>
和<style>
还有一些额外任务要做,比如:
- 需要用Vue模板编译器编译
template
,从而得到render
函数 - 需要对
<style scoped>
中的CSS做后处理(post-process),该操作在css-loader
之后但在style-loader
之前
实现上,这些附加的loader需要被注入到已经展开的loader链上,最终的请求会像下面这样:
// <template lang="pug">
import 'vue-loader/template-loader!pug-loader!source.vue?vue&type=template'
// <style scoped lang="scss">
import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
复制代码
写在最后
时间紧俏,如有考虑不周,希望小伙伴们多多在评论区留言反馈。 如果觉得村长写的不错,请点赞支持一下~