跳至主要內容

Vue源码分析

yyshino大约 4 分钟

框架的基本概念

在本章中,我们对整个 vue 框架设计中的一些基本概念都做了一个了解。明确了如下基本概念:

  1. 命令式
  2. 声明式
  3. 心智负担
  4. 框架设计与取舍之间的关系
  5. 运行时
  6. 编译时
  7. 运行时 + 编译时
  8. 副作用
  9. reactivity、 runtime、compiler 三者之间的运行关系
  10. 扩展:良好的 ts 支持

当我们把这些基本概念了解清楚之后,那么下一章我们就可以准备开始构建我们的 vue 3 框架了。

编程范式之命令式编程

编程范式之声明式编程

命令式 VS声明式

什么是运行时

什么是编译时

运行时+编译时

为什么Vue要设计成一个运行时+编译时的框架呢
  • 针对于 纯运行时 而言:因为不存在编译器,所以我们只能够提供一个复杂的 JS 对象。
  • 针对于 纯编译时 而言:因为缺少运行时,所以它只能把分析差异的操作,放到 编译时 进行,同样因为省略了运行时,所以速度可能会更快。但是这种方式这将损失灵活性(具体可查看第六章虚拟 DOM ,或可点击 这里 查看官方示例)。比如 svelte,它就是一个纯编译时的框架,但是它的实际运行速度可能达不到理论上的速度。
  • 运行时 + 编译时:比如 vue 或 react 都是通过这种方式来进行构建的,使其可以在保持灵活性的基础上,尽量的进行性能的优化,从而达到一种平衡。

11:副作用

副作用指的是:当我们对数据进行settergetter操作时,所产生的一系列后果

副作用是可以产生多个的

  • setter:赋值
  • getter:取值
  • 副作用可以产生多个吗?
    • 可以的

12: Vue3框架设计概述

源码解析

目录结构

├─.github
├─.vscode
├─packages
│  ├─compiler-core // vue核心库
│  ├─compiler-dom // 浏览器相关
│  ├─compiler-sfc // 单文件组件 .vue 的编译模块
│  ├─compiler-ssr // 服务端渲染相关编译模块
│  ├─reactivity // 响应性的核心模块
│  ├─reactivity-transform // 过期
│  ├─runtime-core // 运行时的核心代码
│  ├─runtime-dom // 基于浏览器的运行时
│  ├─runtime-test // 运行时测试代码
│  ├─server-renderer // 服务端渲染相关
│  ├─sfc-playground // sfc工具 https://sfc.vuejs.org/
│  ├─shared // 共享的工具
│  ├─size-check // 运行时的包大小
│  ├─template-explorer // 相关测试
│  ├─vue // 重要:测试示例、对外暴露的入坑方法、项目打包的dist文件
│  └─vue-compat // 
├─scripts
├─test-dts
├─ SECURITY.md
├─ pnpm-lock.yaml
├─ pnpm-workspace.yaml
├─ README.md
├─ rollup.config.js
└─ tsconfig.json

Debugger

  1. 下载 vue 源代码,推荐通过 该仓库 下载指定版本(注意:出错)I直接下载 ZIP文件会导致 build
  2. 为源代码开启 sourcemap,以方便后续进行 debugger
    • 参考minimist文档,在package.json中的script build命令后加上-s即可
  3. packages/vue/examples 中,创建文件,导入 ../../dist/vue.global.js ,书写测试实例
  4. 通过Live Server 启动服务
  5. 在浏览器控制台的Sources中查看运行代码,并进行debugger

手写mini-vue

  • vue-next-mini

  • 为框架进行配置-导入ts

  • 引入prettier、eslint

  • 模块打包器rollup

    import commonjs from "@rollup/plugin-commonjs"
    import resolve from "@rollup/plugin-node-resolve"
    import typescript from "@rollup/plugin-typescript"
    
    /**
     * 默认导出的是一个数组,数组的每一个对象都是一个单独导出文件配置,详情可查:https://www.rollupjs.com/configuration-options/
     */
    export default [
         {
            // 入口文件
            input: 'packages/vue/src/index.ts',
            // 打包出口
            output:[
                // 导出 iife模式的包  iife – 自执行函数,适用于 <script> 标签(如果你想为你的应用程序创建 bundle,那么你可能会使用它)。iife 表示“自执行 函数表达式”
                {
                    // 开启sourceMap
                    sourcemap: true,
                    // 导出文件地址
                    file: './packages/vue/dist/index.ts',
                    // 生成包的格式
                    format: 'iife',
                    // 变量名
                    name: 'Vue'
                }
            ],
            // 插件 pnpm i -D @rollup/plugin-commonjs@22.0.1 @rollup/plugin-node-resolve@13.3.0 @rollup/plugin-typescript@8.3.4
            plugins: [
                // ts 455 165
                // ts tslib@2.4.0 typescript@4.7.4
                typescript({
                    sourceMap: true
                }),
                // 模块导入的路径补全
                resolve(),
                // 转commonjs 为ESM
                commonjs(),
            ]
         }
    ]