Vue.js源码学习之开端

源码构建

源码下载地址:https://github.com/vuejs/vue

源码目录

Vue源码位于src目录下,其目录结构如下:

src
├── compiler        # 编译相关 
├── core            # 核心代码 
├── platforms       # 不同平台的支持
├── server          # 服务端渲染
├── sfc             # .vue 文件解析
├── shared          # 共享代码
  • compiler

    compiler目录中包含Vue中所有与编译相关的代码,主要功能是把模板解析成ast语法树,ast语法树优化,代码生成等。编译工作可以在构建时借助webpack、vue-loader等插件进行离线编译,也可以在运行时直接使用包含构建功能的Vue。由于编译工作非常耗费性能,所以更推荐使用前者的离线编译模式。

  • core

    core目录中包含了Vue的核心代码,包括内置组件、全局API封装、Vue实例化、观察者、虚拟DOM、工具函数等,是学习Vue源码的重点。

  • platform

    platform中包含两个次级目录,代表两个入口。Vue是一个跨平台的MVVM框架,可以在web上运行,也可以配合weex在native客户端上运行。通过两个入口,分别打包运行在web上和weex上的Vue。

  • server

    server目录中包含与服务端渲染相关的逻辑,这部分代码在服务端的Node.js中运行,和在浏览器端运行的Vue不一样。

  • sfc

    在开发过程中,常常会通过webpack构建.vue单文件来编写组件。sfc目录中的代码会将.vue文件解析成一个JS对象。

  • shared

    shared目录中包含的是一些对工具方法定义,这些方法会被浏览器端的Vue和服务端的Vue所共享。

构建过程

package.json中,Vue源码的构建脚本为

{
    "script": {
        "build": "node scripts/build.js",
        "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
    	"build:weex": "npm run build -- weex",
    }
}

当运行脚本npm run build时,实际上时执行node scripts/build.js。Vue源码是基于Rollup构建的,与构建相关的配置均位于scripts目录下。后两条命令是在第一条命令的基础上,添加了环境参数。

以第一条命令为例,在scripts/build.js中,

let builds = require('./config').getAllBuilds()

// filter builds via command line arg
if (process.argv[2]) {
  const filters = process.argv[2].split(',')
  builds = builds.filter(b => {
    return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
  })
} else {
  // filter out weex builds by default
  builds = builds.filter(b => {
    return b.output.file.indexOf('weex') === -1
  })
}

build(builds)

上述代码中,builds是配置文件scripts/config.js中的所有配置选项,如果构建时有命令行参数process.argv[2],则会将输入的参数分割成一个数组filters,然后在builds中过滤出所有涉及到filters中各项的配置。若没有命令行参数,则默认采用weex。

scripts/config.js中的配置选项很多,提取出其中一部分进行分析

const builds = {
    // Runtime+compiler CommonJS build (CommonJS)
    'web-full-cjs-dev': {
        entry: resolve('web/entry-runtime-with-compiler.js'),
        dest: resolve('dist/vue.common.dev.js'),
        format: 'cjs',
        env: 'development',
        alias: { he: './entity-decoder' },
        banner
    },
    // Runtime only ES modules build (for bundlers)
    'web-runtime-esm': {
        entry: resolve('web/entry-runtime.js'),
        dest: resolve('dist/vue.runtime.esm.js'),
        format: 'es',
        banner
    },
    // runtime-only build (Browser)
    'web-runtime-dev': {
        entry: resolve('web/entry-runtime.js'),
        dest: resolve('dist/vue.runtime.js'),
        format: 'umd',
        env: 'development',
        banner
    },
}

在单个配置中,entry表示构建入口js文件地址;dest表示构建出口js文件地址;format表示构建出来的文件所遵循的规范,其中cjs表示CommonJS规范,es表示ES Module规范,umd表示UMD规范。

web-runtime-esm配置为例,其入口文件的地址为resolve('web/entry-runtime.js'),其中resolve函数定义如下

const aliases = require('./alias')
const resolve = p => {
  const base = p.split('/')[0]
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1))
  } else {
    return path.resolve(__dirname, '../', p)
  }
}

在上述代码中,首先获取在scripts/alias中定义的路径别名(先将相对路径转换成绝对路径,然后再取一个简短的路径别名),然后将传入的参数进行分割,取数组第一项,在这里被取出的baseweb,如果路径别名中存在web,则将web对应的路径与参数数组的剩余项进行拼接,找到最终路径。这里找到的是在web目录下的entry-runtime.js文件,也就是web-runtime-esm配置的入口文件。经过Rollup构建打包后,最终在dist目录下生成vue.runtime.esm.js文件。

Runtime Only VS Runtime + Compiler

使用vue-cli脚手架初始化Vue项目时,可以选择使用Runtime Only版本,还是Runtime + Compiler版本。这两个版本的区别在于编译工作时离线时完成 还是在线运行时进行。

  • Runtime Only

    若选择Runtime Only版本,则通常需要借助webpack、Vue-loader等工具将.vue文件编译成js文件。这一工作是在编译阶段完成的,所以在运行时只需要执行Vue.js代码,所以代码体积会更轻量。

  • Runtime + Compiler

    若选择Runtime + Compiler版本,则在运行时直接使用包含构建功能的Vue。在Vue2.0中,最终的渲染都是通过render函数进行的,如果定义了template属性,则需要先编译成render函数,再渲染。

    // 需要编译器编译成render函数
    new Vue({
        templete: '<div>{{ 编译 }}<div>'
    })
    
    // 不需要编译
    new Vue({
        render (h) {
            return h('div',this.hi)
        }
    })

    由于编译工作非常耗费性能,所以更推荐使用Runtime Only的离线编译模式。

Vue.js源码全方位深入解析最新下载地址.rar Vue.js源码全方位深入,帮你更深入了解vue 第1章 准备工作 介绍了 Flow、Vue.js源码目录设计、Vue.js源码构建方式,以及从入口开始分析了 Vue.js 的初始化过程。 第2章 数据驱动 详细讲解了模板数据到 DOM 渲染的过程,从 new Vue 开始,分析了 mount、render、update、patch 等流程。 第3章 组件化 分析了组件化的实现原理,并且分析了组件周边的原理实现,包括合并配置、生命周期、组件注册、异步组件。 第4章 深入响应式原理(上) 详细讲解了数据的变化如何驱动视图的变化,分析了响应式对象的创建,依赖收 集、派发更新的实现过程,一些特殊情况的处理,并对比了计算属性和侦听属性的实现,最后分析了组件更新的过程。 第5章 深入响应式原理(下) 详细讲解了数据的变化如何驱动视图的变化,分析了响应式对象的创建,依赖收集、派发更新的实现过程,一些特殊情况的处理,并对比了计算属性和侦听属性的实现,最后分析了组件更新的过程。 第6章 -编译(上) 从编译的入口函数开始,分析了编译的三个核心流程的实现:parse -> optimize -> codegen。 第7章 -编译(下) 从编译的入口函数开始,分析了编译的三个核心流程的实现:parse -> optimize -> codegen。 第8章 -扩展(上) 详细讲解了 event、v-model、slot、keep-alive、transition、transition-group 等常用功能的原理实现,该章节作为一个可扩展章节,未来会分析更多 Vue 提供的特性。 第9章 -扩展(中) 详细讲解了 event、v-model、slot、keep-alive、transition、transition-group 等常用功能的原理实现,该章节作为一个可扩展章节,未来会分析更多 Vue 提供的特性。 第10章 -扩展(下) 详细讲解了 event、v-model、slot、keep-alive、transition、transition-group 等常用功能的原理实现,该章节作为一个可扩展章节,未来会分析更多 Vue 提供的特性。 第11章 Vue-Router 分析了 Vue-Router 的实现原理,从路由注册开始,分析了路由对象、matcher,并深入分析了整个路径切换的实现过程和细节。 第12章 Vuex 分析了 Vuex 的实现原理,深入分析了它的初始化过程,常用 API 以及插件部分的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值