摘要:簡單來說就是一個對于代碼的一個編譯過程,進行了詞法分析與語法分析的過程。轉換對于進行變換一系列的操作,接受得到并通過對其進行遍歷,在此過程中進行添加更新及移除等操作。而模塊則是將三者結合使得對外提供的做了一個簡化。
直奔主題
對于js,AST能干什么?
babel將es6轉es5
mpvue、taro等將js轉為小程序
定制插件刪除注釋、console等
ps: 本文只探討AST的概念以及使用,編譯原理的其他知識不做太多描述
工具庫@babel/core
用來解析AST以及將AST生成代碼
@babel/types
構建新的AST節點
前置知識 - 編譯原理概述毫無疑問js是一個解釋型語言,有疑問可以參考這篇文章
所以這里只簡單描述一下babel的編譯過程(大霧),有興趣了解編譯型語言詳細編譯過程的可以看這本 《編譯原理》
和編譯器類似,babel 的轉譯過程也分為三個階段,這三步具體是:生成AST解析 Parse
將代碼解析生成抽象語法樹( 即AST ),也就是計算機理解我們代碼的方式(擴展:一般來說每個 js 引擎都有自己的 AST,比如熟知的 v8,chrome 瀏覽器會把 js 源碼轉換為抽象語法樹,再進一步轉換為字節碼或機器代碼),而 babel 則是通過babylon 實現的 。簡單來說就是一個對于 JS 代碼的一個編譯過程,進行了詞法分析與語法分析的過程。轉換 Transform
對于 AST 進行變換一系列的操作,babel 接受得到 AST 并通過 babel-traverse 對其進行遍歷,在此過程中進行添加、更新及移除等操作。生成 Generate
將變換后的 AST 再轉換為 JS 代碼, 使用到的模塊是 babel-generator。而 babel-core 模塊則是將三者結合使得對外提供的API做了一個簡化。
demo.js是我隨便copy來的一段代碼
isLeapYear() function isLeapYear(year) { const cond1 = year % 4 == 0; //條件1:年份必須要能被4整除 const cond2 = year % 100 != 0; //條件2:年份不能是整百數 const cond3 = year % 400 ==0; //條件3:年份是400的倍數 const cond = cond1 && cond2 || cond3; console.log(cond) if(cond) { alert(year + "是閏年"); return true; } else { alert(year + "不是閏年"); return false; } }
現在我要把它轉成AST,這里使用@babel/core來解析,它提供了一個parse方法來將代碼轉化為AST。
parse.ts就是我的解析工具
import * as fs from "fs" import * as path from "path" import { parse} from "@babel/core" const js_path = path.resolve(__dirname, "../demo.js") let code = fs.readFileSync(js_path, { encoding: "utf-8" }) const js_ast = parse(code) console.log(js_ast)
可以看到AST結果如下:
結果太長就不一一解析了,只說type屬性,就表示了這一行代碼做了什么,VariableDeclaration就表示這是一句聲明語句, CallExpression則代表這是一個調用函數的語句
將AST轉回代碼@babel/core提供了一個transform方法,輸入代碼和修改代碼的規則,輸出修改過的AST,它看起來是這樣的:
const ArrowPlugins = { visitor: { VariableDeclaration(path: NodePath) { // ... }, CallExpression(path: NodePath) { // ... } } } const d = transform(code, { plugins: [ ArrowPlugins ] })
當命中對應的type時就會走進相應的回調函數,接下來寫個小
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105471.html
摘要:為什么要談抽象語法樹如果你查看目前任何主流的項目中的,會發現前些年的不計其數的插件誕生。什么是抽象語法樹估計很多同學會和圖中的喵一樣,看完這段官方的定義一臉懵逼。它讀取我們的代碼,然后把它們按照預定的規則合并成一個個的標識。 前言 首先,先說明下該文章是譯文,原文出自《AST for JavaScript developers》。很少花時間特地翻譯一篇文章,咬文嚼字是件很累的事情,實在...
摘要:前言虛擬語法樹是解釋器編譯器進行語法分析的基礎也是眾多前端編譯工具的基礎工具比如等對于由于前端輪子眾多人力過于充足早已經被人們玩膩了光是語法分析器就有等等若干種并且也有了的社區標準這篇文章主要介紹如何去寫一個解析器但是并不是通過分析而是通過 前言 虛擬語法樹(Abstract Syntax Tree, AST)是解釋器/編譯器進行語法分析的基礎, 也是眾多前端編譯工具的基礎工具, 比如...
摘要:前言虛擬語法樹是解釋器編譯器進行語法分析的基礎也是眾多前端編譯工具的基礎工具比如等對于由于前端輪子眾多人力過于充足早已經被人們玩膩了光是語法分析器就有等等若干種并且也有了的社區標準這篇文章主要介紹如何去寫一個解析器但是并不是通過分析而是通過 前言 虛擬語法樹(Abstract Syntax Tree, AST)是解釋器/編譯器進行語法分析的基礎, 也是眾多前端編譯工具的基礎工具, 比如...
摘要:的抽象語法樹中可能如下圖所示代碼生成將轉換為可執行代碼的過程被稱為代碼生成。如果是,編譯器會忽略該聲明,繼續進行編譯,否則它會要求在當前作用域的集合中聲明一個新的變量,并命名為。 在學習 javascript 的過程中,我們第一步最應該了解和掌握的就是作用域,與之相關還有程序是怎么編譯的,變量是怎么查找的,js 引擎是什么,引擎和作用域的關系又是什么,這些是 javascript 這門...
閱讀 1349·2021-09-28 09:43
閱讀 4116·2021-09-04 16:41
閱讀 1918·2019-08-30 15:44
閱讀 3729·2019-08-30 15:43
閱讀 776·2019-08-30 14:21
閱讀 2037·2019-08-30 11:00
閱讀 3320·2019-08-29 16:20
閱讀 1923·2019-08-29 14:21