深入vue - 源码目录及构建过程分析
公众号原文链接:深入vue - 源码目录及构建过程分析 喜欢本文可以扫描下方二维码关注我的公众号 「前端小苑」
“ 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整体有一个认知,有助于后续对源码的阅读。”
一、目录结构

上图是对vue的代码的所有目录进行的梳理,其中源码位于src目录下,下面对src下的目录进行介绍。
compiler
该目录是编译相关的代码,即将 template 模板转化成 render 函数的代码。
vue 提供了 render 函数,render 函数作用是用来创建 VNode,但在平时开发中,绝大多数情况下使用 template 来创建 HTML,所以需要将 template模板编译成 render 函数。
编译工作既可以在代码构建时做,也可以在客户端运行时做,但编译十分消耗性能,所以在项目中建议使用 runtime 版本。
core
这部分代码是 vue 的核心代码,可以说是 vue 的灵魂所在,也是我们要重点学习的源码。
core目录又包含如下子目录。
components -- 内置组件的代码,即 keep-alive 代码
global-api -- 全局API代码,mixin,extend 等 api 在这里实现
instance -- vue实例化相关代码,包括初始化,事件,生命周期,渲染等部分的代码
observer -- 响应式数据相关代码
util -- 工具方法
vdom -- 虚拟 dom 的代码。
platforms
platforms下包含两个子目录,web 和 weex。
分别代表可以打包生成在web端使用的 vue 代码和在native端使用的 weex 代码。美团开源的开发微信小程序的 mpvue 框架也是在这个目录下进行拓展的。
通过不同平台的入口就可以打包出运行在不同平台的版本的 vue 文件,后面代码构建部分会介绍具体的构建过程。
server
该目录下是 SSR 相关的代码。
Vue.js 是构建客户端应用程序的框架。除了可以在浏览器中输出 Vue 组件,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
sfc
我们平时开发时,都是写 .vue 文件。sfc 的代码就是提供一个解析器,把.vue文件代码解析成一个 javascript 对象。
shared
该目录下定义了一些公用的工具方法,提供给上面的几个目录内代码使用。
二、源码编译
vue的源码按照功能拆分的十分清晰,每个功能都有单独的目录,那么项目中引用的vue文件是怎么编译出来的呢?
首先,我们看一下编译输出的dist目录。

可以看到,dist下有10几种不同版本的vue文件,他们是根据不同规范(包括 CommonJS规范,ES Module,UMD)和 是否包含编译器 构建出的不同版本。
vue源码选择了rollup进行构建,rollup相比于webpack,更加轻量,编译后的代码更加干净,更适合javascript库的构建,除了vue以外,像React,Ember,D3,Three.js 以及其他很多开源库也选择了Rollup 进行构建。
下面看一下vue具体构建过程,首先到pakage.json中看下vue编译执行的命令。

从命令可以看出,构建命令就是执行 scripts 目录下 build.js 文件。
下面是 scripts/build.js 核心代码(下文中汉字注释部分是为方便理解自己补充的)

从代码可以看出,首先通过 script/config.js 文件的getAllBuilds方法获取配置,然后根据构建命令传入的参数对配置进行过滤,最后根据过滤后的配置执行build函数,编译出对应版本的vue文件。(这里介绍代码构建的过程,主要说明vue是怎么构建出不同版本代码的,build方法在此不做分析)
接下来我们在看一下配置文件 script/config.js 中的 getAllBuilds 是怎么获取具体配置的。

可以看出,getAllBuilds 方法首先通过 Object.keys 拿到 builds 对象所有key的组成的数组,并通过map遍历执行genConfig方法。下面我们先看一下builds对象。

可以看出,builds对象是不同版本vue的编译配置。具体配置项的作用,已经用注释在代码中标出。接下来我们看下genConfig函数做了什么。

genConfig 通过 key 拿到 builds 中每个key对应的配置对象,然后根据这个对象重新定义一个 config 对象,这个 config 对象的结构才是 rollup 配置真正需要的结构。
看了 builds 对象和 genConfig 方法,我们就知道了 getAllBuilds 的目的,是通过映射把 builds 配置对象转化成 rollup 所需要的配置数据。
到这里,我们就清楚是如何构建出不同版本的vue代码了。
三、心得
学习源码时,不建议按照源码的顺序一行一行的阅读。首先要抓住主干,先梳理清楚主要的代码逻辑,再去仔细阅读具体的每行代码。另外按照源码顺序阅读可能很枯燥,很难坚持下来,可以先选择自己感兴趣的部分进行学习,最后再串联起来。
如果喜欢本文请扫描关注公众号前端小苑,下一篇vue源码文章,将为大家介绍 render 函数和 Virtual DOM 。

深入vue - 源码目录及构建过程分析的更多相关文章
- vue源码构建代码分析
这是xue源码学习记录,如有错误请指出,谢谢!相互学习相互进步. vue源码目录为 vue ├── src #vue源码 ├── flow #flow定义的数据类型库(vue通过flow来检测数据类型 ...
- 大白话Vue源码系列(01):万事开头难
阅读目录 Vue 的源码目录结构 预备知识 先捡软的捏 Angular 是 Google 亲儿子,React 是 Facebook 小正太,那咱为啥偏偏选择了 Vue 下手,一句话,Vue 是咱见过的 ...
- Vue 源码解读(1)—— 前言
当学习成为了习惯,知识也就变成了常识. 感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog ...
- Vue源码学习一 ———— Vue项目目录
Vue 目录结构 可以在 github 上通过这款 Chrome 插件 octotree 查看Vue的文件目录.也可以克隆到本地.. Vue 是如何规划目录的 scripts ------------ ...
- Vue.js 源码目录设计(二)
Vue.js 的源码都在 src 目录下,其目录结构如下. src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── se ...
- 手牵手,从零学习Vue源码 系列一(前言-目录篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 手牵手,从零学习Vue源码 系列三(虚拟DOM篇) 陆续更新中... 预计八月中旬更新 ...
- 大白话Vue源码系列(02):编译器初探
阅读目录 编译器代码藏在哪 Vue.prototype.$mount 构建 AST 的一般过程 Vue 构建的 AST 题接上文,上回书说到,Vue 的编译器模块相对独立且简单,那咱们就从这块入手,先 ...
- 大白话Vue源码系列(03):生成AST
阅读目录 AST 节点定义 标签的正则匹配 解析用到的工具方法 解析开始标签 解析结束标签 解析文本 解析整块 HTML 模板 未提及的细节 本篇探讨 Vue 根据 html 模板片段构建出 AST ...
- 大白话Vue源码系列(03):生成render函数
阅读目录 优化 AST 生成 render 函数 小结 本来以为 Vue 的编译器模块比较好欺负,结果发现并没有那么简单.每一种语法指令都要考虑到,处理起来相当复杂.上篇已经生成了 AST,本篇依然对 ...
随机推荐
- JBOSSAS 5.x/6.x 反序列化命令执行漏洞(CVE-2017-12149)
本文主要记录一下JBOSSAS 5.x/6.x 反序列化命令执行漏洞的测试过程 仅供学习 文中利用到漏洞环境由phith0n维护: JBoss 5.x/6.x 反序列化漏洞(CVE-2017-1214 ...
- python命令行使用的问题
python命令行使用的时候要注意一个陷阱,就是如果某个语句不是在>>>下执行的,而是在...下执行的,那么它可能没有执行成功. 例如如下没有成功,原因是上面有一句注释,导致没有执行 ...
- D3中的each() 以及svg defs元素 clipPath的使用
each() 方法允许我们定制对选择集中DOM元素的处理行为: selection . each ( func ) 参数 func 是调用者定义的函数,在d3中被称为 访问器/accessor . d ...
- Java面试官最常问的volatile关键字
在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...
- bootstrap模态对话框(最简单)
根据公司的需求,需要一个对话框来返回给客户的失败原因,刚刚开在百度上搜了老半天,嫩是没有搜索一个自己想要的,后来发送私信给一个博友,经过他哪里找到了自己想要的答案,废话不多说直接看源码: <!D ...
- expdb和impdb使用方法
一 关于expdp和impdp 使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具 ...
- SSH整合配置文件概括
配置方式一:struts.xml, applicationContext.xml(hibernate.cfg.xml配置信息写入spring配置文件中) (版本号, struts2:2.3.15; s ...
- Python之深浅拷贝
拷贝就是拷贝,何来深浅之说? Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果 其实这个是由于共享内存导致的结果 浅拷贝 l1 = [1,2,3 ...
- Rest接口和Thymeleaf的两个坑
spring boot thymeleaf 热部署 在使用spring boot 开发的时候,使用了Thymeleaf 作为前端的模板开发,发现在调试过程中,改动了Thymeleaf模板后,需要重新启 ...
- Nginx与Lua
http://www.cnblogs.com/xd502djj/archive/2012/11/20/2779598.html 今天安装lua试试,这个从开始装的,发现一篇文字,字数虽少,但是却讲的很 ...