实现 mini-vue 前置准备
前言
手把手实现 mini-vue,实现之前要了解一些前置知识:
- Vue3 新特性
- TDD 测试驱动开发
Vue3 新特性
- 性能比 Vue 2.x 快 2 倍左右
- Tree shaking 按需编译,静态节点标记、事件侦听缓存等
- Fragment、Teleport、suspense 更先进的组件
- Composition 组合 API
- Vue3 使用的是 proxy 数据代理,而 Vue2 是使用 Object.defineProperty 进行数据劫持
- 更好的 Ts 支持
- Custom renderer API 暴露了自定义渲染 API
- Vue3 的源码采用 monorepo 管理方式,实现了从模块管理到包管理的转变
TDD 测试驱动开发
Test-Driven Development
TDD 是一个开发测试代码和业务代码的工作流程,基于这个流程你可以写出具有极高测试覆盖率(通常接近90%)的代码。TDD还可以减少测试中发现比较难以定位的 BUG 的可能性。
TDD 的一般过程是:
- 写一个测试运行这个测试
- 看到预期的失败编写尽可能少的业务代码
- 让测试通过重构代码不断重复以上过程
TDD 是单元测试的一种方式,还有一种是 BDD -- Behavior-Driven Development
本文阅读时间大约为10分钟,请听笔者娓娓道来。
Vue3 项目说明
monorepo
monorepo 是管理代码的一种方式,它是指在一个项目仓库(repo)下管理多个包,即一个仓库中维护多个包。
- 优点:便于版本管理、依赖管理和模块间的引用
- 缺点:仓库体积会变大
目录
- compiler-core:与平台无关的编译器核心
- compiler-dom: 针对浏览器的编译模块
- compiler-sfc: 针对单文件解析
- compiler-ssr: 针对服务端渲染的编译模块
- reactivity:响应式系统,核心
- runtime-core:与平台无关的运行时核心
- runtime-dom: 针对浏览器的运行时。包括DOM API,属性,事件处理等
- runtime-test:用于测试
- server-renderer:用于服务器端渲染
- size-check:用来测试代码体积
- shared:多个包之间共享的内容
- template-explorer:用于调试编译器输出的开发工具
- vue:完整版本,包括运行时和编译器
想要阅读源码,可以先从 reactivity 开始,每个功能都有相应的 单测
TDD 项目准备
建议先去 Jest 官网了解以下 单测 的一些基本语法 jestjs.io/zh-Hans/doc…
- 安装 vscode 插件:Jest、Jest Runner 和 Jest Snippets
- 安装完后,在 xxx.test.js 文件中在每个 单测 之前就能看到 run 的标识
- 点击便能运行此单测
- yarn init -y
- 初始一个 package.json
- yarn add --dev jest
- 安装 jest
- 要加上 --dev,只有开发环境才会使用
- 编写测试文件
- 安装 ts 配置文件 解决 jest 代码块报错问题
- npx tsc --init
- 修改 json 文件
"lib": ["DOM","ES6"], /* Specify library files to be included in the compilation. */ "noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
- 安装相应的包
yarn add typescript --dev yarn add @types/jest --dev
// hello.js
module.exports = () => 'Hello world'
// hello.test.js
let hello = require('hello.js')
test('should get "Hello world"', () => {
expect(hello()).toBe('Hello world') // 测试成功
// expect(hello()).toBe('Hello') // 测试失败
})
注意:jest 是运行在 node 环境,支持的 commonJs,所以在 js 中要用 module.exports,并且是需要用 require 导入;
使用 EMS 配置方法
- babel 转译
- 安装
- yarn add --dev babel-jest @babel/core @babel/preset-env
// babel.config.js module.exports = { presets: [ ['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript' ] }; // 编译成 nodejs 环境下的代码
- 安装
- node 14版本后本身,加添相应字段便可支持
// package.json { "type": "module", "scripts": { "test": "NODE_OPTIONS=--experimental-vm-modules jest" } }
如果报错不能识别 NODE_OPTIONS,那么还需要安装 npm i cross-env,且修改 "test": "cross-env NODE_OPTIONS= "
// sum.js
export function add(a, b) {
return a + b;
}
// sun.test.js
import { add } from './add';
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
写在后面
本项目是参照 mini-vue 作者的项目 + 自己阅读 vue-next 的一些思考,重敲 mini-vue 的过程中,整理形成文档。
项目地址
- mini-vue:github.com/cuixiaorui/…
- vue-next:github.com/vuejs/vue-n…