理解 vue-loader

ObjectKaz Lv4

用法

Vue-Loader配置:
1. 配置 loader

1
2
3
4
{
test: /\.vue$/,
loader: 'vue-loader',
}
  1. 配置 loader-plugin
1
2
3
4
5
{
plugins: [
new VueLoaderPlugin()
]
}

VueLoaderPlugin做了什么

  1. 手动修改webpack配置,在最顶部增加了一个 pitcher,用来引入内部的 pitch-loader。(命中 xxx.vue?vue)
    2. 针对模板引入模板编译器的 template-loader(命中 xxx.vue?vue&type=template)
    3. 拷贝用户css和js的loader配置
1
2
3
4
5
6
7
compiler.options.module!.rules = [
pitcher,
...jsRulesForRenderFn,
templateCompilerRule,
...clonedRules,
...rules,
]

normal-loader(初次解析)的流程

  1. 调用 @complier/sfcparse函数,将代码编译成AST
    2. 判断查询参数是否包含 type属性,如果有则走特定语言模块的编译流程:
1
2
3
4
5
6
7
8
9
10
if (incomingQuery.type) {
return selectBlock(
descriptor,
id,
options,
loaderContext,
incomingQuery,
!!options.appendExtension
)
}
  1. 如果没有 type属性,则为每个block生成特定的import代码:
1
2
3
4
5
6
7
8
9
10
11
12
// 模板
import { render } from "./App.vue?vue&type=template&id=a9794c84&scoped=true"

// 脚本
import script from "./App.vue?vue&type=script&lang=js"
export * from "./App.vue?vue&type=script&lang=js"

// 样式
import "./App.vue?vue&type=style&index=0&id=a9794c84&scoped=true&lang=css"


// 热更新、组件导出等代码

pitch-loader的流程

上面import的 App.vue?vue会匹配 pitch-loader,这个loader主要将 ./App.vue?vue&type=template&id=a9794c84&scoped=true结合匹配规则合成完整的解析链:

1
2
3
4
5
6
7
8
9
// ./App.vue?vue&type=style&index=0&id=a9794c84&scoped=true&lang=css
export * from "-!../node_modules/.pnpm/mini-css-extract-plugin@0.11.3_webpack@4.46.0/node_modules/mini-css-extract-plugin/dist/loader.js??ref--2-0!../node_modules/.pnpm/css-loader@4.3.0_webpack@4.46.0/node_modules/css-loader/dist/cjs.js!../dist/stylePostLoader.js!../dist/index.js??ref--0!./App.vue?vue&type=style&index=0&id=a9794c84&scoped=true&lang=css"

// ./App.vue?vue&type=script&lang=js
export { default } from "-!../dist/index.js??ref--0!./App.vue?vue&type=script&lang=js";
export * from "-!../dist/index.js??ref--0!./App.vue?vue&type=script&lang=js"

// ./App.vue?vue&type=template&id=a9794c84&scoped=true
export * from "-!../dist/templateLoader.js??ref--6!../dist/index.js??ref--0!./App.vue?vue&type=template&id=a9794c84&scoped=true"

loader链整理后如下图所示(加粗为内部loader):

模板脚本样式
语言htmljscss
Loader解析链(从上到下)normal-loader
template-loader
normal-loadernormal-loader
style-post-loader
css-loader
mini-css-extract-plugin-loader

normal-loader(第二次解析)流程

根据上面解析出的loader链可以发现,所有内容会再次经过normal-loader。根据初次解析的流程,第二次解析会走 selectBlock流程:

模板脚本样式
语言htmljscss
解析流程原样返回模板内容调用 compiler-sfccompileScript方法,解析js文件原样返回对应的样式内容

template-loader做了什么

调用 compiler-sfccompileTemplate进行模板编译。

style-post-loader做了什么

调用 compiler-sfccompileStyle进行样式编译。

流程图

  • 标题: 理解 vue-loader
  • 作者: ObjectKaz
  • 创建于: 2022-08-10 17:11:31
  • 更新于: 2022-08-10 17:17:21
  • 链接: https://www.objectkaz.cn/c92a780f287b.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。