01_vue3源码的介绍及体验
一、源码目录结构介绍
vue3
整个的项目结构是通过monorepo
(单一代码库) 的形式来组织的。
所以说,vue3
源码所有的模块都是在packages
里面。
mono意为单一,repo意为仓库,是一种将多个项目代码存储在一个仓库里的软件开发策略。
这里呢,再浅浅说一下采用monorepo
的好处:
monorepo
最主要的好处是统一的工作流和Code Sharing
。比如我想看一个
package
的代码、了解某段逻辑,不需要找它的repo
,直接就在当前repo
;当某个需求要修改多个package
时,不需要分别到各自的repo
进行修改、测试、发版或者npm link
,直接在当前repo
修改,统一测试、统一发版。只要搭建一套脚手架,就能管理(构建、测试、发布)多个package
。代码重用将变得非常容易:由于所有的项目代码都集中于一个代码仓库,我们将很容易抽离出各个项目共用的业务组件或工具,并通过
TypeScript
,Lerna
或其他工具进行代码内引用;依赖管理将变得非常简单:同理,由于项目之间的引用路径内化在同一个仓库之中,我们很容易追踪当某个项目的代码修改后,会影响到其他哪些项目。通过使用一些工具,我们将很容易地做到版本依赖管理和版本号自动升级。
下面就开始介绍vue3源码的核心结构,由下图开始:
1、compiler-sfc
: 用来解析单文件组件,也就是.vue
文件,因为.vue
文件不能直接被浏览器解析,一般会借助webpack
的vue-loader
把template
、script
、style
部分抽离出来,然后各个模块运行各自的解析器,单独解析,而解析工作都是由compiler-sfc
模块实现的。
2、compiler-dom
: 是在compiler-core
的基础上进行的封装,是处理template
的,会把template
编译成一个render
函数。
3、runtime-dom
: 它就是基于runtime-core
创建的以浏览器为目标的运行时,包括对原生DOM API、属性、样式、事件等的管理。
4、runtime-core
: 核心运行时,包括虚拟DOM
的渲染器、组件实现和一些全局的JavaScript API。
5、reactivity
: 数据驱动是Vue.js
的核心概念之一,响应式系统
是实现数据驱动的前提。reactivity
包含了对响应式系统的实现,它是runtime-core
包的依赖,也可是作为单独的包进行使用。
二、体验
先来体验一下compiler-sfc
,此处借助rollup
的打包功能,将sfc
编译成一个js
文件。
创建一个目录,初始化进行包管理
shell# -y是生成默认package.json,省去回车 npm init -y
首先安装一下
compiler-sfc
shellnpm i @vue/compiler-sfc -s
再引入一下
rollup
及vue
官方提供的一个插件:roll-plugin-vue
shellnpm i rollup -D npm i rollup-plugin-vue -D
创建
App.vue
,webstorm
的话,可以新建文件输入vbase-css
,然后回车vue<template> <div> IamZJT </div> </template> <script> export default { setup() { } }; </script> <style></style>
接下来创建
rollup.config.js
,进行roll-up
的配置。tsimport vue from 'rollup-plugin-vue'; export default { input: './App.vue', plugin: [vue()], output: { name: 'vue', format: 'es', file: 'lib/mini-vue.esm.js' } }
配置
package.json
的scripts
json{ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup -c" } }
运行,至此,编译完成
shellnpm run build
以上,compiler-sfc
已经体验过了,可以将.vue
文件编译成js
文件。
那么compiler-dom
和compiler-core
又是用来解决什么问题的呢?
实际上是将template
转成render
函数。
将.vue
文件编译成js
文件,和将template
转成render
函数,这是两个概念。
也就是说compiler-sfc
是用到compiler-dom
和compiler-core
这两个库的。
那是怎么将template
转成render
函数的呢,这里有一个在线体验的网站:Vue 3 Template Explorer
<div id="app">
<div @click="() => console.log('IamZJT')" :id="name">{{ name }}</div>
<h1 v-if="true">技术摸鱼</h1>
<p>今天天气针不戳</p>
</div>
// render函数
import {
toDisplayString as _toDisplayString,
createElementVNode as _createElementVNode,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
createCommentVNode as _createCommentVNode
} from "vue"
// 这里`render`函数用到的这些函数,实际上都是属于vue的运行时的,都是在运行时里面去导出的。
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("div", { id: "app" }, [
_createElementVNode("div", {
onClick: () => _ctx.console.log('IamZJT'),
id: _ctx.name
}, _toDisplayString(_ctx.name), 9 /* TEXT, PROPS */, ["onClick", "id"]),
true
? (_openBlock(), _createElementBlock("h1", { key: 0 }, "技术摸鱼"))
: _createCommentVNode("v-if", true),
_createElementVNode("p", null, "今天天气针不戳")
]))
}
综上来看,compiler-sfc
依赖compiler-dom
和compiler-core
两个模块,将template
解析成render
函数,然后再交给runtime
来执行。
ps
这是一个 早起俱乐部!
⭐️ 适合人群:所有想有所改变的人,可以先从早起半小时开始!抽出30分钟,从初心开始!!
⭐️ 没有任何其它意味,只是本人想寻找一起早起、志同道合的小伙伴。