<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] >[success] # babel -- 初步了解 ~~~ 1.Babel 其實就是一個 JavaScript 的'編譯器',但開箱即用的babel什么也不做。它只會把源文件復 制到構建目錄去,整個過程也分為三個階段解析(Parsing),轉化(Transformation)以及 代碼生成(Code Generation) 1.1.'解析'將源代碼轉換為一個更抽象的形式。 1.2.'轉換'接受解析產生的抽象形式并且操縱這些抽象形式做任何編譯器想讓它們做的事。 1.3.'代碼生成'基于轉換后的代碼表現形式(code representation)生成目標代碼。 2.Babel 模塊 source to source 的轉換對應三個階段依次 2.1.parse:通過 parser 把源碼轉成抽象語法樹(AST)即詞法語法解析生成ast一條龍 2.2.transform:遍歷 AST,調用各種 transform 插件對 AST 進行增刪改 2.3.generate:把轉換后的 AST 打印成目標代碼,并生成 sourcemap ~~~ * 依次對應babel 源碼包位置 1. 解析 ——[@babel/parser](https://github.com/babel/babel/tree/master/packages/babel-parser)(包含 [tokenizer](https://github.com/babel/babel/tree/master/packages/babel-parser/src/tokenizer)、[parser](https://github.com/babel/babel/tree/master/packages/babel-parser/src/parser),即詞法語法解析一體),根據 es2015, es2016… 標準,生成 AST 2. 轉換 ——[@babel/traverse](https://github.com/babel/babel/tree/master/packages/babel-traverse)\+ plugins (visitor) 3. 代碼生成 ——[@babel/generator](https://github.com/babel/babel/tree/master/packages/babel-generator) * [圖片來自](https://mp.weixin.qq.com/s/LlQRx5SPmFgnTDO8VunGnw) ![](https://img.kancloud.cn/58/42/58420cd3b9ac250899c61201543954e5_668x249.png) >[info] ## 安裝使用babel ~~~ 1.從 babel7 開始,所有的官方插件和主要模塊,都放在了 @babel 的命名空間下。 從而可以避免在 npm 倉庫中 babel 相關名稱被搶注的問題,并且采用了Babel Monorepo 風格的倉庫 2.在使用'babel' 時候我們一般需要安裝'@babel/core' '@babel/cli' '@babel/preset-env' 2.1.'@babel/core' Babel 實現轉換的核心,他是依賴能力更底層的 @babel/parser、 @babel/code-frame、@babel/generator、@babel/traverse、@babel/types等 2.1.1.'@babel/parser' 對源碼進行 parse,可以通過 plugins、sourceType 等來指定 parse 語法, 例如指定是'ts',"jsx"語法,詞法語法ast都在這個階段 2.1.2.'@babel/code-frame'可以創建友好的報錯信息 2.1.3.'@babel/traverse'通過 visitor 函數對遍歷到的 ast 進行處理,分為 enter 和 exit 兩個階 段,具體操作 AST 使用 path 的 api,還可以通過 state 來在遍歷過程中傳遞一些數據,簡單 的說操作Ast 語法樹 改變語法樹結構自然達到了轉換效果 2.1.4.'@babel/generator' 打印 AST 成目標代碼字符串,支持 comments、minified、 sourceMaps 等選項。將語法樹轉換成對應新的編碼 2.1.5.'@babel/types' 用于創建、判斷 AST 節點,提供了 xxx、isXxx、assertXxx 的 api 2.2.'@babel/cli'--是 Babel 提供的命令行,它可以在終端中通過命令行方式運行,編譯文件 或目錄 2.3.'@babel/preset-env' -- Babel 只是一個'編譯器' 你需要告訴他轉換規則,需要在transformer 利用我們配置好的 plugins/presets把 Parser生成的 AST轉變為新的 AST,即'@babel/preset-env' 就是一套轉換規則集合 ~~~ >[danger] ##### 使用transform -- api ~~~ 1.'babel/core'中的'transform'方法轉換傳入的代碼,轉換完成后,執行callback,返回參數有 轉換的代碼,source map,和 AST,注意了 這里的'transform' 和之前提到的'transform'階段不同 'transform' api 包含了階段解析(Parsing),轉化(Transformation)以及 代碼生成(Code Generation)完整的三個階段 ~~~ * 使用 ~~~ const core = require("@babel/core"); const code = "const a = 1;"; core.transform(code, {}, (err, result) => { console.log(result, err); // => { code, map, ast } // 輸出轉換結果沒有變化 符合babel 只是一個編譯器并不會做過多操作 console.log(result.code); // const a = 1; }); ~~~ * 配置轉換規則 ~~~ const core = require("@babel/core"); const env = require("@babel/preset-env"); const code = "const a = 1;"; // 配置轉換規則后 es6 =》 es5 core.transform(code, { presets: [env] }, (err, result) => { console.log(result, err); // => { code, map, ast } console.log(result.code); // '"use strict";\n\nvar a = 1;' }); ~~~ * 用更細致的api實現 ~~~ 1.'transform' api 其實是調用了"@babel/parser","@babel/generator","@babel/traverse",幫我們 完成了轉換,如果不直接使用'transform' api 分步來做實際效果 2.針對之前'解析(Parsing)'、'轉換(Transformation)'、'生成(Code Generation)' 三部曲依次對應 上面的包 2.1.'解析(Parsing)',@babel/parser,功能是把源碼轉成 AST 2.2.'轉換(Transformation)','@babel/traverse',可以遍歷 AST,并調用 visitor 函數修改 AST, '@babel/types' 包提供了對具體的 AST 節點的修改能力(AST的判斷、創建、修改等) 2.3. '@babel/generator' 對新的 AST 進行聚合并生成 JavaScript 代碼,同時生成 sourcemap 關于其他的包' @babel/code-frame',中途遇到錯誤想打印代碼位置 ~~~ ~~~ const parser = require("@babel/parser"); const t = require("@babel/types"); const generate = require("@babel/generator").default; const traverse = require("@babel/traverse").default; const code = "const a = 1;"; // 功能是把源碼轉成 AST const ast = parser.parse(code); // 按照規則生成新的 AST traverse(ast, { VariableDeclaration(node, parent) { // console.log(node, parent) console.log(node.container[0].kind); node.container[0].kind = "var"; // const { node } = path // // // 獲取函數名稱等 // // path.replaceWith() // 替換為新的節點 // // path.remove() // 刪除當前節點 // // path.skip() // 跳過子節點 // const newNode = t.variableDeclaration('const', [t.variableDeclarator('var')]) // path.replaceWith(newNode) // const copyNode = t.cloneNode(node) // 復制當前節點 // traverse(copyNode, {}, {}, path) // 對子樹進行遍歷和替換,不影響當前的path }, }); // 編譯新的ast const output = generate(ast); console.log(output); // { code: 'var a = 1;', map: null, rawMappings: undefined } ~~~ >[info] ## 配置 ~~~ 1.在使用'babel/core'中的'transform'api 時候如果沒有去配置規則,字符串在內部就是'一日游' 即code=> 轉換'ast' =>沒規則保持轉換'ast'=>沒改變的'ast'再次變回之前的'code' 2.整個配置中比較常用的兩個字段 "presets"預設,"plugins" 插件,Babel 的'預設(preset)' 可以被看作是一組 Babel 'plugins'插件,更通俗的理解'plugins' 是一條條轉換的規則,例如 來說轉換成es6,'箭頭函數'、'變量聲明'等等這些都是規則,但是如果依次轉換配置需要將 'es6'的配置都一一寫入是一個很麻煩事,"presets"預設 將這中有統一規律的"plugins" 插件 裝進一個預設中 { "presets": [], // 預設 "plugins": [] // 插件 } 3.Babel也是可以配置和其他工具具有類似的配置:ESLint(`.eslintrc`),Prettier(`.prettierrc`)。 'babel'配置文件的優先級 'babel.config.json < .babelrc < programmatic options from @babel/cli' ~~~ [更多配置](https://babel.docschina.org/docs/en/options/) >[danger] ##### plugins -- 插件 ~~~ 1.插件主要分為三類: 1.1.'syntax plugin':只是在parse階段使用,可以讓 parser 能夠正確的解析對應的語法成 AST 1.2.'transform plugin':是對 AST 的轉換,針對es20xx 中的語言特性、typescript、jsx 等的 轉換都是在這部分實現的 1.3.'proposal plugin':未加入語言標準的特性的 AST 轉換插件 ~~~ >[danger] ##### presets -- 預設 ~~~ 1.預設其實就是對于插件的一層封裝,是一組插件的集合 2.不同類型的插件集合又產生了如下幾種預設: 2.1.專門根據es標準處理語言特性的預設 -- babel-preset-es20xx 2.2.對其react、ts兼容的預設 -- preset-react preset-typescript 2.3目前最常使用的便是 @babel/preset-env這個預設 ~~~ >[danger] ##### 補充 [presets 和plugins 補充](https://zhuanlan.zhihu.com/p/164769597) >[danger] ##### 配置文件規則 ~~~ 1.根據官方文檔的說法,目前有兩類配置文件:項目范圍配置 和 文件相對配置。 1.1.項目范圍配置(全局配置) -- babel.config.json 1.2.文件相對配置(局部配置) -- .babelrc.json、package.json 2.區別:第一種配置作用整個項目,如果 babel 決定應用這個配置文件,則一定會應用到所 有文件的轉換。而第二種配置文件只能應用到'當前目錄'下的文件中。babel 在決定一個 js 文 件應用哪些配置文件時,會執行如下策略: 如果這個 js 文件在當前項目內,則會遞歸向上搜索 最近的一個 .babelrc 文件(直到遇到package.json),將其與全局配置合并。 ~~~ >[danger] ##### 總結 ~~~ 1.可能隨著未來前端的發展出現越來越多的發展可能出現,如果一味的讓某種工具必須直接具備 所有功能必然會出現臃腫代碼 2.在工程化的角度上,需要秉承以下理念去設計一個工具鏈來解決上面問題 2.1.'可插拔(Pluggable)',比如 Babel 需要有一套靈活的插件機制,召集第三方開發者力量, 同時還需要方便接入各種工具; 2.2.'可調式(Debuggable)',比如 Babel 在編譯過程中,要提供一套 Source Map,來幫助使用者在編譯結 果和編譯前源碼之間建立映射關系,方便調試; 2.3.'基于協定(Compact)',實現靈活的配置方式,開發者在'盡量還原規范'和'更小的編譯產出體積'之間, 找到平衡。 3.設想一個思路利用'Babel' js 編譯器的功能可以將代碼轉換為ast 語法樹,在配合各種可插拔的組件去對 其介入進行轉換,隨著未來新的場景的更新只需要的的插件出現配合'babel' 語法解析完成想要的可能 ~~~ ![](https://img.kancloud.cn/a8/7e/a87e4a695a603e57190f6ab15b670660_652x523.png) >[info] ## 參考 [07 | 梳理混亂的 Babel,不再被編譯報錯困擾](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=584&sid=20-h5Url-0#/detail/pc?id=5912) [babel-從入門到上手 ](https://mp.weixin.qq.com/s/LlQRx5SPmFgnTDO8VunGnw)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看