为了学源码,我决定手写一个Vue之搭建框架

创作不易,请大家多多点赞、评论、关注哦!

我时常在找寻答案,如何学习编程,如何学好编程。下图是我喜欢的一个B站up主,他的回答让我醍醐灌顶。都说源码很重要,仅仅是阅读源码真的能提高编程水平吗?这里提出三位一体(理论、实践、思考)的循环才能使得编程水平的提高。所以不仅要阅读Vue的源码,还要模仿手写Vue,让知识成为强壮有力的翅膀,让我们飞的更高看得更远!

创建一个vue-mini

我们需要从0开始创建一个自己的vue-mini框架,因为这是一个框架,所以我们不能像创建项目一样去使用命令,下面是步骤:

  1. 创建一个vue-mini的文件夹;
  2. 通过VSCode打开;
  3. 在终端中,输入命令 npm init -y,用来创建package.json模块;
  4. 创建packages文件夹,作为核心代码区域;
  5. 创建packages/vue文件夹:打包、测试实例、项目整体入口模块;
  6. 创建packages/shared文件夹:共享公共方法模块;
  7. 创建packages/compiler-core文件夹:编辑器核心模块;
  8. 创建packages/compiler-dom文件夹:浏览器部分编辑器模块;
  9. 创建packages/reactivity文件夹:响应性模块;
  10. 创建packages/runtime-core文件夹:运行时核心模块;
  11. 创建packages/runtime-dom文件夹:浏览器部分运行时模块;

项目创建完成后,文件目录如下图:

为vue-mini框架进行配置导入ts

要想为vue-mini框架配置ts,有以下3部分需要完成:

  1. 在项目根目录中,创建tsconfig.json文件;
  2. 该tsconfig.json文件指定编译项目所需的入口文件和编译器配置;
  3. 通过以下指令来生产包含默认配置的tsconfig.json;

首先我们需要安装typescirpt包;

js 复制代码
npm install -g [email protected]

安装完成后可以通过tsc -v查看版本号; 接着通过tsc -init命令生成ts.config文件,这里提供了ts.config可以直接拷贝使用,每一项都有注释或链接,链接可直达官方文档;

js 复制代码
// 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"],
  // 设置快捷导入
  "baseUrl": ".",
  "paths": {
    "@vue/*": ["packages/*/src"]
  }
}

引入代码格式化工具prettier

Vue源码里是配置了eslint和prettier做代码的格式校验,但我们去写一个框架是没有必要去引入eslint,我们只要保证代码的格式是正确的,不需要再去提高开发的复杂度,所以我们的项目中只引入prettier;

1.在VSCode的扩展中,安装prettier辅助插件;

2.在项目的根目录下,创建.prettierrc文件,我的prettier配置如下可供参考;

js 复制代码
{
  "semi": false, // 去掉末尾的分号
  "singleQuote": true, // 改成单引号
  "printWidth": 80, // 每一行代码的长度
  "trailingComma": "none", // 不尾随添加逗号
  "arrowParens": "avoid" // 箭头函数
}

3.我们的prettier配置成功啦;

模块打包器:rollup

rollup和webpack一样是一个模块打包器,但不同的是,webpack打包的时候会产生很多的冗余代码,这在大型项目中没有什么影响,但如果我们开发一个库时,这些冗余的代码就会大大增加库的体积,这样就弊大于利了。因此我们选用小而美的rollup作为打包器;

如何在我们的项目中配置rollup?

首先在根目录下创建rollup.config.js文件,配置如下:

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()
		]
	}
]

我们指定生成的bundle的格式是iife,这里官方文档有解释:

这里还需要安装3个包:

js 复制代码
npm i -D <@rollup/[email protected]> <@rollup/[email protected]> @rollup/[email protected]

如果用cnpm安装,速度会快很多,这里也指定了版本。

js 复制代码
cnpm i -D <@rollup/[email protected]> <@rollup/[email protected]> @rollup/[email protected]

让我们试一下rollup的配置是否生效;在vue/src目录下新建一个index.ts文件,添加一行代码console.log('hello');

然后在package.json中添加一条指令,用来读取rollup的配置进行打包;

接着在终端执行npm run build;

这里报错了,项目中使用了ts,但还缺少两个对应的插件;

js 复制代码
cnpm i --save-dev <[email protected]> [email protected]

这里重新执行npm run build,运行成功了;

在vue/dist目录下生成了打包文件,vue.js.map是用来sourceMap的;

到这呢,我们已经把rollup配置好了;

为框架配置路径映射

大家肯定会问这里的路径映射是什么呢?假设shared文件夹里面index文件,有一个判断是否是数组的方法isArray,它在多个地方需要调用,就会向下图一样导入;

在目录层级比较深的情况,相对路径十分不便;如果我们想用下图这种简便的方式引用呢?

此时就用到了ts提供的路径映射的功能了,在ts.config文件中新增一个path的配置项,帮助我们去解析指定的路径;

配置完成之后发现我们@开头的导入就没有再报错了,它指向了正确的路径; 到现在我们已经为手写Vue做好了准备;

文章的结尾,祝福大家when you love what you do!

相关推荐
萌萌哒草头将军1 小时前
⚡⚡⚡尤雨溪宣布开发 Vite Devtools,这两个很哇塞 🚀 Vite 的插件,你一定要知道!
前端·vue.js·vite
小彭努力中2 小时前
7.Three.js 中 CubeCamera详解与实战示例
开发语言·前端·javascript·vue.js·ecmascript
浪裡遊2 小时前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
滿2 小时前
Vue3 Element Plus el-tabs数据刷新方法
javascript·vue.js·elementui
敲厉害的燕宝3 小时前
Pinia——Vue的Store状态管理库
前端·javascript·vue.js
麦麦大数据4 小时前
vue+neo4j+flask 音乐知识图谱推荐系统
vue.js·mysql·flask·知识图谱·neo4j·推荐算法·音乐推荐
GUIQU.5 小时前
【Vue】单元测试(Jest/Vue Test Utils)
前端·vue.js
前端张三6 小时前
vue3中ref在js中为什么需要.value才能获取/修改值?
前端·javascript·vue.js
会飞的鱼先生7 小时前
vue3 内置组件KeepAlive的使用
前端·javascript·vue.js
苹果酱05677 小时前
【Azure Redis 缓存】在Azure Redis中,如何限制只允许Azure App Service访问?
java·vue.js·spring boot·mysql·课程设计