1.文件结构
├── benchmarks ---------------------------- 基准测试文件
├── dist ---------------------------------- 构建后文件的输出目录
├── examples ------------------------------ 存放一些使用Vue开发的应用案例
├── flow ---------------------------------- JS静态类型检查工具[Flow](https://flowtype.org/)的类型声明 vue2.x用的flow
├── package.json
├── packages ------------------------------ 核心代码之外的独立库
├── scripts ------------------------------- 包含与构建相关的脚本和配置文件
│ ├── alias.js -------------------------- 源码中使用到的模块导入别名
| ├── build.js -------------------------- 构建相关的文件,一般情况下我们不需要动
│ ├── config.js ------------------------- 项目的构建配置
├── src ----------------------------------- 源码目录
│ ├── compiler -------------------------- 编译器代码,用来将 template 编译为 render 函数
│ │ ├── codegen ----------------------- 存放从抽象语法树(AST)生成render函数的代码
│ │ ├── directives -------------------- 指令定义 v-on ,v-bind, v-if等实现
│ │ ├── optimizer.js ------------------ 分析静态树,优化vdom渲染
│ │ ├── parser ------------------------ 存放将模板字符串转换成元素抽象语法树的代码[html编译]
│ ├── core ------------------------------ 存放通用的,核心代码
│ │ ├── components -------------------- 包含抽象出来的通用组件,目前只有keep-alive
│ │ ├── global-api -------------------- 给Vue构造函数挂载全局方法(静态方法)或属性的代码[全局API,Vue.use(),set(),delete()]
│ │ ├── instance ---------------------- Vue构造函数与原型相关代码
│ │ ├── observer ---------------------- 响应式实现,包含数据观测的核心代码
│ │ ├── util -------------------------- 工具类,props.js
│ │ ├── vdom -------------------------- 虚拟DOM的 creation 和 patching 的代码
│ ├── platforms ------------------------- 不同平台特有的相关代码
│ │ ├── weex -------------------------- weex平台支持
│ │ ├── web --------------------------- web平台支持
│ │ │ ├── entry-runtime.js ---------------- 运行时构建的入口
│ │ │ ├── entry-runtime-with-compiler.js -- 独立构建版本的入口
│ │ │ ├── entry-compiler.js --------------- vue-template-compiler 包的入口文件
│ │ │ ├── entry-server-renderer.js -------- vue-server-renderer 包的入口文件
│ ├── server ---------------------------- 服务端渲染(server-side rendering)的相关代码
│ ├── sfc ------------------------------- 包含单文件组件.vue文件的解析逻辑,用于vue-template-compiler包
│ ├── shared ---------------------------- 整个代码库通用的代码
├── test ---------------------------------- 测试文件
├── types --------------------------------- ts类型声明
benchmarks文件:benchmark的目的主要有两种,一是验证性能,另一个是获得一些基准数据,从而可以与本软件的其他版本或其他同类软件进行比较。通常不使用benchmark做正确性验证。benchmark测试不一定会发生在每个版本的开发期间。有可能仅会在有较大改动的时候才会进行一次benchmark测试。因此频率相对单元测试来说要低很多。
2.入口文件
(1)前端项目入口文件从package.json文件中查看。
可以找到:
"scripts": {
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
}
rollup是一个类似于webpack的js模块打包器,vue@1.0.10之前还是用的webpack,后改成了rollup, 目的是为了打包体积小一点,初始化速度快一点。 以下是作者本人回答
rollup 只是用于 Vue 发布文件的构建,对用户使用没有直接影响。之前用 webpack 打包,还是会自带一个小型的动态 module 加载机制,并且每个文件是包在一个模块函数里的。rollup 打包通过重命名 import binding 直接把所有文件的函数都放在同一个函数体里面... 所以最终出来的文件会小一些,并且初始化快个十几毫秒的样子。1.0.10 以后 npm 包里包含的是:dist/vue.common.js - 一个 rollup 构建后的单个 CommonJS 文件,package.json 里面的 main 指向这里。用 Webpack 或是 Browserify 打包,获取到的是这个文件。dist/vue.js 和 dist/vue.min.js - 构建后的可直接用于 <script> 引用的文件src - 源文件,ES6(目前只用了模块语法)。package.json 的 esnext:main 指向 src/index.js。用 jspm 或是 rollup 打包,获取的是 ES6 的源文件。---想起来,对于用户来说有一个实际变化就是没有办法再用 require('vue/src/xxx') 的方式直接获取 Vue 内部的模块,不过本来就不推荐这样做。
(2)进入scripts/config.js 文件[命令参数:TARGET:web-full-dev]
找到此参数位置:
const builds = {
...
// Runtime+compiler development build (Browser)
'web-full-dev': {
entry: resolve('web/entry-runtime-with-compiler.js'),//入口文件
dest: resolve('dist/vue.js'),//输出文件
format: 'umd',//编译方式
env: 'development',//环境
alias: { he: './entity-decoder' },//别名
banner //每个包前面的注释,包括:版本、作者、日期
},
...
}
format 编译方式说明:
es:ES Modules,使用ES6的模板语法输出
cjs:CommonJs Module,遵循CommonJs Module规范的文件输出
amd:AMD Module,遵循AMD Module规范的文件输出
umd:支持外链规范的文件输出,此文件可以直接使用script标签
(3)进入web/entry-runtime-with-compiler.js文件
这个文件就是src/platforms/web/entry-runtime-with-compiler.js文件 原因请查看scripts/alias.js模块倒入别名文件
const path = require('path')
const resolve = p => path.resolve(__dirname, '../', p)
module.exports = {
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'),
sfc: resolve('src/sfc')
}
src/platforms/web/entry-runtime-with-compiler.js内容
import Vue from 'core/index'
(4)进入core/index文件
import Vue from './instance/index'
(5)进入./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)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
当执行new vue()时其实就调用的是这个构造函数,所以可以从此处开始看代码!