摘要:今天研究的對象是抽象語法樹它以樹狀的形式表現編程語言的語法結構,樹上的每個節點都表示源代碼中的一種結構。總結發現水很深平時接觸的也比較少今天算是個入門了解下作為理解源碼前的鋪墊。參考源碼參考文檔
什么是AST
樹是一種重要的數據結構,由根結點和若干顆子樹構成的。 根據結構的不同又可以劃分為二叉樹,trie樹,紅黑樹等等。
今天研究的對象是AST,抽象語法樹,它以樹狀的形式表現編程語言的語法結構,樹上的每個節點都表示源代碼中的一種結構。
通過操作這棵樹,可以精準的定位到聲明、賦值、運算語句,從而實現對代碼的分析、優化、變更等操作。
AST處理步驟代碼風格,語法的檢查,IDE中的錯誤提示,格式化,自動補全等等
優化變更代碼,代碼壓縮等等
es6轉es5,以及TypeScript、JSX等轉化為原生Javascript等等
js中借助于一些庫可以把js源碼解析為語法樹,比如 Babylon, esprima、acorn、UglifyJS、AST explorer等等,如下所示是一個簡單的示例。
var a = 42; var b = 5; ar c = a + b;
說明 一個簡單的ast樹示例,對應的json格式如下所示
{ "type": "Program", "start": 0, "end": 37, "body": [ { "type": "VariableDeclaration", "start": 0, "end": 11, "declarations": [ { "type": "VariableDeclarator", "start": 4, "end": 10, "id": { "type": "Identifier", "start": 4, "end": 5, "name": "a" }, "init": { "type": "Literal", "start": 8, "end": 10, "value": 42, "raw": "42" } } ], "kind": "var" }, { "type": "VariableDeclaration", "start": 12, "end": 22, "declarations": [ { "type": "VariableDeclarator", "start": 16, "end": 21, "id": { "type": "Identifier", "start": 16, "end": 17, "name": "b" }, "init": { "type": "Literal", "start": 20, "end": 21, "value": 5, "raw": "5" } } ], "kind": "var" }, { "type": "VariableDeclaration", "start": 23, "end": 37, "declarations": [ { "type": "VariableDeclarator", "start": 27, "end": 36, "id": { "type": "Identifier", "start": 27, "end": 28, "name": "c" }, "init": { "type": "BinaryExpression", "start": 31, "end": 36, "left": { "type": "Identifier", "start": 31, "end": 32, "name": "a" }, "operator": "+", "right": { "type": "Identifier", "start": 35, "end": 36, "name": "b" } } } ], "kind": "var" } ], }
通過操縱解析出來的ast,可以實現我們AST應用場景中列出的一些應用。
下面針對上面列出的ast樹做一些簡單說明:
任何一顆ast樹根節點的類型都是Program,start和end記錄了字符的位置,body表示程序體,其內部是三個簡單的變量聲明,每個變量聲明中記錄了標示符以及字面量的值。最后一個變量c中init是一個BinaryExpression(二元運算表達),記錄的不是字面值,而是引用到的標示符和操作符。想要實現應用場景中舉的示例,大致就是遍歷,修改,刪除,移動這棵樹上的節點,最后遍歷處理后ast生成最終代碼。
//compile.js this.hooks.make.callAsync(compilation, err => {}); ---- //NormalModules.js runLoaders( { resource: this.resource, loaders: this.loaders, context: loaderContext, readResource: fs.readFile.bind(fs) }, (err, result) => { this._source = this.createSource( this.binary ? asBuffer(source) : asString(source), resourceBuffer, sourceMap ); return callback(); } ); ---------------------------------- //Parse.js const acorn = require("acorn-dynamic-import").default; ast = acorn.parse(code, parserOptions); if (this.hooks.program.call(ast, comments) === undefined) { this.detectStrictMode(ast.body); this.prewalkStatements(ast.body); this.walkStatements(ast.body); }
說明 上面是webpack源碼中摘取的和ast處理有關的上下文關鍵片段
在webpack執行流程中,make是一個重要的階段,在一個新的 Compilation 創建完畢后,即將從 Entry 開始讀取文件,根據文件類型和配置的 Loader 對文件進行編譯,將loader處理后的文件通過acorn抽象成抽象語法樹AST,然后遍歷AST,遞歸分析構建該模塊的所有依賴。
發現ast水很深,平時接觸的也比較少, 今天算是個入門了解下,作為理解webpack源碼前的鋪墊。
參考源碼
webpack: "4.4.1"
webpack-cli: "2.0.13"
參考文檔
https://github.com/acornjs/acorn
https://zh.wikipedia.org/wiki...
https://www.sitepoint.com/und...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93966.html
摘要:引言通過前面幾張的鋪墊下面開始分析源碼核心流程大體上可以分為初始化編譯輸出三個階段下面開始分析初始化這個階段整體流程做了什么啟動構建,讀取與合并配置參數,加載,實例化。推薦源碼之源碼之機制源碼之簡介源碼之機制參考源碼 引言 通過前面幾張的鋪墊,下面開始分析webpack源碼核心流程,大體上可以分為初始化,編譯,輸出三個階段,下面開始分析 初始化 這個階段整體流程做了什么? 啟動構建,讀...
摘要:是一個對象,它表示兩個節點之間的連接。接著返回一個對象,其屬性是這個插件的主要節點訪問者。所以上面的執行方式是運行引入了自定義插件的打包文件現在為明顯減小,自定義插件成功插件文件目錄覺得好玩就關注一下歡迎大家收藏寫評論 目錄 Babel簡介 Babel運行原理 AST解析 AST轉換 寫一個Babel插件 Babel簡介 Babel 是一個 JavaScript 編譯器,它能將es...
前言 本文所有內容全部發布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續不斷學習更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機制簡介 axios 核心源碼實現原理 JS 數據類型、賦值、深拷貝和淺拷貝 j...
前言 本文所有內容全部發布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續不斷學習更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機制簡介 axios 核心源碼實現原理 JS 數據類型、賦值、深拷貝和淺拷貝 j...
前言 本文所有內容全部發布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續不斷學習更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機制簡介 axios 核心源碼實現原理 JS 數據類型、賦值、深拷貝和淺拷貝 j...
閱讀 3581·2023-04-26 02:55
閱讀 2849·2021-11-02 14:38
閱讀 4136·2021-10-21 09:39
閱讀 2842·2021-09-27 13:36
閱讀 3943·2021-09-22 15:08
閱讀 2644·2021-09-08 10:42
閱讀 2802·2019-08-29 12:21
閱讀 667·2019-08-29 11:22