Vue源码分析及实现-搭架子

118 阅读3分钟

这一节先来把Vue源码clone下来,参考Vue源代码的项目结构与构建方案,将之用于我们实现的项目中,从现在往后的文章中都会分为分析部分实现部分,望悉知!!

分析部分

下面的就是Vue项目中的重要模块,标文字的才是需要我们关注的 image.png

如何对源码进行debugger

  1. 下载源代码
  2. 在根目录下package.json中的build命令改成"build": "node scripts/build.js -s"即可开启sourceMap

开启sourcemap.gif

  1. vue目录下examples下创建test文件夹,创建文件,导入../../dist/vue.global.js,书写测试实例.html
  2. 通过Live Serve启动页面
  3. 在浏览器控制台的Sources中查看运行代码,并进行debugger

Kapture 2023-03-16 at 16.27.24.gif

实现部分

搭架子

  1. 创建oh-vue项目
  2. npm init -y
  3. 创建packages文件夹,作为核心代码区域
  4. 创建packages/vue文件夹:打包、测试实例、项目整体入口模块
  5. 创建packages/shared文件夹:共享公共方法模块
  6. 创建packages/compiler-core文件夹:编译器核心模块
  7. 创建packages/compiler-dom文件夹:浏览器部分编译器模块
  8. 创建packages/reactivity文件夹:响应性模块
  9. 创建packages/runtime-core文件夹:运行时核心模块
  10. 创建packages/runtime-dom文件夹:浏览器部分运行时模块

参考代码:feat: 搭架子完成 · ohlyf/oh-vue@0dfc92f (github.com)

引入TypeScript

  • 全局安装typescript
npm i -g typescript
  • 验证是否安装成功
tsc -v
  • 初始化tsconfig.json
tsc -init

能看到根目录下新增了一个tsconfig.json

  • 将以下代码剪切去覆盖默认生成的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"],
		// 设置快捷导入
		"baseUrl": ".",
		"paths": {
      "@vue/*": ["packages/*/src"]
    }
	},
	// 入口
	"include": [
		"packages/*/src"
	]
}
  • 并为每个模块下面创建src/index.ts

参考代码:feat: 配置ts · ohlyf/oh-vue@a97268b (github.com)

配置prettier

本项目只需要配置prettier格式化即可,不需要eslint,防止eslint增加开发成本

  • 在根目录下创建.prettierrc文件添加如下字段:
{
  "semi": false,
  "singleQuote": true,
  "printWidth": 80,
  "trailingComma": "none",
  "arrowParens": "avoid"
}
  • 在打开的文件中右键format document配置为prettier即可

配置rollup

  • 根目录下新建rollup.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()
		]
	}
]
  • 指定packages/vue/src/index.ts为全局的打包入口
  • 配置打包出口
  • 安装三个插件的依赖,进行TS等的支持
pnpm i @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript 
  • 安装ts的支持
pnpm i tslib typescript -D
  • 安装rollup
pnpm i rollup
  • 配置根目录下package.jsonscripts
 "build": "rollup -c"
  • 运行打包
npm run build
  • 可能会出的错node:51711,把package.json中的node:'main'删除改为type:'module'

打包成功即可看到packages/vue下产生了新的dist文件夹及文件

参考代码:feat: 配置rollup打包 · ohlyf/oh-vue@bccbe97 (github.com)

明天见!!