Decided to follow huang Yi teacher vue2 source course to learn the source of vue2, learning process, as far as possible output their income, improve learning efficiency, the level is limited, wrong words please correct ~

Clone the vue source code locally and switch to branch 2.6.

To know the flow

Flow is a static type checking tool for JavaScript from Facebook. Vue uses it for type detection.

How to use flow

Installation:

npm i flow-bin -g
Copy the code

Create a configuration file:

flow init
Copy the code

Create a js file

/*@flow*/

function split(str) {
  return str.split("");
}

split(11);
Copy the code

Run the flow command to check, and you will find an error

How flow works

There are two types of type checking:

  • Type inference: Infer the type of a variable from the context in which it is used, and then check the type against these inferences. (The examples above are inferences)

  • Type comments: Make a pre-comment about the type we expect, and Flow will judge based on these comments. (recommended)

Type annotations are very similar to TS:

/*@flow*/

function add(x: number, y: number) :number {
  return x + y;
}

add("Hello".11);
// Execute flow, an error occurs
Copy the code

Add /*@flow*/ to the first line of the file that needs flow check

If undefined or null:

var foo: string | void = null;
varfoo: ? string =null;
Copy the code

Flow is used in vue source code

Flow can be a custom type, vue home directory. Flowconfig file, which is the flow configuration file. The [libs] part of this is used to describe the directory containing the specified library definition, which is named flow by default.

If you come across a type and you want to look at the data structure, look here.

Vue source directory design

Look at SRC’s design:

The function module is split very clearly, so that the readability and maintainability are elegant.

Vue source code construction

The vue.js source code is built based on Rollup, and its buildrelated configurations are in the scripts directory.

Rollup builds JS files, does not process other files, and is much lighter than WebPack.

By build, you run commands and generate the final file.

The build script

The build script is package.json, where the build command is the build command.

Vue runs in three environments:

  • Web (Plain Web side)
  • SSR (Server)
  • Weex (native)

The build process

SRC /build.js simply takes the configuration, filters it according to the environment parameters, and generates the corresponding JS file in the dist directory.

To make the entry/dist path in the configuration more readable, Vue does a few tricks:

const builds = {
  "web-runtime-cjs-dev": {
    // The web is replaced with the absolute path to the Web. Resolve does this
    entry: resolve("web/entry-runtime.js"),
    // The same goes for dist
    dest: resolve("dist/vue.runtime.common.dev.js"),
    format: "cjs".env: "development",
    banner,
  },
  // ...
};
Copy the code

To see the resolve:

const resolve = (p) = > {
  const base = p.split("/") [0];
  // // aliases is the path alias hash table {compile:" Compiler folder absolute address ",core:..... }
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1));
  } else {
    return path.resolve(__dirname, ".. /", p); }};Copy the code

The format attribute

Format indicates what specification the final generated JS file conforms to:

  • The commonJS specification is just thatrequire/module.exports
  • The ESModule specification is just thatimport/export
  • Umd specification, kind of compatibility mode,
(function (window, factory) {
  if (typeof exports= = ="object") {
    module.exports = factory();
  } else if (typeof define === "function" && define.amd) {
    define(factory);
  } else {
    window.eventUtil = factory();
  }
})(this.function () {
  //module ...
});
Copy the code

Tip: Typos and file sizes

There are two functions that you can use everyday

function getSize (code) {
  return (code.length / 1024).toFixed(2) + 'kb'
}

// catch(logError) this is very handy
function logError (e) {
  console.log(e)
}
Copy the code

Runtime Only VS Runtime + Compiler

Actually, these two things are opposite.

When using vue, if template is a string, it looks like this

new Vue({
  template: '<div>{{ hi }}</div>'
})
Copy the code

The vUE must contain the code to compile the template into the render function. The technical term is Compiler

Of course, if there is no such string in the code, Compiler is not needed.

Obviously, the addition of Compiler not only increases the size of the VUE, but also makes the runtime environment do compilation, which is more time-consuming.

The Runtime is vue code without the Compiler. The.vue file is usually used for template development, and the.vue file is in your editor, also known as the Compiler environment. Compile it into the render function (depending on webpack’s vue-loader plug-in), so the environment doesn’t need to compile, just run it, the technical term is Runtime

Obviously Runtime is both lightweight and time saving.

To be honest, if the template does not have strings during development, it is better to use Runtime instead of Compiler

Start at the entrance

Find where to define vUE first!

Dist vue.js is generated by entry-runtime-with-Compiler. js

// entry-runtime-with-compiler.js
import Vue from './runtime/index.js'
// runtime/index.js
import Vue from 'core/index'
// core/index.js
import Vue from './instance/index'
// instance/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)
}

Copy the code

The class is defined as a function, which is easy to extend in vue. prototype, so that the extended methods and properties can be distributed in other files for easy maintenance.

Tip: How to determine whether there is a new call

This is whether this belongs to the current instance

function C(){
  if(!this instanceOf C){console.log('C is a constructor and should be called with the `new` keyword')}}Copy the code

Tip: Define classes in function form for easy extension

Class keyword, the extension will not be convenient, but the function form is more convenient, you can separate methods and properties in other files

function C(){}
// getName.js
C.prototype.getName = function getName(){}
Copy the code

reference

  • Huang Yi teacher vuE2 source decryption course
  • Vue. Js technology revealed