1. 程式人生 > >Vue原始碼中compiler部分邏輯梳理(內有彩蛋)

Vue原始碼中compiler部分邏輯梳理(內有彩蛋)

目錄

  • 一. 簡述
  • 二. 編譯流程
  • 三. 彩蛋環節

示例程式碼託管在:http://www.github.com/dashnowords/blogs

部落格園地址:《大史住在大前端》原創博文目錄

華為雲社群地址:【你要的前端打怪升級指南】

一. 簡述

compiler模組Vue框架中用於模板編譯的,它的作用就是將Vue中的元件模板轉換成render函式,render函式在執行時可以生成虛擬節點vnode,它是Vue中虛擬DOM樹的基本實現流程。完整版的Vue是包含runtimecompiler

的,也就是說模板的編譯過程可以在執行時進行,這無疑是一種效能負擔。Vue官方也提供了獨立的runtime版本,其中只包含執行時環境,把從templaterender函式的生成部分放在構建時完成(利用vue-templete-compiler模組),以提高執行時的效率。

由於跨平臺需求,compiler模組的實現過程步驟稍多,不斷地利用高階函式來拆分整體邏輯,不是很容易閱讀,本篇對該模組的基本流程進行一個梳理,再參考文末彩蛋推薦的電子書,就比較容易看懂了。

二. 編譯流程

相關入口在例項掛載函式$mount的實現中:

Vue.prototype.$mount = function(){
    const options = this.$options
    //....
     const { render, staticRenderFns } = compileToFunctions(template, {
        shouldDecodeNewlines,
        shouldDecodeNewlinesForHref,
        delimiters: options.delimiters,
        comments: options.comments
      }, this)
      options.render = render
      options.staticRenderFns = staticRenderFns
    //....
    return mount.call(this, el, hydrating)
}

可以看到例項掛載方法$mount的邏輯就是在呼叫mount方法前在例項的$options添加了額外的資訊。此處呼叫的compileToFunctions方法經歷的邏輯跳轉了多層高階函式,涉及檔案也比較多,直接上圖比較清楚:

筆者將涉及函式簡化為輸入輸出的形式:

核心邏輯步驟如下所示:

梳理完流程,整個編譯流程的巨集觀流程也就相對清晰了,這裡為了兼顧不同平臺的方法差異,將有差異的部分提取為獨立的模組,然後作為函式引數注入執行函式,這種通過高階函式來組織程式碼的方式能提高核心邏輯的聚合程度,如果是普通的業務邏輯,很可能會是以扁平化串聯呼叫的形式來編寫方法的,筆者個人認為兩種模式沒有絕對的優劣對比,雖然高階函式看起來更高階。

三. 彩蛋環節

分享一本非常詳細的講述Vue核心原理的開源電子書【Vue.js 技術揭祕