准备工作 - 学习vue源码系列1

简介: 准备工作 - 学习vue源码系列1

准备工作 - 学习vue源码系列1


决定跟着黄轶老师的vue2源码课程好好学习下vue2的源码,学习过程中,尽量输出自己的所得,提高学习效率,水平有限,不对的话请指正~

vue的源码clone到本地,切换到分支2.6

认识 flow

Flowfacebook 出品的 JavaScript 静态类型检查工具。 vue使用其进行类型检测

怎么使用 flow

安装:

npm i flow-bin -g

创建配置文件:

flow init

创建一个 js 文件

/*@flow*/
function split(str) {
  return str.split(" ");
}
split(11);

执行flow命令,就可以检测了,这边会发现报错

网络异常,图片无法展示
|

flow 的工作方式

通常类型检查分成 2 种方式:

  • 类型推断:通过变量的使用上下文来推断出变量类型,然后根据这些推断来检查类型。(上面的例子就是推断)
  • 类型注释:事先注释好我们期待的类型,Flow 会基于这些注释来判断。(推荐)

类型注释和 ts 非常像:

/*@flow*/
function add(x: number, y: number): number {
  return x + y;
}
add("Hello", 11);
// 执行 flow,会报错

一般在需要flow检查的文件首行加上/*@flow*/

如果可以为undefined或者null的话:

var foo: string | void = null;
var foo: ?string = null;

flow 在 vue 源码中的使用

flow 可以自定义类型,vue 的主目录下.flowconfig 文件, 它是 Flow 的配置文件。 这其中的 [libs] 部分用来描述包含指定库定义的目录,默认是名为 flow 的目录。

遇到某个类型,想要看数据结构的话,就翻看这里。

网络异常,图片无法展示
|

vue 源码目录设计

主要看src的设计:

网络异常,图片无法展示
|

功能模块拆分的非常清楚,让阅读性和可维护性都很优雅。

vue 源码构建

Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下。

Rollup 主要是构建 js 文件,不处理其他的文件,相比 webpack 更轻量。

所谓构建,就是运行命令之后,生成最终的文件。

构建脚本

构建脚本是package.json,其中的的build命令,就是构建命令。

网络异常,图片无法展示
|

vue 的三种运行环境:

  • web(普通的 web 端)
  • ssr(服务端)
  • weex(原生)

构建过程

src/build.js其实就是获取配置,然后根据环境参数过滤,最后在dist目录生成相应的js文件。

网络异常,图片无法展示
|

为了让配置中的entry/dist路径更具可读性,vue进行了一些技巧性的操作:

const builds = {
  "web-runtime-cjs-dev": {
    // 这里的 web会被替换成web的绝对路径,resolve就是做这个事的
    entry: resolve("web/entry-runtime.js"),
    // 同理 dist也是如此
    dest: resolve("dist/vue.runtime.common.dev.js"),
    format: "cjs",
    env: "development",
    banner,
  },
  // ...
};

再看下resolve:

const resolve = (p) => {
  const base = p.split("/")[0];
  // // aliases就是 路径的别名哈希表 {compile:"compiler文件夹的绝对地址",core:.....}
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1));
  } else {
    return path.resolve(__dirname, "../", p);
  }
};

format属性

format表示 最后生成的 js 文件符合什么规范:

  • commonJS 规范,其实就是require/module.exports
  • ESModule 规范,其实就是import/export
  • umd 规范,算是兼容模式,
(function (window, factory) {
  if (typeof exports === "object") {
    module.exports = factory();
  } else if (typeof define === "function" && define.amd) {
    define(factory);
  } else {
    window.eventUtil = factory();
  }
})(this, function () {
  //module ...
});

小技巧:打印错误和文件大小

有两个函数,可以日常使用

function getSize (code) {
  return (code.length / 1024).toFixed(2) + 'kb'
}
// catch(logError) 这样使用非常方便
function logError (e) {
  console.log(e)
}

Runtime Only VS Runtime + Compiler

其实这两个是相对的。

使用vue的时候,如果template是字符串的话,如下

new Vue({
  template: '<div>{{ hi }}</div>'
})

这种代码一般是在运行环境里,由运行环境template编译成render函数,这里特别注意,编译是运行环境做的,这样vue就必须包含怎么编译的代码,专业名词就是Compiler

当然如果代码里没有这样的字符串,自然也就不需要Compiler

显然加上Compiler既增加了vue的体积,又让运行环境干编译,会更费时。

那另外一种就好理解了,所谓的Runtime其实就是没有Compilervue代码,一般开发是用.vue文件表示模板,而.vue文件,是在你的编辑器里,也称为编译环境里,将其编译成render函数(依靠webpack的vue-loader插件),这样运行环境自然不需要编译,只需要运行就行,专业名词就是Runtime

显然Runtime既轻量,又省时。

说句人话,开发的时候如果模板没有字符串的话,直接Runtime就好,不需要Compiler

从入口开始

先找到定义vue的地方!

网络异常,图片无法展示
|

distvue.js是由entry-runtime-with-compiler.js生成的,一层层往上找线索~

// entry-runtime-with-compiler.js
import Vue from './runtime/index.js'
// runtime/index.js
import Vue from 'core/index'
// core/index.js
import Vue from './instance/index'
// instance/index  找到啦!
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)
}

网络异常,图片无法展示
|

这里用函数的形式定义了类,好处是方便在Vue.prototype上面拓展,这样拓展的方法和属性可以分布在别的文件,方便维护。

小技巧:怎么判断有没有用new调用

其实就是this是不是属于当前实例

function C(){
  if(!this instanceOf C){console.log('C is a constructor and should be called with the `new` keyword')}
}

小技巧:函数的形式定义类,方便拓展

class关键字的方式,拓展会不方便,反而函数的形式更加便捷,可以将方法和属性分门别类在其他文件

function C(){}
// getName.js
C.prototype.getName = function getName(){}

引用

目录
相关文章
|
2天前
|
JavaScript
vue页面加载时同时请求两个接口
vue页面加载时同时请求两个接口
|
1天前
|
JavaScript
vue打印v-model 的值
vue打印v-model 的值
|
2天前
|
移动开发 前端开发 JavaScript
VUE3内置组件Transition的学习使用
VUE3内置组件Transition的学习使用
|
2天前
|
移动开发 JavaScript 前端开发
学习vue3使用在线官方开发环境play.vuejs.org进行测试
学习vue3使用在线官方开发环境play.vuejs.org进行测试
|
2天前
|
JavaScript
Vue实战-组件通信
Vue实战-组件通信
4 0
|
2天前
|
JavaScript
Vue实战-将通用组件注册为全局组件
Vue实战-将通用组件注册为全局组件
5 0
|
2天前
|
JavaScript 前端开发
vue的论坛管理模块-文章评论02
vue的论坛管理模块-文章评论02
|
2天前
|
JavaScript Java
vue的论坛管理模块-文章查看-01
vue的论坛管理模块-文章查看-01
|
2天前
|
JavaScript
VUE里的find与filter使用与区别
VUE里的find与filter使用与区别
11 0