大白话Vue源码系列(01):万事开头难

阅读目录

  • Vue 的源码目录结构
  • 预备知识
  • 先捡软的捏

Angular 是 Google 亲儿子,React 是 Facebook 小正太,那咱为啥偏偏选择了 Vue 下手,一句话,Vue 是咱见过的最对脾气的 MVVM 框架。之前也使用过 knockout,angular,react 这些框架,但都没有让咱产生 follow 的冲动。直到见到 Vue,简直是一见钟情啊。

Vue 的官方文档已经对 Vue 如何使用提供了最好的教程,建议 Vue 新手直接去官网学习,而不要在网上找些质量参差不齐的文档去看,以免误人子弟。中文版英文版 文档写的都很地道,毕竟是国产,中文文档真心赞。不夸张地说,中文文档咱已经看了不下 5 遍了,每次都有收获,第一遍看的很慢,边看边做,之后就非常快了,主要都是扫读。英文的咱也不是看不了,只是速度问题,没必要较这个劲。值得一提的是,Vue 每次版本更新官方文档迅速都会跟进到最新,所以说 Vue 的官方文档是学习 Vue 的不二之选。

本系列的目的不是介绍如何使用 Vue,而是希望把 Vue 的源码实现思路简单清晰地描绘出来,从而摸清一个 MVVM 框架是如何工作的,并从中学习封装轮子(库或框架)的各种实用技巧。文章中的不足和欠缺之处,请大家多多指教/抱拳。

Vue 版本:2.5.9

Vue 的源码目录结构

如果直接去看 Vue 生成的代码文件 Vue.js,代码足足有上万行。这样去研究源码肯定是行不通的,也是不明智的。从 Vue 项目的目录结构入手是个不错的选择,这么大的项目,一个好的目录结构对开发和维护的重要性不言而喻。

Vue 源码目录如下:

Vue 源码目录

各目录和文件功能:

  • compiler
    此目录存放编译模板相关的代码,用于将 html 模板编译成 Vue 的 render 函数
  • runtime
    此目录存放 Vue 生命周期内使用的相关代码,负责 Vue 实例的创建,视图渲染和处理虚拟 DOM 等等一切编译 html 模板之外的事情。
  • server
    这里存放 Vue 服务端渲染(SSR)需要使用的代码。
  • util
    这里存放一些其他模块共用的工具函数。
  • entry-compiler.js
    该文件是一个提供编译 html 模板相关接口的模块,通常用于为 Vue 编写的构建插件,比如 vue-loadervueify
  • entry-runtime.js
    用于构建仅包含运行时的文件,不具备编译 html 模板功能。
  • entry-runtime-with-compiler.js
    用于构建同时包含编译器和运行时的全功能文件。
  • entry-server-basic-renderer.js 和 entry-server-renderer.js
    用于构建服务端渲染可用的文件。

可见 Vue 按照功能块对整个项目进行了目录拆分,每个目录负责一块功能,接下来就可以从这些 entry 文件入手按照 模块依赖 进行由浅及深,从整体到局部的深入剖析。

在继续之前咱们可以先看一下由上面这些源代码构建出来的可用文件是怎么样的。

Vue 构建生成的目录如下:

Vue 构建生成的目录

各文件功能:

UMD CommonJS ES Module
Full vue.js vue.common.js vue.esm.js
Runtime-only vue.runtime.js vue.runtime.common.js vue.runtime.esm.js

表格中的术语解释:

  • Full:包含编译器和运行时的全部功能。
  • Runtime-only:仅包含运行时。
  • UMD:可通过 <script> 标签引入直接在浏览器中使用,Vue 会暴露一个全局变量 window.Vue。同时适配 require.js 这种 AMD 系统的使用。
  • CommonJS:适配 const Vue = require(‘vue‘) 这种 node 式的模块系统。
  • ES Module:适配 import Vue from ‘vue‘ 这种 es6 提供的模块系统。

这些被构建出来的文件才是咱们在实际项目中可以直接使用的文件。

是用 Full 还是用 Runtime-only ?
这个需要具体情况具体分析。如果你需要使用 Vue 提供的 html 模板功能,那么就使用 Full 版本。否则,最好用 Runtime-only 版本,因为它比 Full 版本的文件体积会小上 30% 左右。值得注意的是,*.vue 单文件组件会被 vue-loader 或 vueify 直接构建成 JavaScript,并没有使用到 Vue 的编译器,因此可使用 Runtime-only 版本。

预备知识

# Flow

Vue 使用了 Facebook 出品的 flow.js 作为静态类型检查工具,所以特意跑到 flow 的官网了解了一下(不然看到一些奇怪的写法会一脸懵逼),发现其实很简单,就是在变量或函数签名的地方加上一些类型注解,而且都是可选项,加不加都行,主要是为了方便开发维护用的。

为什么选择 FLow 而不是 TypeScript ?
Vue 是想找一个静态类型检查工具以便提高项目的开发效率和可维护性。Flow 和 TypeScript 都提供了静态类型检查功能,但 TypeScript 提供了更多的有用功能,静态类型检查只是 TypeScript 提供的诸多强大功能里并不起眼的一个。而 Flow 则不一样,静态类型检查几乎是它的全部,可以说是典型小而美的实现。可能是本着杀鸡焉用牛刀,尽可能降低项目复杂度的想法,Vue 选择了 Flow 而不是 TypeScript。无独有偶,Vue 的构建工具选择了 rollup 而不是 webpack,原因应该也是如出一辙。所以说最强的不一定是最好的,最合适的才是最好的。

# ES6

Vue 的源码完全使用 ES6 编写,使得代码更清晰,更易维护。本系列的所有代码片段亦全部使用 ES6,不熟悉 ES6 的同学是时候加强学习了,这可是 JavaScript 的未来。如果想系统了解一下 ES6 的话推荐阮一峰老师的 ECMAScript 6 入门 教程。

# Rollup

Vue 使用了 Rollup 作为最后的打包工具。并且使用了 Rollup 的 rollup-plugin-alias 插件,该插件可以为目录取一个别名,使得在编写 ES6 代码 import 模块时可以使用更短的路径,而不用每次都小心翼翼地去拼相对路径,非常方便。如果不了解这一点,在看到 import config from ‘core/config‘ 这种语句时可能会很迷惑,同级目录下并没有 core 目录啊,实际上 core 是 Vue 为其他目录配置的别名。这个映射表可以在 build/alias.js 文件中找到,映射表中有一条 core: resolve(‘src/core‘)resolve(‘src/core‘) 会解析出 core 目录的绝对路径,这其实就是告诉 rollup 在解析 import config from ‘core/config‘ 时从这个绝对目录中去加载 config.js

先捡软的捏

从源码的目录结构可以看出,Vue 的 runtime 模块负责的事情很多,代码量必然也很大,应该是块难啃的骨头。而 compiler 则只负责将 html 模板转换为 Vue 的 render 函数,这一块应该是水很浅的,因此从这块入手先吃掉它一部分。

本系列将以每周一篇的速度定时更新,喜欢的小伙伴可以点推荐哦。

时间: 2024-10-13 22:22:22

大白话Vue源码系列(01):万事开头难的相关文章

大白话Vue源码系列目录

.first-level{ font-size: 1.2rem; cursor: default; color: #666; } .second-level{ font-size: 1.1rem; padding-left: 2.4rem; } .order-number{ float: left; margin-right: .8rem; text-decoration: none; } .latest-update{ color: #4cae4c !important; } Angular

hbase源码系列(十三)缓存机制MemStore与Block Cache

这一章讲hbase的缓存机制,这里面涉及的内容也是比较多,呵呵,我理解中的缓存是保存在内存中的特定的便于检索的数据结构就是缓存. 之前在讲put的时候,put是被添加到Store里面,这个Store是个接口,实现是在HStore里面,MemStore其实是它底下的小子. 那它和Region Server.Region是什么关系? Region Server下面有若干个Region,每个Region下面有若干的列族,每个列族对应着一个HStore. HStore里面有三个很重要的类,在这章的内容都

vueJs源码解读0-1

vue源码解读-1 在github上下载到源码的后在src的目录下也即是该所有分块的源文件的地址所在的地方,使用webstrom在file–>Settings–>languages&Frameworks中选择javascript使用ECMAScript6 1. index.js import Vue from './instance/vue' import installGlobalAPI from './global-api' import { inBrowser, devtools

Vue源码探究-事件系统

Vue源码探究-事件系统 本篇代码位于vue/src/core/instance/events.js 紧跟着生命周期之后的就是继续初始化事件相关的属性和方法.整个事件系统的代码相对其他模块来说非常简短,分几个部分来详细看看它的具体实现. 头部引用 import { tip, toArray, hyphenate, handleError, formatComponentName } from '../util/index' import { updateListeners } from '../

vue源码之响应式数据

分析vue是如何实现数据响应的. 前记 现在回顾一下看数据响应的原因. 之前看了vuex和vue-i18n的源码, 他们都有自己内部的vm, 也就是vue实例. 使用的都是vue的响应式数据特性及$watchapi. 所以决定看一下vue的源码, 了解vue是如何实现响应式数据. 本文叙事方式为树藤摸瓜, 顺着看源码的逻辑走一遍, 查看的vue的版本为2.5.2. 目的 明确调查方向才能直至目标, 先说一下目标行为: vue中的数据改变, 视图层面就能获得到通知并进行渲染. $watchapi监

jQuery 源码学习 - 01 - 简洁的 $(&#39;...&#39;)

首先贴上学习参考资料:[深入浅出jQuery]源码浅析--整体架构,备用地址:chokcoco/jQuery-. jQuery 库,js 开发的一个里程碑,它的出现,让网页开发者们告别荒蛮的上古时代,初步解放生产力,正式进入黄铜时代. 虽然如今 Angular/React/Vue 三驾马车驰骋畋猎,jQuery的时代渐行渐远,但是它的思想它的设计都有着里程碑式的作用.当然,我是拿它来补基础的,逃... 1.自执行函数 (function(params) { // ... })(Variable)

[Vue源码]一起来学Vue模板编译原理(一)-Template生成AST

本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vue模板编译原理(一)-Template生成AST 一起来学Vue模板编译原理(二)-AST生成Render字符串 一起来学Vue虚拟DOM解析-Virtual Dom实现和Dom-diff算法 这些文章统一放在我的git仓库:https://github.com/yzsunlei/javascrip

vue源码解读(一)Observer/Dep/Watcher是如何实现数据绑定的

欢迎star我的github仓库,共同学习~目前vue源码学习系列已经更新了5篇啦~ https://github.com/yisha0307/... 快速跳转: Vue的双向绑定原理(已完成) 说说vue中的Virtual DOM(已完成) React diff和Vue diff实现差别 Vue中的异步更新策略(已完成) Vuex的实现理解 Typescript学习笔记(持续更新ing) Vue源码中闭包的使用(已完成) 介绍 最近在学习vue和vuex的源码,记录自己的一些学习心得.主要借鉴

hbase源码系列(二)HTable 如何访问客户端

hbase的源码终于搞一个段落了,在接下来的一个月,着重于把看过的源码提炼一下,对一些有意思的主题进行分享一下.继上一篇讲了负载均衡之后,这一篇我们从client开始讲吧,从client到master再到region server,按照这个顺序来开展,网友也可以对自己感兴趣的部分给我留言或者直接联系我的QQ. 现在我们讲一下HTable吧,为什么讲HTable,因为这是我们最常见的一个类,这是我们对hbase中数据的操作的入口. 1.Put操作 下面是一个很简单往hbase插入一条记录的例子.