# 入口
# 目录结构
我们去 github 下载 vue 的源码,主要看 vue 的核心目录结构:
src
├── compiler # 编译
├── core # 核心
├── platforms # 各个平台
├── server # ssr
├── sfc # vue文件处理
└── shared # 共享的工具等
compiler: 主要是模版编译相关的代码
core: 核心代码,包含内置组件,全局的 api,实例化,响应式,工具函数,虚拟 dom
core
├── components # 内置组件
├── global-api # 全局 api
├── instance # 实例化
├── observer # 响应式
├── util # 工具函数
└── vdom # 虚拟 dom
platforms: 提供了跨平台的能力,区分web和weex
platforms
├── web
├── weex
server: ssr 相关的渲染
sfc: 解析 vue 文件转为js 对象
shared: web 和服务端共享代码
我们从整体看,整个项目主要采用了 rollup 来进行构建,将这些逻辑打包成不同规范的文件。
vue 的构建一般分为带 compiler 版本和不带 compiler 的 runtime 版本,不带 compiler 的一般是由 webpack 等工具来处理编译的过程,整体的大小会小很多,由于我们在初始化的时候带有 template 标签,所以自然使用带编译的版本来看代码。
我们先看package.json中的dev脚本:
scripts:{
dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",
}
很清晰的看到传了一个参数web-full-cjs-dev,所以我们直接看scripts目录下的config.js中的某个配置:
web-full-cjs-dev': {
entry: resolve('web/entry-runtime-with-compiler.js'),
dest: resolve('dist/vue.common.dev.js'),
format: 'cjs',
env: 'development',
alias: { he: './entity-decoder' },
banner
}
这个 entry 就是打包的文件入口,包含了 comipler 的内容,也就是我们要看的第一个文件entry-runtime-with-compiler.js。
# 从入口开始
一般我们用 vue 进行开发的时候,入口处基本都是类似的语法:
new Vue({
el: "#app",
template: "<div>{{message}}</div>",
data: {
message: "hello vue",
},
});
我们可以看看入口文件entry-runtime-with-compiler.js做了什么:
这个文件主要扩展了$mount 方法,针对没有传入render 选项的参数,进行 template 或 el 的转化处理,变成新的 render 函数,最终调用 mount方法挂载 dom
import Vue from "./runtime/index";
// 扩展默认的$mount方法
const mount = Vue.prototype.$mount;
Vue.prototype.$mount = function(el){
// 1.传入的el不能是body或者html
// 2.如果不传render,首先会转化template为render函数
if(!options.render){
}
...
// 3.挂载dom
return mount.call(this, el, hydrating);
}
export default Vue;
# 总结
1.el 不能是 body 或者 html 标签
2.如果没有 render,会把 template 转换为 render 函数
- 如果有 render 函数,直接调用 mount 方法挂载 dom
整体流程 →