Vue source code parsing (a)

Some time ago with vue3 development of several projects, because vue3 has a lot of new features so it is necessary to learn about the source of VUe3, before this, first to review the source of vue2. I’ll break down the underlying vue code in several sections.

1. Source code construction

The source code for Vue is built based on Rollup, and its configuration information is all in scripts

"scripts": {
    "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev", · · · · · ·"build": "node scripts/build.js"."build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer"."build:weex": "npm run build -- weex", · · · · · ·}Copy the code

After executing build, go back to the build entry file scripts/build.js

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

// filter builds via command line arg
if (process.argv[2]) { // Here is to determine whether the build has other items
  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 {
  // filter out weex builds by default
  builds = builds.filter(b= > {
    return b.output.file.indexOf('weex') = = = -1
  })
}

build(builds)
Copy the code

In build.js we found that he had taken builds from config.js and made a filter to build different blocks of code. Following the logic, resolve will be used to find the corresponding entry files in builds and they will be built as exit files in Dest

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}, ·····Copy the code

That is, after executing the command build package, Entry will use the resolve function to find the corresponding code block based on the content and output it to Dest. The js file will eventually be generated in the dist directory.

Build a summary

Through the above part of learning we understand the vUE underlying construction package, but also know the different functions and functions of vue.js their corresponding entry and the final compilation generated JS files.

Initialize the

According to the above, we can be informed of the vue code is in the SRC/core/index. In js, according to which we have found the place to store the vue SRC/core/instance/index. Js

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '.. /util/index'

function Vue (options) {
  if(process.env.NODE_ENV ! = ='production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')}this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue
Copy the code

Vue is actually a Function class, so we need new vue to instantiate it every time. There are also many functions with xxxMixin and vUE as arguments. Here are some methods mounted on VuePrototype.

initGlobalAPI

InitGlobalAPI mounts common methods such as nextTick during vue initialization, and vue’s global API can be found here

export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () = > config
  if(process.env.NODE_ENV ! = ='production') {
    configDef.set = () = > {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.')}}Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type= > {
    Vue.options[type + 's'] = Object.create(null)})// this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue

  extend(Vue.options.components, builtInComponents)

  initUse(Vue)
  initMixin(Vue)
  initExtend(Vue)
  initAssetRegisters(Vue)
}
Copy the code

Initialization summary

At this point, vUE initialization is basically over, I believe that after reading everyone has some basic cognition of VUE, there are a lot of things in the article we will slowly learn later.

Stern said

This is the first time for me to post an article in Nuggets, because I answered some questions in Zhihu before, I found that writing some articles can not only know my knowledge, but also consolidate knowledge and discover new knowledge points. So I wrote this article, the first post may not be very friendly, the subsequent iterations will be slowly. This article references vUE technical debunking. Write of very good, interested can go to see, the purpose that I write an article is used to consolidate knowledge point.