version: 2.5.17-beta.0vue
首先從package.json文件開始看,scripts裏有一條命令是dev:ios
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev"
它運行了scripts/config.js文件,這個文件生成了rollup打包器的配置,這個文件裏web-full-dev對應的配置是這樣的:web
// Runtime+compiler development build (Browser) 'web-full-dev': { entry: resolve('web/entry-runtime-with-compiler.js'), dest: resolve('dist/vue.js'), format: 'umd', env: 'development', alias: { he: './entity-decoder' }, banner }
entry入口是web/entry-runtime-with-compiler.js這個文件,可是直接找不到web目錄在哪裏,原來這裏是本身定義了一個路徑別名,scripts/config.js裏有方法專門來轉換別名路徑變成真正的路徑:json
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) } }
這裏引入的alias正是別名對應的真實路徑:api
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'), entries: resolve('src/entries'), sfc: resolve('src/sfc') }
這時就能知道,web/entry-runtime-with-compiler.js對應的路徑是src/platforms/web/entry-runtime-with-compiler.js。weex
打開entry-runtime-with-compiler.js文件,發現這樣一句:less
import Vue from './runtime/index'
因而打開runtime/index.js,發現這樣一句:ide
import Vue from 'core/index'
打開core/index.js,發現這樣一句:函數
import Vue from './instance/index'
打開instance/index.js,發現Vue構造函數就在這裏:工具
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) }
這裏作了判斷,若是是開發環境而不是生產環境,並且實例化vue對象的時候沒有使用new操做符,就會報一個警告,而後針對傳入的options執行以後的操做。
爲何(this instanceof Vue)這一句能夠判斷是否使用了new操做符?
已new來調用構造函數會經歷4個步驟:
而instanceof用來檢測Vue構造函數的prototype是否存在於this的原型鏈上,換句話說,若是使用new實例化的時候,this就指向了這個新建立的對象,這時this instanceof Vue這句話的意思就是判斷新建立的對象是不是Vue類型的,也就至關於判斷新實例對象的constructor是不是Vue構造函數。
initGlobalAPI(Vue)
從函數名字能夠看出它的意思,爲Vue構造函數初始化全局API,也就是官方文檔裏列出來的那一串API列表,它們都是直接掛在Vue構造函數上的屬性。
initGlobalAPI在core/global-api/index.js這個文件裏定義。
//initGlobalAPI初始化全局API 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) //爲Vue構造函數定義一個叫作config的屬性,官方API文檔裏寫「Vue.config 是一個對象,包含 Vue 的全局配置。」 //經過上面對configDef這個屬性描述符的定義,能夠發現這個Vue.config是一個訪問器屬性,而不是數據屬性 //由於它擁有get和set方法,專門處理讀取和修改它的動做 //它的get方法直接返回core/config.js這個文件定義的全局配置 //它的set方法會報一個警告,不要替換整個Vue.config對象,而是設置單個配置項 // 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裏的方法並非全局API,避免依賴它們除非你知道它們的風險 Vue.util = { warn, extend, mergeOptions, defineReactive } //warn方法,在core/util/debug.js裏,報錯方法 //extend方法,在shared/util.js裏,用於將一個對象的多個屬性加到另外一個對象上去 //mergeOptions,在core/util/options.js裏,用於按不一樣參數的策略合併option //defineReactive,在core/observer/index Vue.set = set //set方法,在core/observer/index.js裏,用於給對象設置一個響應式屬性。若是這個屬性被刪除那就會觸發通知。 Vue.delete = del //delete方法,在core/observer/index.js裏,刪除一個屬性而且觸發試圖更新若是須要的話 Vue.nextTick = nextTick //nextTick方法,在core/util/next-tick.js裏,DOM更新循環結束以後執行延遲迴調 Vue.options = Object.create(null) ASSET_TYPES.forEach(type => { Vue.options[type + 's'] = Object.create(null) }) //Vue.options.components,Vue.options.directives,Vue.options.filters // 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) //給Vue.options.components增長內建component,KeepAlive, //(extend方法,在shared/util.js裏,用於將一個對象的多個屬性加到另外一個對象上去) initUse(Vue)//Vue.use,core/global-api/use.js initMixin(Vue)//Vue.mixin,core/global-api/mixin.js initExtend(Vue)//Vue.extend,core/global-api/extend.js initAssetRegisters(Vue)//Vue.component,Vue.directive,Vue.filter,core/global-api/assets.js }
initGlobalAPI爲Vue構造函數添加不少全局API方法和屬性。