从0到1手写mini-vue3系列——(1)源码工程初始化

前言

为了深入理解vue3框架实现的原理,我打算抽时间学习一下vue3源码。之前一直想过要学习的,但由于项目忙、静不下心、懒等原因,慢慢也就搁置了。之前也只是简单的了解过一点vue3的核心源码,只是看了看网上的文章,也没有手写过;这一次打算只保留最核心的代码,手写实现一个极简的 mini-vue3

虽然自己在学习vue3源码过程中也是一直在参考网上一些优秀作者的技术文章一点一滴过来的。但我觉得学习一个新事物,只是去看、去了解是不够的!只有自己动手实现一遍,从0到1走过这个过程,且在这个过程中加入自己的思考,这样就算是看别人的文章、案例实现出来的也能学到很多东西。

学会吸取别人精华之处,在理解透彻的基础上自己去总结、复盘,慢慢也就会变成自己的知识。有时候学习也要学会站在巨人的肩膀上前行。

文章如果存在问题,欢迎大家评论区指点、讨论。如果对你有帮助,你的点赞、评论、收藏是我最大的动力。

学习交流群可评论区获取,就不贴码了掘金不让的!

谨以此篇记录自己的学习过程,同时,也希望能够帮助到其他同学。

源码工程初始化

首先找好目标文件夹,在终端执行 npm init -y 初始化一个 package.json文件

使用 rollup 搭建 mini-vue3 源码环境

什么是 rollup

rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。

为什么是 rollup

rollup 的特点是 ES6 模块和代码 Tree-shaking;这些功能 webpack 同样支持,除此之外 webpack 还支持热模块替换、代码分割、静态资源导入等更多功能。

当开发应用时优先选择的是 webpack,但如果项目只需要打包出一个简单的 bundle 包,并是基于 ES6 模块开发的,那就可以考虑使用 rollup

rollup 相比 webpack,它更少的功能和更简单的 api,是我们在打包类库时选择它的主要原因。

基础依赖安装

  • 安装 rollup 用于我们源码的打包构建 pnpm install rollup

  • 安装 babel,使用babel需要安装核心模块@babel/core

    es6+语法写起来很爽,但是浏览器不兼容,想写的代码在浏览器上跑起来就需要使用 babel

    babel 可以将我们写的es6+的语法转换为浏览器兼容的语法,比如将箭头函数转换为普通函数等
    pnpm install @babel/core

  • rollup 与 babel 关联
    pnpm install rollup-plugin-babel

  • 浏览器兼容:将 ES6 语法转译为 ES5
    pnpm install @babel/preset-env

  • 基础依赖合并写法

    pnpm install rollup @babel/core rollup-plugin-babel @babel/preset-env -D

monorepo开发环境配置

源码目录结构:

lua 复制代码
|---packages
  |---reactivity 响应式核心
     |---src
       |---...
       |---index.js
     |---package.json
  |---shared 各模块通用方法
     |---src
       |---...
       |---index.js
     |---package.json
  |---vue 我们最终vue
     |---src
       |---...
       |---index.js 打包入口
     |---package.json

根目录下 packages 目录下每个模块都要包含src、index.js、package.json文件,且需要注意package.jsonname 字段的名称。

例如 shared模块 package.json文件的 name:@mini-vue3/shared,表示 shared 是属于 @mini-vue3依赖下的子模块

  • shared模块
js 复制代码
// package.json
{
  "name": "@mini-vue3/shared",
  "version": "1.0.0",
  "description": "",
  "main": "./src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@mini-vue3/shared": "workspace:^1.0.0"
  }
}
  • reactivity模块
js 复制代码
// package.json
{
  "name": "@mini-vue3/reactivity",
  "version": "1.0.0",
  "description": "",
  "main": "./src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@mini-vue3/shared": "workspace:^1.0.0"
  }
}

注意: 此时在 reactivity 模块中需要使用到 shared包时,就需要在当前目录下安装pnpm add @mini-vue3/shared 而依赖名称就是对应模块下 package.jsonname 字段。所以这个name字段命名要注意、使用时不要搞错了。

但此时会发现安装完后,打包测试发现包与包之间互相使用时是会报错的。 别急,往下看。

添加monorepo生效的配置文件

要想 monorepo 相关配置生效,还需要在项目根目录下新建一个 pnpm-workspace.yaml 文件:

vbnet 复制代码
packages:
  - 'packages/*'

意思是将 packages 目录下所有的目录都作为单独的包进行管理。

通过这样一个简单的配置,monorepo 开发环境就搭建好了,此时发现包与包依赖就可以互相引用了。

创建 Rollup 配置文件

rollup 的默认配置文件:项目根目录下创建 rollup.config.js文件

js 复制代码
import babel from 'rollup-plugin-babel'

// 导出 rollup 配置对象
export default {
  input: "./packages/vue/src/index.js", // 打包入口
  output: {             // 打包出口:可定义为数组,输出多种构件
    // file: 'dist/miniVue.js',   // 打包输出文件
    file: './packages/vue/dist/minivue3.js', // 打包输出文件
    // 打包格式(可选项):iife(立即执行函数)、esm(ES6 模块)、cjs(Node 规范)、umd(支持 amd + cjs)
    format: 'umd',
    //当format为iife和umd时必须提供,导出的模块名 Minivue3 将作为全局变量挂在window下
    name: 'Minivue3',
    // 开启 sourcemap 源码映射,打包时会生成 .map 文件;作用:浏览器调试ES5代码时,可定位到ES6源代码所在行;
    sourcemap: true,
  },
  // 使用 Rollup 插件转译代码
  plugins: [
    babel({
      // 忽略 node_modules 目录下所有文件(**:所有文件夹下的所有文件)
      exclude: 'node_modules/**'
    }),
  ]
}

创建 rollup 构建脚本

添加构建脚本命令,在源码根目录 package.json 中加入scripts

js 复制代码
"scripts": { 
    "dev": "rollup -c -w",
    "build": "rollup -c",
  },

脚本具体解释:

  • rollup 命令:默认会去找 node_module/bin/rollup
  • -c:config 选项,使用配置文件,默认找 rollup.config.js;
  • -w:watch 选项,监听文件变化;当文件发生变化时重新打包;

打包

执行脚本命令打包:pnpm dev 可能报错如下:

package.json中加入:

js 复制代码
"type": "module",

重新执行命令后,打包成功:

总结

至此,已经完成了一个基于 rollupmini-vue3源码的工程。 接下来可以开始专心去实现vue3中的核心api了。

相关推荐
雯0609~9 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ13 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z18 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
星星会笑滴22 分钟前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
彭世瑜42 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40443 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish43 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five44 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
临枫5411 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript