Vue2.x源码解析(一)

  随着Vue3.0的发布,可以看到如今Vue在现如今的前端开发上占据着越来越重要的地位,那么如果我们了解vue的底层原理,了解其工作机制,无疑会加深我们对他的印象,这样在之后的使用过程中,遇到问题就能从一个更广阔的角度去分析问题产生的原因,而实现这些最好的方式就是看源码。因为Vue3.0发布时间不长,所以我们首先先来分析vue2.x的源码,因为vue2.x版本和vue3.0版本有很多方法的实现方式是类似的,我们先学习了上一个版本的知识,更有助于我们与新的版本产生对比,分析它改动了哪里,而又为什么要改变,那么废话不多说,让我们先从vue的入口开始

vue入口在哪里?

  这里介绍的是Runtime+Complier构建出来的vue,那么这有是什么意思呢?vue主要分为两种:一种是Runtime only,一种是上面的,前者当使用vue-loader或vueify时,vue内部模板会预编译成javascript,所以最终打好的包是不需要编译器的,这样的话运行时版本会比完整版体积要小30%,所以比较推荐使用Runtime only版本的vue,但是这里是在进行源码解析,所以还是要挑完整的来。
  那么进入正题,首先要先找到入口文件,通过npm托管的项目会有一个package.json的文件用来对项目进行描述,我们在其中找到script字段,我们只关心build开头的三个命令,如下:

    "build": "node scripts/build.js",
    "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
    "build:weex": "npm run build -- weex",

  于是我们知道了构建入口的js文件,是scripts文件夹下的builds文件,我们先只关心下面这段代码(注释是我在看源码时加上的):

let builds = require('./config').getAllBuilds()

//对配置进行过滤
// filter builds via command line arg
if (process.argv[2]) {
  const filters = process.argv[2].split(',')//过滤掉不需要的
  builds = builds.filter(b => {
    return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
  })
} else {
  //没有则过滤掉week
  // filter out weex builds by default
  builds = builds.filter(b => {
    return b.output.file.indexOf('weex') === -1
  })
}

// 构建函数
build(builds)

  然后我们来看配置文件config,我们先只看builds变量(代码较长,做了缩减):

//format表格式即cmd,amd之类
//banner注释
const builds = {
  // Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
  'web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  },
  ......
}
 

  这里主要是Vue.js构建的一些配置,其中entry表示构建的入口js文件地址,dest表示构建后的文件地址,我们以web-runtime-cjs-dev为例,先看entry,调用了resolve函数。

//解析路径
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)
  }
}

  这个函数首先将参数p分割成了数组,然后将数组首项作为base,所以之前的例子中base为web,之后去alias中去寻找alias[web]的值:

const path = require('path')

const resolve = p => path.resolve(__dirname, '../', p)

//地址映射
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')
}

  这里可以看到其对应的为 src/platforms/web 之后resolve函数通过path.resolve函数进行拼接,于是我们就可以找到用例的入口文件为src/platforms/web/entry-runtime.js,同理我们也能找到带编译的入口文件为src/platforms/web/entry-runtime-with-compiler.js
  下一篇会接着介绍入口文件,并且会找出vue的庐山真面目,之后会补上链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值