Vue2源码工程结构及入口分析(怎么看Vue源码)

工程结构

├─ .circleci                 # 包含CircleCI持续集成/持续部署工具的配置文件
├─ benchmarks                # 基准和性能测试文件,vue的跑分demo,例如大数据量的table或者渲染大量的SVG
├─ dist                      # 构建后输出的不同版本vue文件(UMD、common.js、生产和开发包)
├─ examples                  # 用vue写的一些小demo
├─ flow                      # 进行静态类型检测,静态类型检测类型声明文件(https://flow.org/)
├─ packages                  # 包含服务端渲染和模块编译器两种不同的NPM包,是提供不同使用场景使用的
├─ scripts                   # 存放npm脚本配置文件,结合webpack、rollup进行编译、测试、构建等操作
│   ├── config.js             # 包含在`dist`中找到的所有文件的生成配置 
│   └── build.js              # 对config.js中所有的rollup配置进行构建
├─ src                       # 主要源码所在位置,核心内容
│   ├── compiler             # 编译器代码,将template编译成render函数
│   ├── core                 # vue核心代码,包括内置组件、全局API封装、vue实例化、观察者、虚拟DOM、工具函数等
│   │   ├── components       # 组件相关属性,主要是keep-Alive
│   │   ├── global-api       # vue全局api。例如:Vue.use Vue.extend vue.mixin
│   │   ├── instance         # 实例化相关内容,生命周期,事件等
│   │   ├── observe          # 响应式核心目录,双向绑定相关文件
│   │   ├── util             # 工具方法
│   │   └── vdom             # 包括虚拟DOM,创建(creation)和打补丁(patching)的代码
│   ├── platforms            # 包含平台特有的相关代码,vue是一个跨平台的mvvm框架(web、weex)
│   │   ├── web              # web端
│   │   │   ├── compiler     # web端编译相关代码,用来编译模版或render函数
│   │   │   ├── runtime      # web端运行是相关代码,用来创建vue实例等
│   │   │   ├── server       # 服务端渲染
│   │   │   └── util         # 相关工具类
│   │   └── weex             # 基于通用跨平台的web开发语言和开发经验,来构建Android、ios和web应用
│   ├── server               # 服务端渲染(ssr)
│   ├── sfc                  # 转换单文件组件(*.vue)
│   └── shared               # 全局共享的方法和常量
├─ test                      # test测试用例
├─ types                     # vue新版本支持TypeScript,主要是用typeScript声明文件
├─ .editorconfig             # 文本编码样式配置文件      
├─ .eslintignore             # eslint校验忽略文件
├─ .eslintrc.js              # eslint配置文件
├─ .flowconfig               # flow配置文件
├─ LICENSE                   # 项目开源协议

整体流程图

源码入口

第一种(顺藤摸瓜)

通常看一个前端开源项目先看package.json文件(我博客有package.json键值详细介绍,可自行搜索)
main是require的入口,module是import的入口
require('Vue') 实际是引用下面的文件(commonjs规范)
"main": "dist/vue.runtime.common.js", 
import Vue from 'vue' 实际是引用下面的文件(ES module规范)
"module": "dist/vue.runtime.esm.js",
我们可以看到上面不管是commonjs规范引入,还是es标识ES module规范引入
引入的包文件都在dist文件夹下
dist文件夹下的文件是webpack构建(build)后产生的,package.json文件中有一个打包构建方式 ➡ "build": "node scripts/build.js",
我们可以顺藤摸瓜到scripts文件夹下看build.js
在build文件中 我们可以看到build(builds)这就是构建入口
其中形参 builds 就是 let builds = require('./config').getAllBuilds()
所以我们可以去config文件下去看getAllBuilds()方法
(或者在vscode中直接ctrl+左键点击getAllBuilds()方法,会自动跳转到./config.js文件中的getAllbuilds方法)
进来config.js文件后我们可以看到文件中
exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
这里遍历了 我们可以看到形参builds是很多对象 这里引入了很多vue.js
这其实是为了兼容多平台使用的 因为不同规范引入方式不同 这里做了区分
在这里我们选用builds中功能完善的entry-runtime-with-compiler.js(npm run dev的时候里面执行的脚本target就是web-full-dev)
compiler这个模块可以将vue中的template模板编译成render执行
无这个模块虽然体积小了 但是只能用render编译虚拟dom(用js对象描述真实dom)
这个entry-runtime-with-compiler.js文件在
src/platforms/web文件夹中
在这个entry-runtime-with-compiler.js文件中 找到 export default Vue
这就是真正引入vue的地方 将vue暴露出去的地方
可以看到export default的vue就是  import Vue from './runtime/index'
这个暴露的vue就是这里引入的 我们可以去看下这个runtime目录下的index文件
我们可以注意到entry-runtime-with-compiler.js和runtime/index
里面都有  Vue.prototype.$mount 他们的区别就是有没有compiler
compiler是用于解析template模板的
render的优先级是高于template先执行
接着找 在runtime/index 又引入了 vue
import Vue from 'core/index' (src下的core)
再去src目录下找core/index
在里面再次发现引入了 vue import Vue from './instance/index'
最后在./instance/index(src/core/instance/index)中找到了Vue构造函数 里面有众多的init初始化函数 就此开启了入口

第二种(利用debugger与--sourcemap)

先新建一个index.html静态文件 文件内容如下 里面的js加上debugger关键词
  <div id="app">
    {{message}}
    <xxx></xxx>
  </div>
  <script src="../../dist/vue.js"></script>
<script>
  debugger
  Vue.component('xxx', {
    template: "<div>90989</div>"
  })
  new Vue({
    // el: '#app',
    data: {
      message: 'tesserwgt'
    },
    // components:{
    //   localComp,
    //   globComp
    // }
  }).$mount('#app')

</script>
在package.json文件scripts里面的dev中加入--sourcemap 如下⬇
"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",
之后运行 npm run dev 在dist文件夹中出现vue.js.map文件就算映射成功了
加入--sourcemap原因 webpack打包后的js代码是全部在一起的,有几万行代码在一个文件中(vue.js) 
你debugger调试的时候希望debuggger定位到vue的源码文件(也就是src下的core这个核心文件中) 这样能更好的调试代码
而不是定位到引入webpack打包后的vue.js 
所以使用--sourcemap就有映射作用
利用这个我们就可以快速找到第一种方式最后找到的src/core/instance/index  
posted @ 2022-01-20 12:22  Model-Zachary  阅读(574)  评论(0编辑  收藏  举报