vue 源码解析(一)

源码之内,了无秘密。

此系列是应群内朋友所邀,抛砖引玉所用。通过分析 vue 的源码来让大家对这些新框架有更深入的了解。 让大家知其然,知其所以然。面对 bug 的时候也不会不知所措。

vue 的源代码版本我们使用v2.3.3,我们先从目录结构分析,一步一步析构。

.
├── BACKERS.md           赞助商名单
├── LICENSE              授权协议(MIT)
├── README.md            项目简介
├── benchmarks/          性能测试脚本
├── build/               项目构建脚本
├── circle.yml           Circle CI 配置文件
├── dist/                预构建的发布版本
├── examples/            入门使用例子
├── flow/                Flow类型声明
├── package.json         npm依赖
├── packages/            包含了 vue 项目所囊括的子项目或者衍生项目,
|                        会在构建过程被构建,同时以不同的包名在 npm 上面发布
├── src/                 源码
├── test/                测试代码
├── types/               Typescript 的类型描述
└── yarn.lock            Yarn依赖配置

其中最重要的当然是 src 目录里面的各个模块

.
├── compiler/       模板到html的渲染引擎
├── core/           平台无关的运行时代码
├── platforms/      平台相关的代码
├── server/         服务器渲染代码
├── sfc/            单文件解析逻辑代码,用于 comiler 模块
└── shared/         公共函数模式

分析过 vue 的大体架构,我们现在就开始分析其整体是如何组成的,我们会先从compiler package 入手

compiler package分析

package 结构

.
├── codegen
│   ├── events.js
│   └── index.js
├── directives
│   ├── bind.js
│   ├── index.js
│   └── model.js
├── error-detector.js
├── helpers.js
├── index.js
├── optimizer.js
└── parser
    ├── entity-decoder.js
    ├── filter-parser.js
    ├── html-parser.js
    ├── index.js
    └── text-parser.js

index.js module 入口

index.js中我们可以看到basicCompile, makeFunction, createCompiler三个函数, 其中仅有createCompiler为公共接口,其他均为私有接口。

那么就按照作者的思路走下去吧,看看createCompiler到底是有什么作用。

注意:vue 项目使用了 flow 作为类型检测,因此虽然 vue 是按照标准 Javascript 来写的,但是会出现诸如function baseComile (template: string, options: commpilerOptions): CompiledResult这样的函数签名,冒号后面的纯属flow所需要的类型而已,完全可以将其当作注释

createComiler 中首先创建了一个functionCompileCache作为结果的缓存, 而compile则是复制传进来的参数,同时用户自定义的modules跟directives(指令) 都会在此处进行合并,并传给baseCompile函数。 至于compileToFunctions只是单纯地将compile函数的结果中的错误码转化为Function对象

因此所有将活泼惹人喜欢的template小姐杀死变成冷冰冰的string的凶手就是隐藏在此处的baeCompile

他的整个犯罪过程分为三步

  1. 尾随(parse)
  2. 踩点(optimize)
  3. 行动(generate)

犯罪过程分析(一): parse

综合了以前各位大神的工作,比如jQuery作者John Resig, Babel作者Juriy Zaytsev,还是有Erik Arvidsson等。 看代码的话应该是直接衍生于Babel作者Jury Zaytsev的html-minifier