介绍

  • 源码采用 monorepo 方式进行管理,将模块拆分到package目录中
  • Vue3 采用ts开发,增强类型检测。 Vue2 则采用flow
  • Vue3 的性能优化,支持 tree-shaking, 不使用就不会被打包
  • Vue2后期引入RFC , 使每个版本改动可控 rfcs

内部代码优化

  • Vue3 劫持数据采用proxy ,vue2 劫持数据采用 defineProperty, defineProperty 有性能问题和缺陷
  • Vue3 中对模块编译进行了优化,编译时生成了 Block tree, 可以对子节点的动态节点进行收集,可以减少比较,并且采用 patchFlag 标记动态节点
  • Vue3 采用 compositionApi 进行组织功能,解决反复横跳,优化复用逻辑(mixin带来的数据来源不清晰,命名冲突等)相比 optionsApi 类型推断更加方便
  • 增加了Fragment, Teleport, SusPense组件

Vue3 架构分析

1.Monorepo介绍

Monorepo 是管理项目代码的一个方式,指在一个项目仓库(repo)中管理多个模块/包(package)

  • 优点:
    • 一个仓库可维护多个模块,不用到处找仓库
    • 方便版本管理和依赖管理,模块之间的引用,调用都非常方便
  • 缺点:
    • 仓库体积会变大

2.Vue3项目结构

  1. ├─packages # N个repo
  2. └─compiler-core # 与平台无关的编译器核心
  3. └─compiler-dom # 针对浏览器的编译模块
  4. └─compiler-sfc # 针对单文件解析
  5. └─compiler-ssr # 针对服务端渲染的编译模块
  6. └─reactivity # 响应式系统
  7. └─runtime-core # 与平台无关的运行时核心 (可以自定义渲染器)
  8. └─runtime-dom # 针对浏览器的运行时。包括DOM API,属性,事件处理等
  9. └─runtime-test # 用于测试
  10. └─server-renderer # 用于服务器端渲染
  11. └─shared # 多个包之间共享的内容
  12. └─size-check # 用来测试代码体积
  13. └─template-explorer # 用于调试编译器输出的开发工具
  14. └─vue # 完整版本,包括运行时和编译器
  1. +---------------------+
  2. | |
  3. | @vue/compiler-sfc |
  4. | |
  5. +-----+--------+------+
  6. | |
  7. v v
  8. +---------------------+ +----------------------+
  9. | | | |
  10. +-------->| @vue/compiler-dom +--->| @vue/compiler-core |
  11. | | | | |
  12. +----+----+ +---------------------+ +----------------------+
  13. | |
  14. | vue |
  15. | |
  16. +----+----+ +---------------------+ +----------------------+ +-------------------+
  17. | | | | | | |
  18. +-------->| @vue/runtime-dom +--->| @vue/runtime-core +--->| @vue/reactivity |
  19. | | | | | |
  20. +---------------------+ +----------------------+ +-------------------+

3.安装依赖

依赖 说明
typescript 支持ts
rollup 打包工具
rollup-plugin-typescript2 rollup 和 ts的 桥梁
@rollup/plugin-node-resolve 解析node第三方模块
@rollup/plugin-json 支持引入json
execa 开启子进程方便执行命令

必须使用yarn

  1. yarn init -y
  2. yarn add typescript rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve @rollup/plugin-json execa -D

Running this command will add the dependency to the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or —ignore-workspace-root-check

  1. tsc --init

4.目录结构:

  1. ├─packages # N个repo
  2. └─reactivity # 响应式目录
  3. package.json
  4. └─src
  5. index.ts
  6. └─shared #公共方法目录
  7. package.json
  8. └─src
  9. index.ts
  10. └─scripts # 打包命令
  11. build.js # 全部打包
  12. | | dev.js # 单个打包
  13. package.json # 配置运行命令
  14. rollup.config.js # rollup配置文件
  15. tsconfig.json # ts配置文件 更改为esnext
  16. yarn.lock

5.代码文件

代码路径:https://github.com/mewcoder/vue3-demo/tree/step1

  • package.json
  • packages/reactivity/package.json
  • packages/shared/package.json
  • scripts/build.js
  • scripts/dev.js
  • rollup.config.js
  • tsconfig.json

注意:在某个模块下引入另一个模块时,需要配置 tsconfig.json

  1. import {shared} from "@vue/shared"
  2. //找不到模块“@vue/shared”。
  3. //你的意思是要将 "moduleResolution" 选项设置为 "node",还是要将别名添加到 "paths" 选项中
  4. const reactivity = {}
  5. export {
  6. reactivity
  7. }
  1. "moduleResolution":"node",
  2. "baseUrl":".",
  3. "paths": {
  4. "@vue/*":[
  5. "packages/*/src"
  6. ]
  7. }

搭建好后执行的命令:

  1. "dev": "node scripts/dev.js",
  2. "build": "node scripts/build.js"

参考: