古人有云:码农爱coding,则为之计深远。

众人问:何为之?

古人曰:底层、算法和架构。

众木然。

古人又曰:多看源码。

以下内容是我在学习 Vue-2.5.2 源码时的一个总结。

第一章 活捉Vue

旁白:既然是学习Vue源码,首先要搞清楚的是——Vue是什么东西?不然,天知道你在学什么玩意儿。所以,找到Vue对象就是本次学习的一条主线。本次任务的目标就是——活捉Vue

盖工欲善其事必先利其器。出发之前,应该要有一件趁手的武器,呐,这套祖传的vs code就送给你了。

第一回 不入虎穴焉得虎子

欲活捉Vue,最紧要的是找到它大概在哪里,然后根据线索顺藤摸瓜。那么,它到底在哪儿呢?

看着眼前的武器,你灵光一闪:git clone https://github.com/vuejs/vue.git。恭喜,Vue的老巢已经被你发现,令人激动的是,入口package.json也被你找到了。但紧闭的大门阻碍了你的步伐,于是你运用所学姿势,很快找到破解开关的关键scripts属性:

  "scripts": {
"dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev",
...
"build": "node build/build.js",
...
}

P.S.package.json几乎是所有成熟库/框架必备的入口文件。

你命令终端执行npm run dev,看到rollup构建工具正在自动执行build文件夹下的config.js,并在环境中注入参数TARGET:web-full-dev,你紧跟线索,找到了build/config.js。看着两百多行代码,你微微一笑,心想,这等雕虫小技也敢造次?径直走向exports,看它导出了什么?

P.S.s 一般而言,导出对象在文件末尾。

// build/config.js

...
if (process.env.TARGET) {
module.exports = genConfig(process.env.TARGET); // (1)
} else {
exports.getBuild = genConfig
exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}

脑回路高速运行——因为执行npm run dev会植入环境变量TARGET:web-full-dev,上述代码会走(1),所以结合上下文,build/config.js实际导出的对象应该是这样的:

module.exports = {
input: resolve('web/entry-runtime-with-compiler.js'),
plugins: [
replace({__VERSION__: version}),
{
vue: resolve('src/platforms/web/entry-runtime-with-compiler'),
compiler: resolve('src/compiler'),
core: resolve('src/core'),
shared: resolve('src/shared'),
web: resolve('src/platforms/web'),
weex: resolve('src/platforms/weex'),
server: resolve('src/server'),
entries: resolve('src/entries'),
sfc: resolve('src/sfc'),
he: './entity-decoder'
}
],
output: {
file: resolve('dist/vue.js'),
format: 'umd',
banner: banner,
name: 'Vue'
}
}

直到这里,Vue的庐山真面目依然没有揭开。“果然是狡兔三窟!”你不屑道,然而你明白,已经越来越接近了...

此地唯一的入口就是input,小小的障眼法对你来讲不足挂齿,轻轻旋转机关,来到了src/platforms/web/entry-runtime-with-compiler.js。只一眼,你便看到了import Vue from './runtime/index'。"hehe,总算把你逮住了,老东西!"

你小心翼翼的进入./runtime/index,以为终于抓到了Vue。突然,一支利箭飞来import Vue from 'core/index',险险的避过后,一群彪形大汉又蜂拥而至:

./runtime/index.js

import Vue from 'core/index'
...
Vue.config.mustUseProp = mustUseProp
...
extend(Vue.options.directives, platformDirectives)
...
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
...

第二回 降服Vue

面对群魔乱舞,你开始受伤、流血,一波又一波的攻势逐渐让你体力不支,更糟糕的是,你,只是一个人。“就这样结束了么?”你喘着粗气暗问自己,恍惚间,往昔在脑海中一幕幕重现,从一无所知的小白到现在敢于挑战Vue,经历了重重历练,你不甘心,不甘心就这样失败。放手一搏吧,骚年!!!

体内的能量在积累,终于,你用尽全力使出了终极必杀技:404 Page Not Found。一时间,大汉们应声而倒,就连./runtime/index也开始坍塌,电光火石间,一股大力将你震晕击飞,醒来之时,已经到了另一个世界:src/core/index.js

这里就是Vue的核心了么?环顾四周,只见一间虚掩着房门的小屋./instance/index,推开门,Vue端坐在那里:

...
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。当刃尖离Vue只有0.0001公分的时候,你看着眼前的Vue,原来,鼎鼎大名的Vue只是一个普普通通的构造函数,好像看到了最初的自己,刹那间,你顿住了。

Vue却开口到:“骚年,你终于来了!看你风流倜傥、天资聪颖,老夫这一身绝学总算是后继有人了。”说罢,万丈金光从Vue身上迸发而出,场面一度失控。待金光散去,Vue却不见了,只留下一本《Vue 编程房内考》...

《Vue 编程房内考》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 使用kindeditor 4.1.7 编辑器 注意事项,上传图片失败 问题 ,

    <script charset="utf-8" src="editor/kindeditor.js"></script> <scr ...

  2. Linux编程规范

    1)在使用C语言进行编程时,源文件都必须加---文件头 /******************************************************** *文件名:test.c *创 ...

  3. 2018.09.26 洛谷P2464 [SDOI2008]郁闷的小J(map+vector)

    传送门 本来出题人出出来想考数据结构的. 但是我们拥有map+vector/set这样优秀的STL,因此直接用map离散化,vector存下标在里面二分找答案就行了. 代码: #include< ...

  4. UVa 11280 Flying to Fredericton (DP + Dijkstra)

    题意:给出n(2<=n<=100)个城市之间的m(0<=m<=1000)条航线以及对应的机票价格,要求回答一些询问,每个询问是给出最大停留次数S,求从其实城市Calgary到终 ...

  5. storyBoard中取消键盘第一响应

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {     [self.view endEditing:YES]; } ...

  6. (动态规划 01背包 打印路径) CD --UVA --624

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#problem/G 每个CD的时间不超过 20没有哪个CD的时间是超过N ...

  7. # 20155204 2016-2017-2 《Java程序设计》第五周学习总结

    20155204 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生时显示友好的错误信 ...

  8. SpringMVC绑定到实体数组、list、set、和map时要注意

    实体的属性前一定要用.分割,如果是使用jquery的ajax提交的一个js数组对象,则请求数据会被格式化为 var sub = [{name:1,num:2},{name:1,num:2}] $.po ...

  9. Android-Xml,PullParser,解析

    在上一篇博客,Android-XML格式描述,介绍来XML在Android中的格式: 解析persons.xml文件内容: <?xml version="1.0" encod ...

  10. 新建linux服务器初始化操作

    1.关闭不需要的服务 首先确定服务器有没有ntsysv命令,如果没有的话,直接使用yum安装即可. 使用ntsysv关闭不需要的服务以节省服务器资源 需要打开的服务如下: crond:周期性计划任务 ...