摘要:表示的是在嚴格模式下解析并且允許模塊定義即能識別和語法識別不了。
前段時間開始研究ast,然后慢慢的順便把babel都研究了,至于ast稍后的時間會寫一篇介紹性博客專門介紹ast,本博客先介紹一下babel的基本知識點。
背景:
由于現在前端出現了很多非es5的語法,如jsx,.vue,ts等等的格式和寫法,如果要在瀏覽器的設備上識別并執行,需要額外將這些非傳統格式的語法轉成傳統的es5格式,而babel插件,就是用來將非es5格式的語法轉成es5語法。
babel其實是一個解釋器,它主要講進行中的代碼分為三個階段執行:解釋,轉換,生成。其中babel插件或者其他插件都是在轉換階段起作用。
babel核心包:
babel既然是個解釋器,那么就會擁有解釋,遍歷,以及生成的一系列工具和api:
1)babylon:babel里面用來將js代碼詞法分析,生成ast,他的結構有些像acron,它的返回的結構里面包含著ast和tokens。
require("babylon").parse("code", { // parse in strict mode and allow module declarations sourceType: "module", plugins: [ // enable jsx and flow syntax "jsx", "flow" ] });
sourceType: module表示的是在嚴格模式下解析并且允許模塊定義(即能識別import和expor語法);script識別不了。
2)babel-traverse:功能就像estraverse一樣,主要是給plugin提供遍歷ast節點的功能;
var babylon = require("babylon"); var result = babylon.parse(code, { sourceType: "module",}); console.log("result:", result); import traverse from "babel-traverse"; traverse(result, { enter(node) { console.log(node); } });
3)babel-generator:將ast生成js代碼;
var babylon = require("babylon"); var result = babylon.parse(code, { sourceType: "module",}); console.log("result:", result); import traverse from "babel-traverse"; import generate from "babel-generator"; traverse(result, { enter(node) { console.log(node); } }); var conde1 = generate(result); console.log("generate:", conde1);
babel工具包:
要完成復雜的轉換工作,單靠核心包是不能完成的,所以必要還要依賴于其他工具包輔助。
1)babel-types:包含著ast中的所有類型,可以生成一個ast的節點,然后替換真是ast的節點,從而改變ast的內容(ast工具庫,類似于lodash,具有校驗,創建和轉換ast的方法)。
import * as t from "babel-types"; console.log(t.stringLiteral("my-module")); 語法:t.anyTypeAnnotation(內容) // 最終返回一個類型的對象
2)babel-template:可以通過字符串的形式生成一個ast;
import template from "babel-template"; const buildRequire = template(` var IMPORT_NAME = require(SOURCE); `); const ast2 = buildRequire({ IMPORT_NAME: t.identifier("myModule"), SOURCE: t.stringLiteral("my-module") }); console.log("ast2", ast2);
3)babel-helps: 主要是用來協助babel轉換;
4)babel-core-frame: 主要是用來將錯誤信息打印出來;
5)babel-cli:babel的命令行工具,通過命令行對js代碼進行轉譯;
6)babel-register: 因為babel工具文件,插件里面使用了很多require,而 該文件可以將node中的require于babel中的require綁定,從而可以使用require引入文件;
7)babel-plugin-xxx: 在轉換過程中使用的插件;
8)babel-plugin-transform-xxx: 在transerform過程中使用到的插件;
(.babelrc文件:該文件會在babel編譯過程中,自動配置babel的參數,babel的運行環境--env,babel的設置---preset,babel的所需要用到的插件---plugins等)
9)babel-core:該核心包包含著babel的核心(babel-lon,babel-traverse,babel-generate),提供了更多更友善的api給開發者使用。
babel編譯原理:
編譯器就是講高級的語言或者語法,編譯成更進階機器識別的語言和語法;
babel其實更像一個轉譯器,因為它主要是將高級的js語法轉成低級的語法;
他們兩者雖然有區別,但有很多相似之處(都是經歷三個過程:解析,處理,生成);
以es6轉成es5為例:
ES6代碼輸入 ==》 babylon進行解析 ==》 得到AST ==》 plugin用babel-traverse對AST樹進行遍歷轉譯 ==》 得到新的AST樹 ==》 用babel-generator通過AST樹生成ES5代碼
babel-pollfill,babel-runtime,transfer-runtime的區別:
babel-pollfill是針對于應用和頁面范圍內,對新的對象和新的語法進行兼容,主要是通過一些輔助函數進行兼容新的語法,但如果針對外部的庫使用,就會產生污染全局環境的影響,一般對項目代碼使用;
babel-runtime是對于外部插件和庫的語法兼容,能將新的對象和語法,通過在運行時,把對應的可識別的語法和對象匹配出來并進行轉換,從而顯示在運行時進行語法降級兼容,且不會產生全局污染,一般對外部的插件使用;
transfer-babel是對babel-runtime進行封裝,新的語法,對象能通過該插件,換種形式引用runtime的東西;
(其實runtime,pollfill都是建立在core-js之上的)。
對于babel的插件,主要是因為生成的ast的底層中有一個accept方法,專門用來接收visitor(插件)訪問者對象,然后在visitor中定義各種節點類型的操作-visite,每個visite都可以接受一個path參數(節點信息,節點和位置信息的對象,其包含很多有用的方法),在visit中處理path,從而實現轉換的作用。
const result = babel.transform(code, { plugins: [{ visitor }] }) console.log(result.code);
至于visitor后續會詳細介紹。
整個babel的結構圖,我大概花了一張圖表示出來:
而babel和webpack的協同開發,我也大概花了一張圖表示他們之間的關系,但里面的原理,我后續會再去研究,研究好再分享一下:
以上是我對babel的初步理解,如果有不正確的地方,歡迎指出。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100357.html
摘要:本質就是一個編譯器,通過將源代碼解析成抽象語法樹將源代碼的結果一系列轉換生成目標代碼的將目標代碼的轉換成代碼。項目構建三開發環境本地服務器搭建源碼下載地址參考資料入門阮一峰中文文檔中文網 注:以下教程均在 windows 環境實現,使用其他操作系統的同學實踐過程可能會有些出入。 ??在上一章 webpack 項目構建:(一)基本架構搭建 我們搭建了一個最基本的 webpack 項目,現...
摘要:的轉譯過程分為三個階段。標準為例,提供了如下的一些的只轉譯該年份批準的標準,而則代指最新的標準,包括和。未完待續,繼續學習繼續補充哦參考文獻深入理解原理及其使用 Babel Babel的轉譯過程分為三個階段: parsing, transforming, generating。babel只是轉譯新標準引入的語法,比如ES6的箭頭函數轉譯成ES5的函數;而新標準引入的原生對象,部分原生對...
摘要:雖然夠好用,奈何沒有瀏覽器對其可以完全支持,本文書寫時間,開發版號稱已經支持的特性。開始安裝本系列假定讀者都有使用經驗,如果還沒有,趕緊去這里了解并安裝吧。到此,我們的已經準備就緒。 通過前面章節的講解,大家對ES2015的一些新語法有了初步的理解,之前我們的測試代碼都可以直接放入 Chrome Console 中直接運行,為了更好的學習后面的面向對象和模塊開發,我先用一章介紹一下 B...
摘要:年,很多人已經開始接觸環境,并且早已經用在了生產當中。我們發現,關鍵字會被編譯成構造函數,于是我們便可以通過來實現實例的生成。下一篇文章我會繼續介紹如何處理子類的并會通過一段函數橋梁,使得環境下也能夠繼承定義的。 2017年,很多人已經開始接觸ES6環境,并且早已經用在了生產當中。我們知道ES6在大部分瀏覽器還是跑不通的,因此我們使用了偉大的Babel來進行編譯。很多人可能沒有關心過,...
摘要:開發完了,并部署到服務器后,就遇到了一個非常明顯的問題。所以可以利用按需加載來進一步縮小文件的體積。另外圖片還可以去下面這個網上壓縮一下經過上述的幾步,首頁的加載速度已經比較快了,項目經理也比較滿意。初步結束了首頁加載慢的問題的研究。 本次開發的項目中使用了vue2.5.2和自帶的vue-cli生成了前端的基本架構。隨后在項目開發當中,添加了自己寫的UI組件,和復雜的業務邏輯。整個項目...
閱讀 3427·2021-11-12 10:36
閱讀 2734·2021-11-11 16:55
閱讀 2957·2021-09-27 13:36
閱讀 1615·2021-08-05 10:01
閱讀 3555·2019-08-30 15:55
閱讀 765·2019-08-30 13:01
閱讀 1905·2019-08-29 17:16
閱讀 2376·2019-08-29 16:40