前言
本系列文章旨在通过学习阅读解析 vue3
源码,来实现并产出一个 精简版的 vue
库
小励志一下:阅读源码的过程会是痛苦的,但这一步总是要迈出去的,如果我们能咬牙坚持到最后,回过头会发现,其实我们已经走出去了很远很远。就酱,Here we go!
1. 搭建 mini-vue 项目基本结构
- 创建
mini-vue
文件夹 - 通过
VSCode
打开 - 在终端中,通过
npm init -y
创建 package.json
模块
- 创建
packages
文件夹,作为:核心代码 区域 - 创建
packages/vue
文件夹:打包、测试实例、项目整体入口模块 - 创建
packages/shared
文件夹:共享公共方法模块 - 创建
packages/compiler-core
文件夹:编译器核心模块 - 创建
packages/compiler-dom
文件夹:浏览器部分编译器模块 - 创建
packages/reactivity
文件夹:响应性模块 - 创建
packages/runtime-core
文件夹:运行时核心模块 - 创建
packages/runtime-dom
文件夹:浏览器部分运行时模块 - 在每个模块下面创建
/src/index.ts
和README.md
文件
README.md
内容示例:
# reactivity
响应性核心
2. 导入 TS 配置
想要在项目中使用 ts
构建(这里我使用的 ts
版本为 4.7.4
),那么首先我们在项目中创建对应的 tsconfig.json
配置文件。
- 在项目根目录中,创建
tsconfig.json
文件。 - 该
tsconfig.json
文件指定编译项目所需的 入口文件 和 编译器 配置 - 也可以通过以下指令来生成 包含默认配置 的
tsconfig.json
文件:
// 需要先安装 typescript
npm install -g typescript@4.7.4
// 生成默认配置
tsc -init
- 在
tsconfig.json
中指定如下配置:
// https://www.typescriptlang.org/tsconfig,也可以使用 tsc -init 生成默认的 tsconfig.json 文件进行属性查找
{
// 编辑器配置
"compilerOptions": {
// 根目录
"rootDir": ".",
// 严格模式标志
"strict": true,
// 指定类型脚本如何从给定的模块说明符查找文件。
"moduleResolution": "node",
// https://www.typescriptlang.org/tsconfig#esModuleInterop
"esModuleInterop": true,
// JS 语言版本
"target": "es5",
// 允许未读取局部变量
"noUnusedLocals": false,
// 允许未读取的参数
"noUnusedParameters": false,
// 允许解析 json
"resolveJsonModule": true,
// 支持语法迭代:https://www.typescriptlang.org/tsconfig#downlevelIteration
"downlevelIteration": true,
// 允许使用隐式的 any 类型(这样有助于我们简化 ts 的复杂度,从而更加专注于逻辑本身)
"noImplicitAny": false,
// 模块化
"module": "esnext",
// 转换为 JavaScript 时从 TypeScript 文件中删除所有注释。
"removeComments": false,
// 禁用 sourceMap
"sourceMap": false,
// https://www.typescriptlang.org/tsconfig#lib
"lib": ["esnext", "dom"],
},
// 入口
"include": ["packages/*/src"]
}
3. 引入代码格式化工具: Prettier 让代码结构更加规范
这里没有引入 eslint
因为 mini-vue
这并不是一个开源的代码仓库,所以我们无需专门导入 eslint
增加项目的额外复杂度,只需要导入 prettier
帮助我们控制代码格式即可。
- 在
VScode
扩展中,安装prettier
辅助插件 - 在项目根目录下,创建
.prettierrc.js
文件:
module.exports = {
// 结尾无分号
semi: false,
// 全部使用单引号
singleQuote: true,
// 每行长度为 80
printWidth: 80,
// 不添加尾随 , 号
trailingComma: 'none',
// 省略箭头函数括号
arrowParens: 'avoid'
};
4. 模块打包器:rollup
rollup
是一个模块打包器,和 [webpack](https://webpack.docschina.org/concepts/)
一样可以将 JavaScript
打包为指定的模块。
但是不同的是,对于 webpack
而言,它在打包的时候会产生许多 冗余的代码,这样的一种情况在我们开发大型项目的时候没有什么影响,但是如果我们是开发一个 库 的时候,那么这些冗余的代码就会大大增加库体积,这就不好美好了。
所以说我们需要一个 小而美 的模块打包器,这就是 rollup
:
Rollup
是一个JavaScript
模块打包器,可以将小块代码编译成大块复杂的代码,例如library
或应用程序。
rollup
我们可以在项目根目录下,创建 rollup.config.js
文件作为 rollup
的配置文件(就像 webpack.config.js
一样 ):
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
/**
* 默认导出一个数组,数组的每一个对象都是一个单独的导出文件配置,详细可查:https://www.rollupjs.com/guide/big-list-of-options
*/
export default [
{
// 入口文件
input: 'packages/vue/src/index.ts',
// 打包出口
output: [
// 导出 iife 模式的包
{
// 开启 SourceMap
sourcemap: true,
// 导出的文件地址
file: './packages/vue/dist/vue.js',
// 生成的包格式:一个自动执行的功能,适合作为<script>标签
format: 'iife',
// 变量名
name: 'Vue'
}
],
// 插件
plugins: [
// ts 支持
typescript({
sourceMap: true
}),
// 模块导入的路径补全
resolve(),
// 将 CommonJS 模块转换为 ES2015
commonjs()
]
}
]
安装插件依赖
npm i @rollup/plugin-commonjs@22.0.1 rollup/plugin-node-resolve@13.3.0 rollup/plugin-typescript@8.3.4 -D
npm i tslib@2.4.0 typescript@4.7.4 -D
在 package.json
中新增一个 scripts
:
"build": "rollup -c -w"
随便在 packages/vue/src/idnex.ts
中导出个变量,再执行 npm run build
,出现下图结果即说明打包成功。
5. 配置路径映射
在 tsconfig.json
中添加如下代码:
{
// 编辑器配置
"compilerOptions": {
...
// 设置快捷导入
"baseUrl": ".",
"paths": {
"@vue/*": ["packages/*/src"]
}
}
}
6. 总结
这一章应该是比较简单,只是搭建了框架雏形,并且对项目进行了结构和配置上的初始化。
做完了这些之后,接下来我们终于可以开始 源码的阅读 和 模块的实现了,嗨起来!😍