Build the development environment with Rollup

1. What is Rollup?

Rollup is a JavaScript module wrapper that compiles small pieces of code into large, complex pieces of code. Rollup. js is more focused on JavaScript library packaging (use WebPack for application development, Rollup for library development).

2. Environment construction

Install the rollup environment


npm install @babel/preset-env @babel/core rollup rollup-plugin-babel rollup-plugin-serve cross-env -D
Copy the code

Rollup.config. js file

import babel from 'rollup-plugin-babel'; import serve from 'rollup-plugin-serve'; Export default {input: './ SRC /index.js', output: {format: 'umd', // Module type file: 'dist/umd/vue.js', name: 'Vue', // the name of the packaged global variable sourcemap: true}, plugins: [Babel ({exclude: 'node_modules/**' }), process.env.ENV === 'development'?serve({ open: true, openPage: '/public/index.html', port: 3000, contentBase: '' }):null ] }Copy the code

Configure the. Babelrc file


{
    "presets": [
        "@babel/preset-env"
    ]
}
Copy the code

Executing script Configuration


"scripts": {
    "build:dev": "rollup -c",
    "serve": "cross-env ENV=development rollup -c -w"
}
Copy the code

Vue response principle

Export the vue constructor

import {initMixin} from './init'; function Vue(options) { this._init(options); } initMixin(Vue); // Add the _init method export default Vue to the prototype;Copy the code

Initialize the VUE state in the init method

import {initState} from './state'; export function initMixin(Vue){ Vue.prototype._init = function (options) { const vm = this; $options = options // initialization state initState(VM)}}Copy the code

Initialize operations based on different attributes

export function initState(vm){ const opts = vm.$options; if(opts.props){ initProps(vm); } if(opts.methods){ initMethod(vm); } if(opts.data){// Initialize data initData(vm); } if(opts.computed){ initComputed(vm); } if(opts.watch){ initWatch(vm); } } function initProps(){} function initMethod(){} function initData(){} function initComputed(){} function initWatch(){}Copy the code

1. Initialize data


import {observe} from './observer/index.js'
function initData(vm){
    let data = vm.$options.data;
    data = vm._data = typeof data === 'function' ? data.call(vm) : data;
    observe(data);
}
Copy the code

2. Recursive attribute hijacking

Class Observer {// Constructor (value){this.walk(value); } walk(data){let keys = object.keys (data); for(let i = 0; i < keys.length; i++){ let key = keys[i]; let value = data[key]; defineReactive(data,key,value); } } } function defineReactive(data,key,value){ observe(value); Object.defineProperty(data,key,{ get(){ return value }, set(newValue){ if(newValue == value) return; observe(newValue); value = newValue } }) } export function observe(data) { if(typeof data ! == 'object' || data == null){ return; } return new Observer(data); }Copy the code

3. Hijacking of array methods

import {arrayMethods} from './array'; Constructor (value){if(array.isarray (value)){value.__proto__ = arrayMethods; // Override the array prototype method this.observeArray(value); }else{ this.walk(value); } } observeArray(value){ for(let i = 0 ; i < value.length ; i ++){ observe(value[i]); }}}Copy the code

Overrides array prototype methods

let oldArrayProtoMethods = Array.prototype; export let arrayMethods = Object.create(oldArrayProtoMethods); let methods = [ 'push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice' ]; methods.forEach(method => { arrayMethods[method] = function (... args) { const result = oldArrayProtoMethods[method].apply(this, args); const ob = this.__ob__; let inserted; switch (method) { case 'push': case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2) default: break; } if (inserted) ob.observeArray(inserted); Return result}})Copy the code

Add OB attributes

class Observer { constructor(value){ Object.defineProperty(value,'__ob__',{ enumerable:false, configurable:false, value:this }); / /... }}Copy the code

Add identifiers to all reactive data and get methods on Observer instances on reactive data

4.Data brokers

function proxy(vm,source,key){ Object.defineProperty(vm,key,{ get(){ return vm[source][key]; }, set(newValue){ vm[source][key] = newValue; }}); } function initData(vm){ let data = vm.$options.data; data = vm._data = typeof data === 'function' ? data.call(vm) : data; For (let key in data){proxy(vm,'_data',key)} observe(data); }Copy the code