摘要:今天研究的對象是抽象語法樹它以樹狀的形式表現(xiàn)編程語言的語法結(jié)構(gòu),樹上的每個節(jié)點都表示源代碼中的一種結(jié)構(gòu)。總結(jié)發(fā)現(xiàn)水很深平時接觸的也比較少今天算是個入門了解下作為理解源碼前的鋪墊。參考源碼參考文檔
什么是AST
樹是一種重要的數(shù)據(jù)結(jié)構(gòu),由根結(jié)點和若干顆子樹構(gòu)成的。 根據(jù)結(jié)構(gòu)的不同又可以劃分為二叉樹,trie樹,紅黑樹等等。
今天研究的對象是AST,抽象語法樹,它以樹狀的形式表現(xiàn)編程語言的語法結(jié)構(gòu),樹上的每個節(jié)點都表示源代碼中的一種結(jié)構(gòu)。
通過操作這棵樹,可以精準(zhǔn)的定位到聲明、賦值、運算語句,從而實現(xiàn)對代碼的分析、優(yōu)化、變更等操作。
AST處理步驟代碼風(fēng)格,語法的檢查,IDE中的錯誤提示,格式化,自動補(bǔ)全等等
優(yōu)化變更代碼,代碼壓縮等等
es6轉(zhuǎn)es5,以及TypeScript、JSX等轉(zhuǎn)化為原生Javascript等等
js中借助于一些庫可以把js源碼解析為語法樹,比如 Babylon, esprima、acorn、UglifyJS、AST explorer等等,如下所示是一個簡單的示例。
var a = 42; var b = 5; ar c = a + b;
說明 一個簡單的ast樹示例,對應(yīng)的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,可以實現(xiàn)我們AST應(yīng)用場景中列出的一些應(yīng)用。
下面針對上面列出的ast樹做一些簡單說明:
任何一顆ast樹根節(jié)點的類型都是Program,start和end記錄了字符的位置,body表示程序體,其內(nèi)部是三個簡單的變量聲明,每個變量聲明中記錄了標(biāo)示符以及字面量的值。最后一個變量c中init是一個BinaryExpression(二元運算表達(dá)),記錄的不是字面值,而是引用到的標(biāo)示符和操作符。想要實現(xiàn)應(yīng)用場景中舉的示例,大致就是遍歷,修改,刪除,移動這棵樹上的節(jié)點,最后遍歷處理后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處理有關(guān)的上下文關(guān)鍵片段
在webpack執(zhí)行流程中,make是一個重要的階段,在一個新的 Compilation 創(chuàng)建完畢后,即將從 Entry 開始讀取文件,根據(jù)文件類型和配置的 Loader 對文件進(jìn)行編譯,將loader處理后的文件通過acorn抽象成抽象語法樹AST,然后遍歷AST,遞歸分析構(gòu)建該模塊的所有依賴。
發(fā)現(xiàn)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...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93966.html
摘要:引言通過前面幾張的鋪墊下面開始分析源碼核心流程大體上可以分為初始化編譯輸出三個階段下面開始分析初始化這個階段整體流程做了什么啟動構(gòu)建,讀取與合并配置參數(shù),加載,實例化。推薦源碼之源碼之機(jī)制源碼之簡介源碼之機(jī)制參考源碼 引言 通過前面幾張的鋪墊,下面開始分析webpack源碼核心流程,大體上可以分為初始化,編譯,輸出三個階段,下面開始分析 初始化 這個階段整體流程做了什么? 啟動構(gòu)建,讀...
摘要:是一個對象,它表示兩個節(jié)點之間的連接。接著返回一個對象,其屬性是這個插件的主要節(jié)點訪問者。所以上面的執(zhí)行方式是運行引入了自定義插件的打包文件現(xiàn)在為明顯減小,自定義插件成功插件文件目錄覺得好玩就關(guān)注一下歡迎大家收藏寫評論 目錄 Babel簡介 Babel運行原理 AST解析 AST轉(zhuǎn)換 寫一個Babel插件 Babel簡介 Babel 是一個 JavaScript 編譯器,它能將es...
前言 本文所有內(nèi)容全部發(fā)布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續(xù)不斷學(xué)習(xí)更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機(jī)制簡介 axios 核心源碼實現(xiàn)原理 JS 數(shù)據(jù)類型、賦值、深拷貝和淺拷貝 j...
前言 本文所有內(nèi)容全部發(fā)布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續(xù)不斷學(xué)習(xí)更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機(jī)制簡介 axios 核心源碼實現(xiàn)原理 JS 數(shù)據(jù)類型、賦值、深拷貝和淺拷貝 j...
前言 本文所有內(nèi)容全部發(fā)布再個人博客主頁 https://github.com/muwoo/blogs歡迎訂閱。不過最近因為事情比較多,有一段時間沒有更新了,后面打算繼續(xù)不斷學(xué)習(xí)更新,歡迎小伙伴一起溝通交流~ 最近更新 前端單測的那些事 基于virtual dom 的canvas渲染 js Event loop 機(jī)制簡介 axios 核心源碼實現(xiàn)原理 JS 數(shù)據(jù)類型、賦值、深拷貝和淺拷貝 j...
閱讀 3601·2023-04-26 02:55
閱讀 2868·2021-11-02 14:38
閱讀 4147·2021-10-21 09:39
閱讀 2857·2021-09-27 13:36
閱讀 3968·2021-09-22 15:08
閱讀 2658·2021-09-08 10:42
閱讀 2812·2019-08-29 12:21
閱讀 680·2019-08-29 11:22