# 入口

# 目录结构

我们去 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: 提供了跨平台的能力,区分webweex

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 选项的参数,进行 templateel 的转化处理,变成新的 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 函数

  1. 如果有 render 函数,直接调用 mount 方法挂载 dom