深入解析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代码了。

三、心得

学习源码时,不建议按照源码的顺序一行一行的阅读。首先要抓住主干,先梳理清楚主要的代码逻辑,再去仔细阅读具体的每行代码。另外按照源码顺序阅读可能很枯燥,很难坚持下来,可以先选择自己感兴趣的部分进行学习,最后再串联起来。

(0)

相关推荐

  • vuex 项目结构目录及一些简单配置介绍

    首先先正经的来一段官网的"忠告": vuex需要遵守的规则: 一.应用层级的状态应该集中到单个 store 对象中. 二.提交 mutation 是更改状态的唯一方法,并且这个过程是同步的. 三.异步逻辑都应该封装到 action 里面. 文件目录结构 文件之间的关系: store文件夹 - 存放vuex的系列文件 store.js - 引入vuex,设置state状态数据,引入getter.mutation和action getter.js - 获取store内的状态 mutatio

  • vue-cli脚手架config目录下index.js配置文件的方法

    此文章介绍vue-cli脚手架config目录下index.js配置文件 1.此配置文件是用来定义开发环境和生产环境中所需要的参数 2.关于注释 当涉及到较复杂的解释我将通过标识的方式(如(1))将解释写到单独的注释模块,请自行查看 3.上代码 // see http://vuejs-templates.github.io/webpack for documentation. // path是node.js的路径模块,用来处理路径统一的问题 var path = require('path')

  • 解决vue-cli3 使用子目录部署问题

    在使用 vue-cli3 build的时候,使用非子目录需要在 vue.config.js 中添加如下代码: module.exports = { baseUrl: process.env.NODE_ENV === 'production' ? '/dist/' : '/', } 但是build完后,放在nginx服务下,会看到如下报错,页面也显示 no-script 的内容 [Vue warn]: You are using the runtime-only build of Vue wher

  • 解读vue生成的文件目录结构及说明

    利用node和npm环境我们可以很快的搭建一个vue环境.具体步骤,请看上一篇博客.搭建完成后,我们可以看到生成的文件夹中包括如下文件: 1.build文件夹是保存一些webpack的初始化配置.config文件夹保存一些项目初始化的配置. 2.node_modules是npm加载的项目依赖的模块. 3.src目录是我们要开发的目录,打开是这样的: 其中assets:用来放置图片 components:用来放组件文件 app.vue:是项目入口文件,代码如下: App.vue相当于一个组件 ma

  • 详解vue-cli脚手架build目录中的dev-server.js配置文件

    本文系统讲解vue-cli脚手架build目录中的dev-server.js配置文件 1.这个配置文件是命令npm run dev 和 npm run start 的入口配置文件,主要用于开发环境 2.由于这是一个系统的配置文件,将涉及很多的模块和插件,所以这部分内容我将分多个文章讲解,请关注我博客的其他文章 3.关于注释 •当涉及到较复杂的解释我将通过标识的方式(如(1))将解释写到单独的注释模块,请自行查看 4.上代码 // 导入check-versions.js文件,并且执行导入的函数,用

  • vue 文件目录结构详解

    项目简介 基于 vue.js 的前端开发环境,用于前后端分离后的单页应用开发,可以在开发时使用 ES Next.scss 等最新语言特性.项目包含: 基础库: vue.js.vue-router.vuex.whatwg-fetch 编译/打包工具:webpack.babel.node-sass 单元测试工具:karma.mocha.sinon-chai 本地服务器:express 目录结构 ├── README.md 项目介绍 ├── index.html 入口页面 ├── build 构建脚本

  • 深入解析vue 源码目录及构建过程分析

    ​" 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整体有一个认知,有助于后续对源码的阅读." 一.目录结构 上图是对vue的代码的所有目录进行的梳理,其中源码位于src目录下,下面对src下的目录进行介绍. compiler 该目录是编译相关的代码,即将 template 模板转化成 render 函数的代码. vue 提供了 render 函数,render 函数作用是用来创建 VNode,但在平时开发中,绝大多数情况下使用 template 来创建 H

  • 深入解析Vue源码实例挂载与编译流程实现思路详解

    在正文开始之前,先了解vue基于源码构建的两个版本,一个是 runtime only ,另一个是 runtime加compiler 的版本,两个版本的主要区别在于后者的源码包括了一个编译器. 什么是编译器,百度百科上面的解释是 简单讲,编译器就是将"一种语言(通常为高级语言)"翻译为"另一种语言(通常为低级语言)"的程序.一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) →

  • Vue源码解析之Template转化为AST的实现方法

    什么是AST 在Vue的mount过程中,template会被编译成AST语法树,AST是指抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式. Virtual Dom Vue的一个厉害之处就是利用Virtual DOM模拟DOM对象树来优化DOM操作的一种技术或思路. Vue源码中虚拟DOM构建经历 template编译成AST语法树 -> 再转换为render函数 最终返回一个VNode(VNod

  • Vue编译器解析compile源码解析

    目录 引言 解析 compile compile 源码 配置选项 属性分别解析 finalOptions添加warn 方法 两个特殊的属性处理 引言 在上篇文章 Vue编译器源码分析compileToFunctions作用中我们介绍到了,在 compileToFunctions 方法中: // compile var compiled = compile(template, options); 而真正的编译工作是依托于 compile 函数,接下来我们详细解析 compile . 解析 comp

  • Vue源码cached解析

    目录 前言 参数解释 传入参数 返回参数 源码解释 实验解释 源码疑问 前言 创建一个纯函数的缓存版本 主要用途:优化性能——对于之前运算过一次的内容,利用闭包原理,缓存起来,避免重复调用,造成性能的浪费 /** * Create a cached version of a pure function. */ function cached (fn) { var cache = Object.create(null); return (function cachedFn (str) { var

  • vue 源码解析之虚拟Dom-render

    vue 源码解析 --虚拟Dom-render instance/index.js function Vue (options) { if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword') } this._init(options) } renderMixin

  • Vue源码解析之数组变异的实现

    力有不逮的对象 众所周知,在 Vue 中,直接修改对象属性的值无法触发响应式.当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变. 这是什么原因? 原因在于: Vue 的响应式系统是基于Object.defineProperty这个方法的,该方法可以监听对象中某个元素的获取或修改,经过了该方法处理的数据,我们称其为响应式数据.但是,该方法有一个很大的缺点,新增属性或者删除属性不会触发监听,举个栗子: var vm = new Vue({ data () { return

  • 从vue源码解析Vue.set()和this.$set()

    前言 最近死磕了一段时间vue源码,想想觉得还是要输出点东西,我们先来从Vue提供的Vue.set()和this.$set()这两个api看看它内部是怎么实现的. Vue.set()和this.$set()应用的场景 平时做项目的时候难免不会对 数组或者对象 进行这样的骚操作操作,结果发现,咦~~,他喵的,怎么页面没有重新渲染. const vueInstance = new Vue({ data: { arr: [1, 2], obj1: { a: 3 } } }); vueInstance.

  • vue源码之批量异步更新策略的深入解析

    vue异步更新源码中会有涉及事件循环.宏任务.微任务的概念,所以先了解一下这几个概念. 一.事件循环.宏任务.微任务 1.事件循环Event Loop:浏览器为了协调事件处理.脚本执行.网络请求和渲染等任务而定制的工作机制. 2.宏任务Task: 代表一个个离散的.独立的工作单位.浏览器完成一个宏任务,在下一个宏任务开始执行之前,会对页面重新渲染.主要包括创建文档对象.解析HTML.执行主线JS代码以及各种事件如页面加载.输入.网络事件和定时器等. 3.微任务:微任务是更小的任务,是在当前宏任务

  • Vue源码学习记录之手写vm.$mount方法

    目录 一.概述 二.使用方式 三.完整版vm.$mount的实现原理 四.只包含运行时版本的vm.$mount的实现原理 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.概述 在我们开发中,经常要用到Vue.extend创建出Vue的子类来构造函数,通过new 得到子类的实例,然后通过$mount挂载到节点,如代码: <div id="mount-point"></div> <!-- 创建构造器 --> var Profile =

随机推荐