Published: May 15, 2023
·
LastMod: May 15, 2023
·
984 words
vue @vue/compiler-core整体逻辑 🔗 “version”: “3.3.2”
@vue/compiler-core主要处理的是@vue/compiler-sfc模版部分,最终处理成render函数
其中主要对外暴露的有以下几个api
baseCompile baseParse transform generate baseParse 🔗 baseParse主要处理是sfc 中模版的部分(html部分),我们在写模版部分的时候,会写很多插值、指令、组件等等之类的
baseParse处理之后的结果是把模版处理成ast 对象
比如
会处理成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
type : NodeTypes . INTERPOLATION ,
content : {
type : NodeTypes . SIMPLE_EXPRESSION ,
content : `a<b` ,
isStatic : false ,
constType : ConstantTypes.NOT_CONSTANT ,
loc : {
start : { offset : 3 , line : 1 , column : 4 },
end : { offset : 6 , line : 1 , column : 7 },
source : 'a<b'
}
},
loc : {
start : { offset : 0 , line : 1 , column : 1 },
end : { offset : 9 , line : 1 , column : 10 },
source : '{{ a<b }}'
}
}
节点类型 🔗 内置以下不同的节点类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
enum NodeTypes {
ROOT ,
ELEMENT ,
TEXT ,
COMMENT ,
SIMPLE_EXPRESSION ,
INTERPOLATION ,
ATTRIBUTE ,
DIRECTIVE ,
// containers
COMPOUND_EXPRESSION ,
IF ,
IF_BRANCH ,
FOR ,
TEXT_CALL ,
// codegen
VNODE_CALL ,
JS_CALL_EXPRESSION ,
JS_OBJECT_EXPRESSION ,
JS_PROPERTY ,
JS_ARRAY_EXPRESSION ,
JS_FUNCTION_EXPRESSION ,
JS_CONDITIONAL_EXPRESSION ,
JS_CACHE_EXPRESSION ,
// ssr codegen
JS_BLOCK_STATEMENT ,
JS_TEMPLATE_LITERAL ,
JS_IF_STATEMENT ,
JS_ASSIGNMENT_EXPRESSION ,
JS_SEQUENCE_EXPRESSION ,
JS_RETURN_STATEMENT
}
transform的主要作用就是转化ast中我们写的一些特殊的语法,比如说 v-for、v-if、slot等等
这里传入的是上面编译过后的ast
第二个参数是系统内置的一些转换器和指令转换器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
transform (
ast ,
extend ({}, options , {
prefixIdentifiers ,
nodeTransforms : [
... nodeTransforms ,
...( options . nodeTransforms || []) // user transforms
],
directiveTransforms : extend (
{},
directiveTransforms ,
options . directiveTransforms || {} // user transforms
)
})
)
包括以下内置转换器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
[
transformOnce ,
transformIf ,
transformMemo ,
transformFor ,
...( __COMPAT__ ? [ transformFilter ] : []),
...( ! __BROWSER__ && prefixIdentifiers
? [
// order is important
trackVForSlotScopes ,
transformExpression
]
: __BROWSER__ && __DEV__
? [ transformExpression ]
: []),
transformSlotOutlet ,
transformElement ,
trackSlotScopes ,
transformText
],
{
on : transformOn ,
bind : transformBind ,
model : transformModel
}
]
对ast的操作其实就是递归处理, 根据上面compile的结果,每个节点其实都有不同的type,识别出不同的type,就可以对ast对象进行处理
编译的主要核心就是在transform这一块,这一块可以对最终生成的模板进行定制
generate 🔗 generate就是生成的意思
这里传入上面处理transform过的ast结果
1
2
3
4
5
6
generate (
ast ,
extend ({}, options , {
prefixIdentifiers
})
)
这里就是生成对应的render函数代码
1
2
3
4
5
6
7
8
9
10
11
return function render ( _ctx , _cache ) {
with ( _ctx ) {
return _createElementVNode ( \\ "div\\" , {
id : \\ "foo\\" ,
[ prop ] : bar ,
[ foo + bar ] : bar
}, [
_createElementVNode ( \\ "p\\" , { \\ "some-key\\" : \\ "foo\\" })
], 16 )
}
}
genNode 🔗 会进行递归调用,组装改节点类型的type,最终拼装成render执行的js函数
baseCompile 🔗 baseCompile就是一个组装函数,内部执行了上面3个函数
baseParse transform generate 最终返回编译后的render函数