前言
Vue3 的源码采用 模块化 Monorepo 架构,分布在 packages/
目录下。每个模块都承担着清晰的职责:有的处理模板编译,有的负责运行时渲染,有的提供响应式引擎。
理解这些模块的关系,是研究源码的第一步。
一、编译层
1. compiler-core
-
作用:模板编译的核心逻辑。
- 输入:模板字符串
<div>{{ msg }}</div>
- 输出:渲染函数源码
- 输入:模板字符串
-
特点:平台无关,只管 AST 生成和转换。
-
示例:
javascriptimport { baseParse } from '@vue/compiler-core' const ast = baseParse('<p>{{ hello }}</p>') console.log(ast.children[0].tag) // 输出 "p"
2. compiler-dom
-
作用 :扩展
compiler-core
,加入浏览器平台相关逻辑。 -
应用场景 :处理 DOM 专用指令,例如
v-model
、事件绑定。 -
示例:
cssimport { compile } from '@vue/compiler-dom' const { code } = compile('<button @click="count++">{{ count }}</button>') console.log(code) // 输出渲染函数源码字符串,内部包含 _createElementVNode 等调用
3. compiler-sfc
-
作用 :处理单文件组件(
.vue
),解析<template>
、<script>
、<style>
。 -
示例:
xmlimport { parse } from '@vue/compiler-sfc' const source = ` <template><div>{{ msg }}</div></template> <script>export default { data(){ return { msg: 'hi' } } }</script> ` const { descriptor } = parse(source) console.log(descriptor.template.content) // "<div>{{ msg }}</div>"
4. compiler-ssr
-
作用:专用于服务端渲染,输出字符串拼接代码而不是 DOM 操作。
-
示例:
javascriptimport { compile } from '@vue/compiler-ssr' const { code } = compile('<div>{{ msg }}</div>') console.log(code) // 输出包含 ctx.msg 的字符串拼接函数
二、运行时层
1. runtime-core
-
作用:Vue 运行时的核心,包含组件系统、虚拟 DOM、生命周期调度。
-
特点:不依赖任何平台 API,可移植。
-
示例:
javascriptimport { h, render } from '@vue/runtime-core' const vnode = h('h1', null, 'Hello Core') render(vnode, document.body)
2. runtime-dom
-
作用 :为浏览器环境实现
runtime-core
的渲染逻辑,调用真实的 DOM API。 -
示例:
arduinoimport { createApp } from 'vue' const App = { data: () => ({ count: 0 }), template: `<button @click="count++">{{ count }}</button>` } createApp(App).mount('#app')
3. runtime-test
-
作用:提供一个测试用渲染器,不依赖真实 DOM。
-
示例:
javascriptimport { createApp, h } from '@vue/runtime-test' const App = { render: () => h('div', 'test') } const root = {} createApp(App).mount(root) console.log(root.children[0].type) // "div"
4. server-renderer
-
作用 :在 Node.js 环境下生成 HTML 字符串,配合
compiler-ssr
使用。 -
示例:
javascriptimport { renderToString } from '@vue/server-renderer' import { createSSRApp } from 'vue' const app = createSSRApp({ template: `<h1>Hello SSR</h1>` }) const html = await renderToString(app) console.log(html) // "<h1>Hello SSR</h1>"
三、基础模块
1. reactivity
-
作用:Vue 响应式系统的核心。
-
示例:
javascriptimport { ref, effect } from '@vue/reactivity' const count = ref(0) effect(() => console.log('count changed:', count.value)) count.value++ // 触发 effect
2. shared
-
作用:公共工具函数与常量,整个源码都会用到。
-
示例:
javascriptimport { isArray } from '@vue/shared' console.log(isArray([1, 2, 3])) // true
四、整合入口
1. vue
-
作用:开发者使用的入口包,整合了所有子模块。
-
示例:
javascriptimport { createApp, ref } from 'vue' const App = { setup() { const msg = ref('Hello Vue3') return { msg } }, template: `<p>{{ msg }}</p>` } createApp(App).mount('#app')
五、模块关系图
yaml
compiler-core
/ \
compiler-dom compiler-ssr
| |
compiler-sfc server-renderer
|
vue (整合入口)
|
runtime-core ------ reactivity ------ shared
|
runtime-dom / runtime-test
六、结语
Vue3 的源码像一座"分层工厂":
- 编译层:把模板翻译成渲染函数。
- 运行时层:执行渲染函数,生成 DOM 或字符串。
- 基础模块:提供响应式与工具函数。
- 整合入口 :最终打包成
vue
,交到开发者手里。
这张导览图与示例,能帮助你快速定位源码,带着问题深入研究细节。
本文部分内容借助 AI 辅助生成,并由作者整理审核。