开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
01_Vue3源码的介绍及体验
🙋 Hello,I'm IamZJT!
✍️ 一名菜鸟前端开发工程师!📦 Github项目地址:zjt-mini-vue3。
🖐️ 欢迎点赞➕star,期盼与您并肩前行...
一、源码目录结构介绍
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文件。
-
创建一个目录,初始化进行包管理
# -y是生成默认package.json,省去回车 npm init -y -
首先安装一下
compiler-sfcnpm i @vue/compiler-sfc -s -
再引入一下
rollup及vue官方提供的一个插件:roll-plugin-vuenpm i rollup -D npm i rollup-plugin-vue -D -
创建
App.vue,webstorm的话,可以新建文件输入vbase-css,然后回车<template> <div> IamZJT </div> </template> <script> export default { setup() { } }; </script> <style></style> -
接下来创建
rollup.config.js,进行roll-up的配置。import vue from 'rollup-plugin-vue'; export default { input: './App.vue', plugins: [vue()], output: { name: 'vue', format: 'es', file: 'lib/mini-vue.esm.js' } } -
配置
package.json的scripts{ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup -c" } } -
运行,至此,编译完成
npm 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
🎯 如果您看到这里,请不要走开。
🎉 这是一个早起俱乐部:三更灯火五更鸡!
⭐️ 寻找 志同道合 的小伙伴,我们一起 早起。