创作不易,请大家多多点赞、评论、关注哦!
我时常在找寻答案,如何学习编程,如何学好编程。下图是我喜欢的一个B站up主,他的回答让我醍醐灌顶。都说源码很重要,仅仅是阅读源码真的能提高编程水平吗?这里提出三位一体(理论、实践、思考)的循环才能使得编程水平的提高。所以不仅要阅读Vue的源码,还要模仿手写Vue,让知识成为强壮有力的翅膀,让我们飞的更高看得更远!
创建一个vue-mini
我们需要从0开始创建一个自己的vue-mini框架,因为这是一个框架,所以我们不能像创建项目一样去使用命令,下面是步骤:
- 创建一个vue-mini的文件夹;
- 通过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文件夹:浏览器部分运行时模块;
项目创建完成后,文件目录如下图:
为vue-mini框架进行配置导入ts
要想为vue-mini框架配置ts,有以下3部分需要完成:
- 在项目根目录中,创建tsconfig.json文件;
- 该tsconfig.json文件指定编译项目所需的入口文件和编译器配置;
- 通过以下指令来生产包含默认配置的tsconfig.json;
首先我们需要安装typescirpt包;
js
npm install -g typescript@4.7.4
安装完成后可以通过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/pugin-commonjs@22.0.1> <@rollup/plugin-node-resolve@13.3.0> @rollup/plugin-typescript@8.3.4
如果用cnpm安装,速度会快很多,这里也指定了版本。
js
cnpm i -D <@rollup/pugin-commonjs@22.0.1> <@rollup/plugin-node-resolve@13.3.0> @rollup/plugin-typescript@8.3.4
让我们试一下rollup的配置是否生效;在vue/src目录下新建一个index.ts文件,添加一行代码console.log('hello')
;
然后在package.json中添加一条指令,用来读取rollup的配置进行打包;
接着在终端执行npm run build
;
这里报错了,项目中使用了ts,但还缺少两个对应的插件;
js
cnpm i --save-dev <tslib@2.4.0> typescript@4.7.4
这里重新执行npm run build
,运行成功了;
在vue/dist目录下生成了打包文件,vue.js.map是用来sourceMap的;
到这呢,我们已经把rollup配置好了;
为框架配置路径映射
大家肯定会问这里的路径映射是什么呢?假设shared文件夹里面index文件,有一个判断是否是数组的方法isArray,它在多个地方需要调用,就会向下图一样导入;
在目录层级比较深的情况,相对路径十分不便;如果我们想用下图这种简便的方式引用呢?
此时就用到了ts提供的路径映射的功能了,在ts.config文件中新增一个path的配置项,帮助我们去解析指定的路径;
配置完成之后发现我们@开头的导入就没有再报错了,它指向了正确的路径; 到现在我们已经为手写Vue做好了准备;
文章的结尾,祝福大家when you love what you do!