先簡單介紹一下爲何要研究這個事情的背景,咱們但願能夠基於weex framework.js定製一份本身的實現,weex的融合程度已經到達了Vue的倉庫,學會這個,也有助於摸清楚Vue的脈絡。vue
先從package.json開始,從scripts裏能找出五處跟構建weex有關係的鉤子,分別是:node
"dev:weex": "TARGET=weex-framework rollup -w -c build/config.js", "dev:weex:compiler": "TARGET=weex-compiler rollup -w -c build/config.js", "build": "node build/build.js", "build:weex": "npm run build -- weex-vue-framework,weex-template-compiler", "test:weex": "npm run build:weex && jasmine JASMINE_CONFIG_PATH=test/weex/jasmine.json", "release:weex": "bash build/release-weex.sh",
無論是dev環境仍是build環境都指向了build/build.js和build/config.js這兩處文件,而release指向了一段shell腳本,先從release開始看看這段腳本有什麼做用:git
set -e CUR_VERSION=`node build/get-weex-version.js -c` NEXT_VERSION=`node build/get-weex-version.js` echo "Current: $CUR_VERSION" read -p "Enter new version ($NEXT_VERSION): " -n 1 -r if ! [[ -z $REPLY ]]; then NEXT_VERSION=$REPLY fi read -p "Releasing weex-vue-framework@$NEXT_VERSION - are you sure? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Releasing weex-vue-framework@$NEXT_VERSION ..." npm run lint npm run flow npm run test:weex # build WEEX_VERSION=$NEXT_VERSION npm run build:weex # update package cd packages/weex-vue-framework npm version $NEXT_VERSION npm publish cd - cd packages/weex-template-compiler npm version $NEXT_VERSION npm publish cd - # commit git add src/entries/weex* git add packages/weex* git commit -m "[release] weex-vue-framework@$NEXT_VERSION"fi
從脈絡上來看,前面三項的lint flow test都是次要的,主要的是從npm run build:weex開始,看來release也是走到了build/build.js中。web
繼續閱讀build/build.js文件,東西很少,只是一段構建腳本,經過process.argv拿到運行的參數,而後使用rollup來啓動構建。在這個文件中,有這麼一行代碼:let builds = require('./config.js').getAllBuilds(),暫停一下,繼續閱讀build/config.js文件,能夠看到大段的配置信息,找到跟weex相關的有三個,分別是'weex-factory’,'weex-framework’,'weex-compiler’,並且也能夠從entry中找到入口文件,有了入口就比較好辦了。shell
(建議:第一個要學的東西是rollup構建)npm
從構建腳本讀起來,它使用Rollup 構建,起始位置從entries開始,直接載入了weex/framework,在這裏引用vue-runtime(core/index.js),看起來整段腳本使用ES6編寫,並且其內部所引用的都是短路徑,猜想應該是起了別名的,回到build目錄中,能夠看見有alias.js文件,這裏能夠看到不少有用的別名:json
module.exports = { vue: path.resolve(__dirname, '../src/entries/web-runtime-with-compiler'), compiler: path.resolve(__dirname, '../src/compiler'), core: path.resolve(__dirname, '../src/core'), shared: path.resolve(__dirname, '../src/shared'), web: path.resolve(__dirname, '../src/platforms/web'), weex: path.resolve(__dirname, '../src/platforms/weex'), server: path.resolve(__dirname, '../src/server'), entries: path.resolve(__dirname, '../src/entries'), sfc: path.resolve(__dirname, '../src/sfc') }
(註明:這個比React扁平化的構建方式,更易讀)bash
既然找到了weex framework入口文件,在閱讀這個文件中,找到了幾行關鍵性的代碼,我判斷它應該與定製實現framework有關係。weex
const VueFactory = require('./factory')
在 createVueModuleInstance 函數中的:app
const exports = {} VueFactory(exports, renderer) const Vue = exports.Vue
在createInstance函數中的:
Object.freeze(weexInstanceVar)// Each instance has a independent `Vue` mdoule instance const Vue = instance.Vue = createVueModuleInstance(instanceId, moduleGetter) const instanceVars = Object.assign({ Vue, weex: weexInstanceVar, // deprecated __weex_require_module__: weexInstanceVar.requireModule // eslint-disable-line }, timerAPIs) callFunction(instanceVars, appCode)
這是weex能運行Vue的關鍵之處,那麼其實問題也來,在platforms/weex目錄下並無明顯的./factory 文件,那麼這個是從哪裏來的呢?
(註明:到這裏先暫停一下,無論這個./factory是從哪裏來的,且繼續往下看。)
在createInstance函數中,會執行createVueModuleInstance來掛起Vue的引用,而createVueModuleInstance函數裏,看起來weex團隊用到了Vue.mixin來擴展。
(建議:第二個要學的內容,Vue.mixin是什麼鬼)
而createInstance函數中注入了一個instanceVars,這纔是在Native端weex容器中能真正使用的對象。
(建議:第三個要學的內容,freeze是什麼鬼,assign是什麼鬼)
至此,整個脈絡就比較清晰了,後期考慮好以後咱們能夠很方便的實現定製。
不過,回到上面的VueFactory究竟是什麼?只能從build/build.js文件裏着手了,若是它也是一個構建後的平行「文件」,這個極有可能就是指向vue-runtime.js文件的,(猜想),不過看起來好像還有一些其餘的東西。從release shell腳本處理能夠看出來,它執行了npm run build:weex,而這個npm 鉤子其實是傳入了[ 'weex-vue-framework', 'weex-template-compiler' ]給build/build.js文件,經過這個解析能獲得config.js裏的配置清單,之因此須要傳入一個exports,是由於最後這個VueFactory裏會最終存在exports.Vue = Vue$2來進行交換,這樣,就比較明瞭了。
你們要是對Vue的構建有興趣,也能夠摸着上述的脈絡,閱讀一下,整個庫打包的路徑,對於閱讀源碼,有極大的幫助。