公众号原文链接:深入vue - 源码目录及构建过程分析 喜欢本文可以扫描下方二维码关注我的公众号 「前端小苑」
“ 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整体有一个认知,有助于后续对源码的阅读。”
上图是对vue的代码的所有目录进行的梳理,其中源码位于src目录下,下面对src下的目录进行介绍。
该目录是编译相关的代码,即将 template 模板转化成 render 函数的代码。
vue 提供了 render 函数,render 函数作用是用来创建 VNode,但在平时开发中,绝大多数情况下使用 template 来创建 HTML,所以需要将 template模板编译成 render 函数。
编译工作既可以在代码构建时做,也可以在客户端运行时做,但编译十分消耗性能,所以在项目中建议使用 runtime 版本。
这部分代码是 vue 的核心代码,可以说是 vue 的灵魂所在,也是我们要重点学习的源码。
core目录又包含如下子目录。
platforms下包含两个子目录,web 和 weex。
分别代表可以打包生成在web端使用的 vue 代码和在native端使用的 weex 代码。美团开源的开发微信小程序的 mpvue 框架也是在这个目录下进行拓展的。
通过不同平台的入口就可以打包出运行在不同平台的版本的 vue 文件,后面代码构建部分会介绍具体的构建过程。
该目录下是 SSR 相关的代码。
Vue.js 是构建客户端应用程序的框架。除了可以在浏览器中输出 Vue 组件,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
我们平时开发时,都是写 .vue 文件。sfc 的代码就是提供一个解析器,把.vue文件代码解析成一个 javascript 对象。
该目录下定义了一些公用的工具方法,提供给上面的几个目录内代码使用。
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代码了。
学习源码时,不建议按照源码的顺序一行一行的阅读。首先要抓住主干,先梳理清楚主要的代码逻辑,再去仔细阅读具体的每行代码。另外按照源码顺序阅读可能很枯燥,很难坚持下来,可以先选择自己感兴趣的部分进行学习,最后再串联起来。