写在开头
很多人可能会问:网上关于vuejs
的文章那么多,为什么还要自己写一遍呢。
是的,确实
vuejs
相关源码的文章非常多,但很多关键点似乎就是一笔带过,看不懂的自然还是看不懂。源码就是一个知识渊博的老师,是多少人多少年知识沉淀的积累,阅读源码就是与高人对话,是提高自己的最大捷径。别人写的文章,那是别人的积累,看得懂和表达出来完全是两码事。源码也是非常值得看几十遍的读物,每看一遍都会有不同收获。
学习就好比去景区游玩,沿着自己的路线观赏,分享着自己看到的风景。每个人都有自己的感触,体会到别人无法体会到的心情。不亲身体会,你只能从别人嘴里体验他人的快乐。
目录及文件说明
老规矩,阅读源码第一步是从github
上clone
一份最新代码下来。磨刀不误砍柴工,在阅读前有必要弄清目录结构以及每个文件是干嘛用的,现在不懂如何工作的不要紧,但必须先搞明白每个文件的作用。
详细目录介绍:
├── 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的时候已经借助webpack
、vue-loader
等插件离线编译好,所以实际得到的是已经编译好的JSON对HTML结构的描述
,并已打包入对应的JS文件中了。
core
此目录才是核心中的核心,需要重点理解吃透的地方。
Vuejs的核心代码都在这里,包括内置虚拟组件keep-alive
、对全局API的封装工作、VUE实例化过程、数据响应式原理、虚拟DOM以及常用的工具函数等都包括在里面。知识的精华,绝对值得细细品味,想想作者尤大也是阅遍各种开源库,用多少年时间修修改改才形成的这套逻辑。
platforms
直白翻译过来就是:平台的入口,其中包括web
平台入口以及weex
入口。
weex
是前端极度膨胀的那几年,大有吞并IOS
跟Android
的趋势下阿里开源的一套用js驱动原生的框架,笔者2017年有用过weex
开发过一个“订单评论模块”,支持在线更新,体验还是蛮好的。可惜weex
后来被捐赠给Apache基金会
,半路夭折,这里不做过多分析。
server
与服务端渲染相关的逻辑都在这里。主要是在服务端渲染合成html代码,直接吐给浏览器去渲染,大部分逻辑在服务端完成。此部分代码运行在Node.js环境中,本系列文章暂不做介绍。
sfc
其中只包含了parser.js
一个文件。我们平时开发的都是 .vue 文件,称为SFC
(Single File Components),vue会先对.vue文件进行拆解,主要分为template
、script
、styles
三个部分,最终拆解成以.js、.css为后缀的浏览器可以解析的文件。
shared
定义的其他一些共用的工具方法。