vue源码(一)

搭建环境

获取地址:GitHub - vuejs/vue: This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

安装依赖:npm i

安装 rollup

npm i -g -rollup

修改dev脚本:添加 --sourcemap

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

执行dev脚本:npm run dev

此处使用vue的版本是2.6

目录:

dist 发布目录 

examples 范例

flow 试代码 

node_modules

scripts 构建脚本

src 源码

  compiler 编译器相关

  core 核心代码

    components 通用组件如keep-alive

    global-api 全局api

    instance 构造函数等

    observer 响应式相关

    util 

    vdom 虚拟DOM相关

......

术语解释:

runtime 仅包含运行时,不包含编译器

common cjs规范,适用于webpack1

esm es模块,用于webpack2+

umd universal module definition,兼容cjs和amd,用于浏览器,一般使用的都是这个版本。

入口文件

-c scripts/config.js //配置文件所在
TARGET:web-full-dev" //指明输出文件配置项

能够通过config.js找到对应的entry入口文件

// 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
  },

所以默认是web开头的路径

const aliases = require('./alias')
const resolve = p => {
  const base = p.split('/')[0]
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1))
  } else {
    return path.resolve(__dirname, '../', p)
  }
}

进入alias

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')
}

找到了最终的路径

/Users/jerrychen/Desktop/vue-2.6/src/platforms/web/entry-runtime-with-compiler.js
//扩展$mount:解析模版
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
  el?: string | Element, //宿主元素
  hydrating?: boolean
): Component {
    el = el && query(el) //获取真实dom
    ......
}

 解析模版相关选项,首先判断是否有render函数,所以render的优先级很高,再看template,最后是el。如果写了el,则可以省略$mount。template或者render需要加上$mount。

//检测render函数
if (!options.render) {
    //再看template
    let template = options.template
    //解析template
    if (template) {
      if (typeof template === 'string') {  //template:'#app' 选择器
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
          /* istanbul ignore if */
          if (process.env.NODE_ENV !== 'production' && !template) {
            warn(
              `Template element not found or is empty: ${options.template}`,
              this
            )
          }
        }
      } else if (template.nodeType) { //dom节点
        template = template.innerHTML
      } else {
        if (process.env.NODE_ENV !== 'production') {
          warn('invalid template option:' + template, this)
        }
        return this
      }
    } else if (el) { //最后一种情况查看el选项
      template = getOuterHTML(el)
    }
    //如何处理模版,编译渲染
    if (template) {
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        mark('compile')
      }

      const { render, staticRenderFns } = compileToFunctions(template, {
        outputSourceRange: process.env.NODE_ENV !== 'production',
        shouldDecodeNewlines,
        shouldDecodeNewlinesForHref,
        delimiters: options.delimiters,
        comments: options.comments
      }, this)
      //重新赋值给我们的选项
      options.render = render
      options.staticRenderFns = staticRenderFns

      /* istanbul ignore 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Goat恶霸詹姆斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值