Vue源码阅读——框架分析

随着Vue框架状态越来越火热,不少feder已经不仅仅满足于vue框架的使用,有很多人都打算阅读vue源码来提升自己。那么提到源码阅读就不免产生了一个问题,到底要从何处开始源码阅读呢?

package的入口:

// package.json
"main": "dist/vue.runtime.common.js"

经过全局搜索文件名找到入口源码的打包配置在scripts/config.js

// scripts/config.js

  'web-runtime-cjs-dev': {
   
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  },
  'web-runtime-cjs-prod': {
   
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.prod.js'),
    format: 'cjs',
    env: 'production',
    banner
  }

即项目入口为:

// scripts/config.js
resolve('web/entry-runtime.js')

可以看到这个地址并非是直接目录,同文件内找到解析函数resolve:

// scripts/config.js
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)
  }
}

可以看到这个地址解析函数引入了别名文件,并且取’/‘之前的作为别名检查存在性,如果不存在则整体进行解析,可以看到入口文件的’/'之前是web,打开别名文件./alias

// scripts/alias.js
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')
}

可以看到web这个别名是存在的,因此入口地址

resolve('web/entry-runtime.js')

将被解析为:

src/platforms/web/entry-runtime.js

打开该文件:

// src/platforms/web/entry-runtime.js
import Vue from './runtime/index'
export default Vue

即入口文件在此处的操作是引入./runtime/inde并暴露出去,因此核心文件的解析将从src/platforms/web/runtime/index.js开始

// src/platforms/web/runtime/index.js

/* @flow */
import Vue from 'core/index'
import config from 'core/config'
import {
    extend, noop } from 'shared/util'
import {
    mountComponent } from 'core/instance/lifecycle'
import {
    devtools, inBrowser } from 'core/util/index'

import {
   
  query,
  mustUseProp,
  isReservedTag,
  isReservedAttr,
  getTagNamespace,
  isUnknownElement
} from 'web/util/index'

import {
    patch } from './patch'
import platformDirectives from './directives/index'
import platformComponents from './components/index'

// install platform specific utils
// 标签及属性使用限制
Vue.config.mustUseProp = mustUseProp
// 判定是否为html或svg标签
Vue.config.isReservedTag = isReservedTag
// 判定是否为style、class
Vue.config.isReservedAttr = isReservedAttr
// 获取tag的命名空间
Vue.config.getTagNamespace = getTagNamespace
// 判定标签是否为未定义标签
Vue.config.isUnknownElement = isUnknownElement

// install platform runtime directives & components
// 给vue原型链上进行方法挂载
// 将platformDirectives对象可枚举属性拷贝给Vue.options.directives
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)

// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop

// public mount method
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
   
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}

// devtools global hook
/* istanbul ignore next */
if (inBrowser) {
   
  setTimeout(() => {
   
    // 开发者工具init事件触发及提示
    if (config.devtools) {
   
      if (devtools) {
   
        devtools.emit('init', Vue)
      } else if (
        process.env.N
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值