Vue源码学习(一):源码的入口在哪里

Vue源码解读系列



前言

  如何设计API和如何使用元编程思想(元编程,简单说是指框架的作者使用一种编程语言固有的语言特性,使得使用者能够以新语法和语义来构建应用程序,从而获得更好的开发体验)将新特性融入到框架中,是现代JS框架设计的两个核心,Vue.js侧重于后者。
  元编程思想涉及具体实现,需要考虑很多细节,比如要做到向下兼容,那么就要对一些特性的实现方式做成取舍,一些可通过书写向下兼容代码,另一些通过编译机制,还有一些要舍弃。这不仅在框架设计和实现的过程中会遇到,在具体实现应用程序的过程中也会遇到。
  因此,通过学习Vue.js,不仅能掌握设计应用程序框架的一般性技巧,还可以实现应用程序时运用其中的具体设计思想和方法论(学习源码也是对JS高级内容的一种实践)。

一、源码下载

1、首先找到Vue项目 github 地址:https://github.com/vuejs/vue
在这里插入图片描述
(这里学习源码下载的是2.6.14版本的)在这里插入图片描述
2、安装依赖:下载完后进行npm install 或者yarn add all 安装依赖

3、启动项目npm run dev ,在package.json文件中配置sourcemap,然后再执行npm run dev 会生成带编译版本的Vue.js和对应的.map文件,在源码解读时就可以引用dist目录下的 vue.js 文件,从而通过 vue.js.map 在浏览器中调试,就能关联到对应的源码文件。

// package.json
  "scripts": {
    "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev --sourcemap",
    ......
  },

二、目录解读

└── vue
    ├── BACKERS.md
    ├── FILE_README.md
    ├── LICENSE
    ├── README.md
    ├── benchmarks // 做性能测试的
    ├── dist // 最终打包的结果
    ├── examples // 官方的例子,可以写一些小demo调试
    ├── flow // 类型检测(和ts功能类似,没有ts好用,应该没人用了)
    ├── package.json // 项目依赖文件
    ├── packages  // 包含服务器渲染和模板编译两种npm包,供不同场景使用
    ├── scripts // 存放npm脚本配置文件,结合webpack、rollup进行编译、测试、构建等操作(使用者不需要关心)
    ├── src // 项目核心源码
    ├── test // test测试用例
    ├── types // vue新版本支持ts,主要是ts声明文件
    └── yarn.lock // yarn版本锁定文件
├─ src                         // 主要源码所在位置,核心内容
│   ├─ compiler                // 模板编译相关文件,将 template 编译为 render 函数
│       ├─ codegen             // 把AST(抽象语法树)转换为Render函数
│       ├─ directives          // 生成Render函数之前需要处理的东西
│       ├─ parser              // 模板编译成AST
│   ├─ core                    // Vue核心代码,包括了内置组件、全局API封装、Vue实例化、响应式原理、vdom(虚拟DOM)、工具函数等等。
│       ├─ components          // 组件相关属性,包含抽象出来的通用组件 如:Keep-Alive
│       ├─ global-api          // Vue全局API,如Vue.use(),Vue.nextTick(),Vue.config()等,包含给Vue构造函数挂载全局方法(静态方法)或属性的代码。 链接:https://012-cn.vuejs.org/api/global-api.html
│       ├─ instance            // 实例化相关内容,生命周期、事件等,包含Vue构造函数设计相关的代码
│       ├─ observer            // 响应式核心目录,双向数据绑定相关文件。包含数据观测的核心代码
│       ├─ util                // 工具方法
│       └─ vdom                // 虚拟DOM相关的代码,包含虚拟DOM创建(creation)和打补丁(patching)的代码
│   ├─ platforms               // vue.js和平台构建有关的内容 不同平台的不同构建的入口文件也在这里 (Vue.js 是一个跨平台的MVVM框架)
│       ├── web                // web端 (渲染,编译,运行时等,包括部分服务端渲染)
│       │   ├── compiler       // web端编译相关代码,用来编译模版成render函数basic.js
│       │   ├── entry-compiler.js               // vue-template-compiler 包的入口文件
│       │   ├── entry-runtime-with-compiler.js  // 独立构建版本的入口,它在 entry-runtime 的基础上添加了模板(template)到render函数的编译器
│       │   ├── entry-runtime.js                // 运行时构建的入口,不包含模板(template)到render函数的编译器,所以不支持 `template` 选项,我们使用vue默认导出的就是这个运行时的版本。
│       │   ├── entry-server-basic-renderer.js  // 输出 packages/vue-server-renderer/basic.js 文件
│       │   ├── entry-server-renderer.js        // vue-server-renderer 包的入口文件
│       │   ├── runtime        // web端运行时相关代码,用于创建Vue实例等
│       │   ├── server         // 服务端渲染(ssr)
│       │   └── util           // 工具类相关内容
│       └─ weex                // 混合运用 weex框架 (一端开发,三端运行: Android、iOS 和 Web 应用) 2016年9月3日~4日 尤雨溪正式宣布以技术顾问的身份加盟阿里巴巴Weex团队, 做Vue和Weex的整合 让Vue的语法能跨三端
│   ├─ server                  // 服务端渲染相关内容(ssr)
│   ├─ sfc                     // 转换单文件组件(*.vue)
│   └─ shared                  // 共享代码 全局共享的方法和常量

三、找到打包入口文件

进入package.json,可以看到入口文件是scripts文件夹下的config.js:
在这里插入图片描述
进入config.js,会对build对象进行解析,src/platforms/web下的entry-runtime.js和entry-runtime-with-compiler.js是构建入口(两个入口的区别:带compliler的会重写$mount,将template变成render函数):
在这里插入图片描述

四、如何进行代码调试

在examples文件夹下新建html文件,写入demo,打debugger就可以进行浏览器调试:
在这里插入图片描述
在这里插入图片描述

总结

本文参考书籍:《深入浅出Vue.js》
视频:B站视频
博客:源码解读的正确姿势

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 首先,我们需要了解一下 `Object.defineProperty` 这个方法。它是一个 JavaScript 的内置方法,用于在一个对象上定义一个新的属性或者修改一个已有的属性。这个方法接受三个参数,分别是要定义属性的对象、属性名和属性描述符。 其中,属性描述符是一个包含了四个属性的对象:`value`、`writable`、`enumerable` 和 `configurable`。`value` 属性指定了属性的值,`writable` 属性指定了属性是否可写,`enumerable` 属性指定了属性是否可枚举,`configurable` 属性指定了属性是否可配置。 在 Vue 组件中,我们可以使用 `Object.defineProperty` 来定义响应式数据。具体来说,我们可以在组件的 `data` 选项中定义一个对象,并使用 `Object.defineProperty` 将该对象的属性转换成响应式数据,这样当我们修改属性时,组件会自动重新渲染。 下面是一个简单的例子,展示了如何使用 `Object.defineProperty` 定义一个响应式数据: ``` const obj = {} Object.defineProperty(obj, 'name', { value: 'Vue', writable: true, enumerable: true, configurable: true }) ``` 这里我们定义了一个空对象 `obj`,然后使用 `Object.defineProperty` 将该对象的属性 `name` 定义为一个响应式数据,初始值为 `'Vue'`。由于 `writable` 属性被设置为 `true`,所以我们可以修改 `obj.name` 的值,而这个修改会触发组件的重新渲染。 希望我的回答能够解决你的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值