vuejs源码解剖 — 写在开头

1,122 阅读5分钟

写在开头

很多人可能会问:网上关于vuejs的文章那么多,为什么还要自己写一遍呢。

是的,确实vuejs相关源码的文章非常多,但很多关键点似乎就是一笔带过,看不懂的自然还是看不懂。源码就是一个知识渊博的老师,是多少人多少年知识沉淀的积累,阅读源码就是与高人对话,是提高自己的最大捷径。别人写的文章,那是别人的积累,看得懂和表达出来完全是两码事。源码也是非常值得看几十遍的读物,每看一遍都会有不同收获。

学习就好比去景区游玩,沿着自己的路线观赏,分享着自己看到的风景。每个人都有自己的感触,体会到别人无法体会到的心情。不亲身体会,你只能从别人嘴里体验他人的快乐。

目录及文件说明

老规矩,阅读源码第一步是从githubclone一份最新代码下来。磨刀不误砍柴工,在阅读前有必要弄清目录结构以及每个文件是干嘛用的,现在不懂如何工作的不要紧,但必须先搞明白每个文件的作用。

详细目录介绍:

├── src ----------------------------------- 源码核心目录地址,我们首先需要搞明白的地方(重要!重要!重要!)
│   ├── compiler -------------------------- 编译器代码的存放目录,将类HTML(template)编译为渲染函数
│   ├── core ------------------------------ 存放通用的,与平台无关的代码
│   │   ├── components -------------------- vue自带虚拟组件KeepAlive
│   │   ├── global-api -------------------- Vue构造函数挂载全局静态、属性
│   │   ├── instance ---------------------- Vue构造函数,也就是初始化的时候的关键代码
│   │   │	├── index.js ------------------ Vue初始化入口(其他文件可顺藤摸瓜,下一节将主要解剖)
│   │   ├── observer ---------------------- 响应式原理关键位置(watcher、数组监听、深度监听等等)
│   │   ├── util     ---------------------- 纯函数工具方法或属性
│   │   ├── vdom -------------------------- 创建虚拟DOM、对比打补丁的关键代码
│   ├── platforms ------------------------- 包含平台特有的相关代码,不同平台的不同构建的入口文件也在这里
│   │   ├── web --------------------------- web平台
│   │   │   ├── entry-runtime.js ---------- 运行时版,不包含模板(template)到render函数的编译器
│   │   │   ├── entry-runtime-with-compiler.js -- 构建时版,增加模板编译器(后面会详细讲到)
│   │   │   ├── entry-compiler.js --------- vue-template-compiler 包的入口文件
│   │   │   ├── entry-server-renderer.js -- vue-server-renderer 包的入口文件
│   │   │   ├── entry-server-basic-renderer.js -- 输出 packages/vue-server-renderer/basic.js 文件
│   │   ├── weex -------------------------- 适配第三方weex相关文件(暂不在我们讨论范围内)
│   ├── server ---------------------------- 服务端ssr渲染相关
│   ├── sfc ------------------------------- 包含单文件组件(.vue文件)的解析逻辑
│   ├── shared ---------------------------- 通用工具方法等
├── dist ---------------------------------- build打包文件输出目录
├── examples ------------------------------ Vue开发示例
├── flow ---------------------------------- 类型声明,[Flow]开源项目
├── packages ------------------------------ 存放独立发布的包的目录
├── scripts ------------------------------- rollup打包构建配置,若暂时不想了解rollup打包,暂时了解即可
│   ├── git-hooks ------------------------- git钩子的目录
│   ├── alias.js -------------------------- 别名配置
│   ├── config.js ------------------------- rollup配置文件
│   ├── build.js -------------------------- 对 config.js 中所有的rollup配置进行构建
│   ├── ci.sh ----------------------------- 持续集成运行的脚本
│   ├── release.sh ------------------------ 用于自动发布新版本的脚本
├── test ---------------------------------- 单元测试文件
├── package.json -------------------------- 资源包依赖配置等
├── yarn.lock ----------------------------- yarn配置锁定文件
├── .editorconfig ------------------------- 针对编辑器的编码风格配置文件
├── .flowconfig --------------------------- flow配置文件
├── .babelrc ------------------------------ babel编译配置文件
├── .eslintrc ----------------------------- eslint配置文件
├── .eslintignore ------------------------- eslint忽略配置
├── .gitignore ---------------------------- git提交忽略配置文件

以上就是目录文件的大致说明,本系列文章主要关注src目录下的源代码,能完全理解这里的代码逻辑,我们就已经受益匪浅了。其他的暂时只要混个眼熟即可,等你搞懂src文件夹内容再回头看看,其他的那都不叫事儿。

compiler

源代码中与编译相关的代码,都包含在这里了。何为编译?就是将template中的类html解析渲染成AST抽象语法数,简单说就是用JSON文件描述出你的html结构。此文件夹内代码主要用于在线把模板解析成AST语法树,但是一般来说编译是非常耗性能的,我们并不推荐实时在线编译。而实际开发一般是基于webpack脚手架进行,在build的时候已经借助webpackvue-loader等插件离线编译好,所以实际得到的是已经编译好的JSON对HTML结构的描述,并已打包入对应的JS文件中了。

core

此目录才是核心中的核心,需要重点理解吃透的地方。
Vuejs的核心代码都在这里,包括内置虚拟组件keep-alive、对全局API的封装工作、VUE实例化过程、数据响应式原理、虚拟DOM以及常用的工具函数等都包括在里面。知识的精华,绝对值得细细品味,想想作者尤大也是阅遍各种开源库,用多少年时间修修改改才形成的这套逻辑。

platforms

直白翻译过来就是:平台的入口,其中包括web平台入口以及weex入口。
weex是前端极度膨胀的那几年,大有吞并IOSAndroid的趋势下阿里开源的一套用js驱动原生的框架,笔者2017年有用过weex开发过一个“订单评论模块”,支持在线更新,体验还是蛮好的。可惜weex后来被捐赠给Apache基金会,半路夭折,这里不做过多分析。

server

与服务端渲染相关的逻辑都在这里。主要是在服务端渲染合成html代码,直接吐给浏览器去渲染,大部分逻辑在服务端完成。此部分代码运行在Node.js环境中,本系列文章暂不做介绍。

sfc

其中只包含了parser.js一个文件。我们平时开发的都是 .vue 文件,称为SFC(Single File Components),vue会先对.vue文件进行拆解,主要分为templatescriptstyles三个部分,最终拆解成以.js、.css为后缀的浏览器可以解析的文件。

shared

定义的其他一些共用的工具方法。