从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了。

相关推荐
诗书画唱1 分钟前
【前端面试题】JavaScript 核心知识点解析(第二十二题到第六十一题)
开发语言·前端·javascript
excel8 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子15 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构21 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep23 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss27 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风27 分钟前
html二次作业
前端·html
江城开朗的豌豆31 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵31 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮34 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf