日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

深入理解 Babel - 微內核架構與 ECMAScript 標準化

來源: 責編: 時間:2024-09-10 09:51:09 127觀看
導讀隨著瀏覽器版本的持續更新,瀏覽器對JavaScript的支持越來越強大,Babel的重要性顯得較低了。但Babel的設計思路、背后依賴的ECMAScript標準化思想仍然值得借鑒。本文涉及的Babel版本主要是V7.16及以下,截至發文時,Babel最

隨著瀏覽器版本的持續更新,瀏覽器對JavaScript的支持越來越強大,Babel的重要性顯得較低了。但Babel的設計思路、背后依賴的ECMAScript標準化思想仍然值得借鑒。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

本文涉及的Babel版本主要是V7.16及以下,截至發文時,Babel最新發布的版本是V7.25.6,未出現大版本更新,近2年也進入了穩定迭代期,本文的分析思路基本適用目前的Babel設計。6CT28資訊網——每日最新資訊28at.com

一、Babel簡介

6CT28資訊網——每日最新資訊28at.com

Babel是什么

6CT28資訊網——每日最新資訊28at.com

Babel是JavaScript轉譯器,通過Babel,開發者可以自由使用下一代ECMAScript 語法。高版本ECMAScript語法將被轉譯為低版本語法,以便順利運行在各類環境,如低版本瀏覽器、低版本 Node.js 等。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Babel 是轉譯器,不是編譯器。下面是轉譯和編譯的區別:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

編譯,一般指將一種語言轉換為另一種語法和抽象程度等都不同的語言,常見的比如 gcc 編譯器。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

轉譯,一般指將一種語言轉換為不同版本或者抽象程度相同的語言,比如 Babel 可以把 ECMAScript 6 語法轉譯為 ECMAScript 5語法。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

利用 Babel,開發者可以使用 ECMAScript 的各種新特性進行開發,同時花極少的精力關注瀏覽器或其他JS運行環境對新特性的支持。甚至,開發者可以根據自身需要,創造屬于自己的 JavaScript 語法。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Babel在轉譯的時候,會對源碼進行以下處理: 語法轉譯(Syntax)和添加API Polyfill。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

  • 語法(Syntax)部分Babel 支持識別高版本語法,并通過插件將源碼從高版本語法轉譯為低版本語法,如:

6CT28資訊網——每日最新資訊28at.com

箭頭函數 () => {} 轉為普通函數 function() {}。6CT28資訊網——每日最新資訊28at.com

const / let 轉譯為var6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • API Polyfill有些運行時相關的 API,語法轉譯無法解決它們對低版本瀏覽器等環境的兼容性問題,因此 Babel 通過與 core-js 等工具的配合,實現 API 部分對目標環境(通常是低版本瀏覽器等)的兼容。例如[1, 2, 3].include、Promise等 API,Babel 在處理時,如果目標環節可能不支持原生的 include / Promise 的話,Babel 會在轉譯結果中嵌入 include / Promise 的自定義實現。有多種方式可以使用 Babel,如: 命令行(babel-cli、babel-node)、瀏覽器(babel-standalone)、API 調用(babel-core)、webpack loader(babel-loader)等。

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

轉譯過程

6CT28資訊網——每日最新資訊28at.com

和多數轉譯器相同,Babel 運行的生命周期主要是 3 個階段: 解析、轉換、代碼生成。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

這個過程涉及抽象語法樹:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

抽象語法樹(Abstract Syntax Tree,AST),或簡稱語法樹(Syntax tree),是源代碼語法結構的一種抽象表示。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

AST 是樹形對象,以結構化的形式表示編程語言的語法結構,樹上的每個節點都表示源代碼中的一種結構。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

源碼字符串需要經轉譯器生成 AST,轉譯器有很多種,不同轉譯器,生成的AST對象格式細節可能有差異,但共同點為: 都是樹形對象、該樹形對象描述了節點特征、各節點之間的關系(兄弟、父子等)。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

以下是 Babel 生命周期的三個過程:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 解析(Parsing): Code1 ==> 抽象語法樹1解析過程包括 2 個環節: 詞法解析、語法解析,最終生成抽象語法樹。詞法解析階段,代碼字符串被解析為 token 令牌數組,數組項是一個對象,包括: 代碼字符碎片的值、位置、類型等信息。token 數組是平鋪式的數組,沒有嵌套的結構信息,它是為語法解析階段做準備的。語法解析階段,token 令牌數組被解析為結構化的抽放語法樹對象(AST)。babel-parser 完成該階段的主要功能。

圖片圖片6CT28資訊網——每日最新資訊28at.com

  • 轉換(Transformation): AST1 ==> AST2Babel 生成 AST 后,會對 AST 進行遍歷,遍歷過程中,各類插件對原 AST 對象進行增刪改查等操作,AST 結構被修改。

圖片圖片6CT28資訊網——每日最新資訊28at.com

  • 代碼生成(Generation): AST2 ==> Code2Babel 將修改后的 AST 對象轉目標代碼字符串。babel-generator 完成該階段的主要功能。

圖片圖片6CT28資訊網——每日最新資訊28at.com

二、Babel微內核架構

6CT28資訊網——每日最新資訊28at.com

微內核架構

6CT28資訊網——每日最新資訊28at.com

Babel 采用微內核架構,其內核保留核心功能,其余功能利用外部工具和插件機制實現,也體現了"開放-封閉"的設計原則。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

除了微內核設計架構,Babel 的模塊設計也可以做如下分類:6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

轉譯模塊

6CT28資訊網——每日最新資訊28at.com

轉譯模塊位于 Babel 微內核架構的"微內核"部分,該部分主要負責代碼轉譯,也就是上面提到的"解析-轉換-代碼生成"過程。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

該模塊主要包括: babel-parser、babel-traverse、babel-generator。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-parser負責將代碼字符串轉為 AST 對象。有 2 點值得一提:

6CT28資訊網——每日最新資訊28at.com

babel-parser 本身并不會對 AST 做轉換操作,只是負責解析出 AST。AST 轉換部分交由各類 plugins 和 presets 處理。6CT28資訊網——每日最新資訊28at.com

babel-parser 內置了對 ESNext/TypeScript/JSX/Flow 最新版本語法的支持,但很多默認是不開啟的,目前沒有開放插件機制擴展新語法。6CT28資訊網——每日最新資訊28at.com

  • babel-traverse在轉譯過程中,babel-traverse 負責遍歷 AST 節點,并根據配置的 plugins/presets,在遍歷過程中,對各個 AST 節點進行增刪改查的操作。AST 是一個樹形對象,遍歷 AST 對象的過程也是一個深度優先遍歷的過程。

6CT28資訊網——每日最新資訊28at.com

  • babel-generator負責將 AST 節點,轉為代碼字符串,同時也可以生成 source-map。

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

插件模塊

6CT28資訊網——每日最新資訊28at.com

插件模塊包括 plugins、presets。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • plugins豐富的插件,幫助 Babel 成為一個非常成功的轉譯工具。對 AST 的遍歷、轉換是 Babel 轉譯的核心功能,但 Babel 本身并不參與該過程,將這些功能作為插件引入到運行時。具體來說,babel-core 作為核心工具,不提供對 AST 的修改邏輯,通過調用各類插件,實現對 AST 的修改。Babel的插件分為語法插件和轉換插件。

6CT28資訊網——每日最新資訊28at.com

語法插件6CT28資訊網——每日最新資訊28at.com

值得注意的是,babel-parser 負責將 JavaScript 代碼解析出抽象語法樹(AST),它支持全面識別 ESNext/TypeScript/JSX/Flow 等語法,目前由 Babel 團隊開發維護,不支持插件化。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Babel 插件生態中的語法插件,其功能就是作為"開關",配置是否開啟 babel-parser 的某些語法轉譯功能。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

語法插件在 Babel 源碼中,以 babel-plugin-syntax 開頭。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

舉個例子:6CT28資訊網——每日最新資訊28at.com

babel-plugin-syntax-decorators負責開啟 babel-parser 對裝飾器的語法支持。6CT28資訊網——每日最新資訊28at.com

babel-plugin-syntax-dynamic-import負責開啟 babel-parser 對 import 語句的語法支持。6CT28資訊網——每日最新資訊28at.com

babel-plugin-syntax-jsx負責開啟 babel-parser 對 jsx 語法的支持。6CT28資訊網——每日最新資訊28at.com

  • 轉換插件轉換插件就是社區里常說的 Babel 插件,負責轉換 AST 節點。在介紹babel-traverse時提到,它負責遍歷AST對象,每個AST節點會被訪問到,等待轉換,轉換的部分,由"轉換插件"負責。轉換插件會提供一個叫做"Visitor"的對象,該對象的 Key 為節點名稱,Value 部分提供進入該節點時、離開該節點時的回調函數,在回調函數里,可以對該節點進行一系列操作。"Visitor" 又稱為 "訪問者"。
// plugin 提供 visitor,在 visitor 中對 AST 節點操作const visitor = {    Program: {        enter() {},        exit() {},    },    CallExpression: {        enter() {},        exit() {},    },    NumberLiteral: {        enter() {},        exit() {},    }};traverse(ast, visitor);

轉換插件在Babel源碼中,以 babel-plugin-transform 開頭。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

舉個例子:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

babel-plugin-transform-strict-mode6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

該插件攔截 Program 節點,也就是整個程序的根節點,添加 "use strict"指令。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

visitor 節點值為函數時,是 enter 回調的快捷方式。6CT28資訊網——每日最新資訊28at.com

{    name: "transform-strict-mode",    visitor: {      Program(path) {        const { node } = path;        for (const directive of node.directives) {          if (directive.value.value === "use strict") return;        }        path.unshiftContainer(          "directives",          t.directive(t.directiveLiteral("use strict")),        );      },    },  };}
  • babel-plugin-transform-object-assign

6CT28資訊網——每日最新資訊28at.com

該插件負責攔截函數調用表達式節點 CallExpression,將 Object.assign 轉為 extends 寫法。6CT28資訊網——每日最新資訊28at.com

{    name: "transform-object-assign",    visitor: {      CallExpression(path, file) {        if (path.get("callee").matchesPattern("Object.assign")) {          path.node.callee = file.addHelper("extends");        }      },    },}
  • PresetsBabel 插件的功能是細粒度的,大部分插件承擔了單一功能。而在實際開發過程中,往往需要支持對各類語法的支持。此時,有兩種做法:

6CT28資訊網——每日最新資訊28at.com

需要支持哪些特性,就分別引入支持該特性的插件6CT28資訊網——每日最新資訊28at.com

直接引入一個插件集合,涵蓋所需的各類插件功能6CT28資訊網——每日最新資訊28at.com

很顯然,第一種做法是相對麻煩的。針對第二種做法,Babel提供了插件集 preset。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

preset 在 Babel 源碼中,以 babel-preset 開頭。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

例如,Babel 已經提供了幾種常用的 preset 供開發者使用:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

babel-preset-env6CT28資訊網——每日最新資訊28at.com

babel-preset-react6CT28資訊網——每日最新資訊28at.com

babel-preset-flow6CT28資訊網——每日最新資訊28at.com

babel-preset-typescript6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 插件運行順序Babel 配置項中,plugins 和 presets 均以數組的形式配置,執行時有先后順序。

6CT28資訊網——每日最新資訊28at.com

plugins 在 presets之前運行6CT28資訊網——每日最新資訊28at.com

plugins 按照數組正序執行6CT28資訊網——每日最新資訊28at.com

presets 按照數組倒序執行6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

工具模塊

6CT28資訊網——每日最新資訊28at.com

工具模塊提供 Babel 相關模塊所需的各類工具,以下一一簡要介紹:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-corebabel-core 對外提供了 Babel 多項功能的 API,如轉譯文件、轉譯代碼、創建/獲取配置等,在 Babel 官方文檔介紹的比較詳細,不再贅述。值得注意的是,轉譯類的 API 均提供了同步和異步版本,如 transformSync/transfomAsync、parseSync/parseAsync。

6CT28資訊網——每日最新資訊28at.com

  • babel-cliBabel 的命令行工具,可以直接轉譯文件夾/文件,它也提供了很多配置項做其他工作,官方文檔介紹的比較詳細,感興趣的同學可以去 Babel 官網查看詳細配置。

6CT28資訊網——每日最新資訊28at.com

  • babel-standaloneBabel 對外服務的很多包是基于 node 環境下使用的,babel-standalone 提供了瀏覽器下轉譯的方案。babel-standalone 內置了所有 Babel 插件,所以體積還是比較大的,而且在瀏覽器端轉譯需要時間,比較適合開發、學習使用,不適合在生產環境使用。舉個例子:
<!DOCTYPE html><html>  <head>    <meta charset="utf-8" />    <title>test babel-standalone</title>    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>    <script type="text/babel">      const arr = [1, 2, 3];      console.log(...arr);</script>  </head>  <body></body></html>

在瀏覽器運行該 html,可以看到,頁面結構變成了:6CT28資訊網——每日最新資訊28at.com

<!DOCTYPE html><html>  <head>    <meta charset="utf-8" />    <title>test babel-standalone</title>    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>    <script type="text/babel">      const arr = [1, 2, 3];      console.log(...arr);</script>    <script>      "use strict";      var _console;      var arr = [1, 2, 3];      (_console = console).log.apply(_console, arr); //# sourceMappingURL=data:application/json;charset=utf-8;base64...</script>  </head>  <body></body></html>
  • babel-node

6CT28資訊網——每日最新資訊28at.com

提供在命令行執行高級語法的環境。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

例如:6CT28資訊網——每日最新資訊28at.com

// index.js 里可以使用高級語法     babel-node -e index.js

index.js 文件以及被其引入的其他文件均可以使用高級語法了。和 babel-cli 不同的是,babel-cli 只負責轉換,不在 node 運行時執行;babel-node 會在 node 運行時執行轉換,不適合生產環境使用。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-register

6CT28資訊網——每日最新資訊28at.com

在源文件中,引入babel-register,如 index.js:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

index.js6CT28資訊網——每日最新資訊28at.com

require('babel-register');     require('./run');

run.js6CT28資訊網——每日最新資訊28at.com

import fs from 'fs';     console.log(fs);

執行 node index 時,run.js 就不需要被轉碼了。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

babel-register 通過攔截 node require 方法,為 node 運行時引入了 Babel 的轉譯能力。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-loader

6CT28資訊網——每日最新資訊28at.com

babel-loader 是利用 babel-core 的 API 封裝的 webpack loader,用于 webpack 構建過程。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-types

6CT28資訊網——每日最新資訊28at.com

babel-types 是一個非常強大的工具集合,它集成了節點校驗、增刪改查等功能,是 Babel 核心模塊開發、插件開發等場景下不可或缺的工具。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

例如:6CT28資訊網——每日最新資訊28at.com

const t = require('@babel/types');const binaryExpression = t.binaryExpression('+', t.numericLiteral(1), t.numericLiteral(2));
  • babel-template

6CT28資訊網——每日最新資訊28at.com

模板引擎,負責將代碼字符串轉為 AST 節點對象。6CT28資訊網——每日最新資訊28at.com

import { smart as template } from '@babel/template';    import generate from '@babel/generator';    import * as t from '@babel/types';    const buildRequire = template(      var %%importName%% = require(%%source%%);    );    const ast = buildRequire({        importName: t.identifier('myModule'),        source: t.stringLiteral("my-module"),    });    const code = generate(ast).code    console.log(code)

        運行結果:6CT28資訊網——每日最新資訊28at.com

var myModule = require("my-module");
  • babel-code-frame

6CT28資訊網——每日最新資訊28at.com

負責打印出錯的代碼位置,例如:6CT28資訊網——每日最新資訊28at.com

const { codeFrameColumns } = require('@babel/code-frame');const testCode = `class Run {    constructor() {}}`;const location = {    start: {        line: 2,        column: 2,    }};const result = codeFrameColumns(testCode, location);console.log(result);
1 | class Run {> 2 |     constructor() {}    |  ^  3 | }  4 |
  • babel-highlight

6CT28資訊網——每日最新資訊28at.com

向控制臺輸出有顏色的代碼片段。該工具可以識別 JavaScript 中的操作符號、標識符、保留字等類型的詞法單元,并在終端環境下顯示不同的顏色。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

運行時相關模塊

6CT28資訊網——每日最新資訊28at.com

Babel 配合其插件可以對靜態代碼進行轉譯,但有一些遺漏點:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 對于運行時涉及的一些高版本 API,并沒有提供兼容目標環境的 Polyfill。
  • 轉譯產物代碼可能有些臃腫。

6CT28資訊網——每日最新資訊28at.com

為此,運行時模塊(runtime)關注的是轉譯產物的運行時環境,對運行時提供 API polyfill、代碼優化等,該模塊涉及幾個子包:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-preset-env
  • babel-plugin-transform-runtime
  • babel-runtime
  • babel-runtime-corejs2/3
  • core-js

6CT28資訊網——每日最新資訊28at.com

接下來以案例解釋 runtime 模塊的作用。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

源碼文件 index.js 的內容:6CT28資訊網——每日最新資訊28at.com

const a = 1; // const 為語法部分class Base {} // class 為語法部分new Promise() // Promise 為 API 部分

這段源碼包含了語法和 API 部分:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • const、class 為語法部分
  • Promise 為 API 部分

6CT28資訊網——每日最新資訊28at.com

如果希望這段源碼轉為 ES5 版本,使構建產物可以運行在不支持 ES6 和 Promise 的環境里,該怎么做呢?6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

用 babel 命令行執行轉譯,其中源文件為 index.js,轉譯產物文件為 index-compiled.js。6CT28資訊網——每日最新資訊28at.com

npx babel index.js --out-file index-compiled.js

需要配置.babelrc 幫助 Babel 完成語法和 API 部分的轉譯:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

.babelrc:6CT28資訊網——每日最新資訊28at.com

{    "presets": [        [             "@babel/preset-env"        ]    ],    "plugins": [        [            "@babel/plugin-transform-runtime",            {                "corejs": 3            }        ]    ]}

簡要解釋下該配置的原理:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-preset-env 可以完成語法部分轉譯,即 const 轉譯為var但構建產物中,有些輔助代碼如 _classCallCheck 是以硬編碼的形式直接寫入轉譯產物的:
"use strict";    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }    var a = 1;    var Base = function Base() {        _classCallCheck(this, Base);    };    new Promise();

這樣的后果就是構建產物比較臃腫。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • babel-plugin-transform-runtime 可以將上述 _classCallCheck 置于通用包中,以引用的形式寫入轉譯產物:
"use strict";    var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");    var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));    var a = 1;    var Base = function Base() {        (0, _classCallCheck2["default"])(this, Base);    };    new Promise();
  • babel-plugin-transform-runtime 的配置參數 corejs 用于轉譯 API 部分,如 Promsie
"use strict";    var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");    var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));    var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));    var a = 1;    var Base = function Base() {        (0, _classCallCheck2["default"])(this, Base);    };    new _promise"default";

Babel 轉譯過程的運行時優化是一個繁瑣的過程,為此將單獨用一章講解運行時優化,感興趣的同學可以直接閱讀 "Babel Runtime" 章節詳細了解。6CT28資訊網——每日最新資訊28at.com

三、標準化

Babel 生態涉及的一些標準化組織。無論是 JavaScript、HTML、DOM、URL 等領域,均需要統一的標準,才能在不同的運行環境下有統一的表現。Babel 轉譯也需要遵循這些標準,包括 ECMAScript、web標準等。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ECMAScript

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

JavaScript誕生

1995 年,JavaScript 的第一個版本發布。用時間線的方式描述 JavaScript 的誕生過程會更清晰: 6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ECMAScript發布

1996 年,微軟模仿 JavaScript 實現了 JScript 并內置在 IE3.0,隨后,Netscape 公司著手推動 JavaScript 標準化。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

這里涉及幾個組織:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • Ecma International

6CT28資訊網——每日最新資訊28at.com

Ecma International 是一家國際性會員制度的信息和電信標準組織。1994年之前,名為歐洲計算機制造商協會(European Computer Manufacturers Association)。因為計算機的國際化,組織的標準牽涉到很多其他國家,因此組織決定改名表明其國際性。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Ecma International 的任務包括與有關組織合作開發通信技術和消費電子標準、鼓勵準確的標準落實、和標準文件與相關技術報告的出版。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Ecma International 負責多個國際標準的制定:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • CD-ROM 格式(之后被國際標準化組織批準為ISO 9660)
  • C# 語言規范
  • C++/CLI 語言規范
  • 通用語言架構(CLI)
  • Eiffel 語言
  • 電子產品環境化設計要素
  • Universal 3D 標準
  • OOXML
  • Dart 語言規范
  • ECMAScript 語言規范(以 JavaScript 為基礎)ECMA-262其中就包括 JavaScript 標準語言規范 ECMAScript。cma International 擁有 ECMAScript 的商標。
  • ECMA TC39

6CT28資訊網——每日最新資訊28at.com

「TC39」全稱「Technical Committee 39」譯為「第 39 號技術委員會」,是 Ecma International 組織架構中的一部分。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

TC39 負責迭代和發展 ECMAScript,它的成員由各個主流瀏覽器廠商的代表組成,通常每年召開約 6 次會議來討論未決提案的進展情況,會議的每一項決議必須得到大部分人的贊同,并且沒有人強烈反對才可以通過。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

TC39 負責:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

維護和更新 ECMAScript 語言標準6CT28資訊網——每日最新資訊28at.com

識別、開發、維護 ECMAScript 的擴展功能庫6CT28資訊網——每日最新資訊28at.com

開發測試套件6CT28資訊網——每日最新資訊28at.com

為 ISO/IEC JTC 1 提供標準6CT28資訊網——每日最新資訊28at.com

評估和考慮新添加的標準6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • ISO

6CT28資訊網——每日最新資訊28at.com

國際標準化組織(英語: International Organization for Standardization,簡稱: ISO)成立于 1947 年 2 月 23 日,制定全世界工商業國際標準的國際標準建立機構。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ISO 的國際標準以數字表示,例如: "ISO 11180:1993" 的 "11180" 是標準號碼,而 "1993" 是出版年份。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ISO/IEC JTC 1 是國際標準化組織和國際電工委員會聯合技術委員會。其目的是開發、維護和促進信息技術以及信息和通信技術領域的標準。JTC 1 負責了許多關鍵的 IT 標準,從 MPEG 視頻格式到 C++ 編程語言。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

  • ECMAScript 發展過程中的關鍵節點

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ECMAScript 各版本

ECMAScript 經歷了多個版本,每個版本有自己的特點,簡單列舉如下: 6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ECMAScript 迭代過程

一個 ECMAScript 標準的制作過程,包含了 Stage 0 到 Stage 4 共 5 個階段,每個階段提交至下一階段都需要 TC39 審批通過。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

特性進入 Stage-4 后,才有可能被加入標準中,還需要 ECMA General Assembly 表決通過才能進入下一次的 ECMAScript 標準中。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

如何閱讀 ECMAScript

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

ECMAScript 文檔結構

ECMAScript 的規格,可以在 ECMA 國際標準組織的官方網站免費下載和在線閱讀。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

查看ECMAScript 不同版本的地址:https://ecma-international.org/publications-and-standards/standards/ecma-262/。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

截至 2023年底,已發布的版本如下:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • ECMA-262 5.1 edition, June 2011

(https://262.ecma-international.org/5.1/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 6th edition, June 2015

(https://262.ecma-international.org/6.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 7th edition, June 2016

(https://262.ecma-international.org/7.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 8th edition, June 2017

(https://262.ecma-international.org/8.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 9th edition, June 2018

(https://262.ecma-international.org/9.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 10th edition, June 2019

(https://262.ecma-international.org/10.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 11th edition, June 2020

(https://262.ecma-international.org/11.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 12th edition, June 2021

(https://262.ecma-international.org/12.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 13th edition, June 2022

(https://262.ecma-international.org/13.0/index.html)6CT28資訊網——每日最新資訊28at.com

  • ECMA-262, 14th edition, June 2023

(https://262.ecma-international.org/14.0/index.html)6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

每個版本有獨立的網址,格式為: https://262.ecma-international.org/{version}/,比如 ECMAScript 14.0 版本的網址為 https://262.ecma-international.org/14.0/。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

從章節數量上,ECMAScript 6.0、ECMAScript 7.0 有 26 章,之后的版本有 27-29 章,雖然章節數量不同,規格章節的分布是保持一定規律的,以 ECMAScript 11.0 版本為例:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • Introduction: 介紹部分

6CT28資訊網——每日最新資訊28at.com

該章節簡要描述了: JavaScript 和 ECMAScript 的發展歷史、不同 ECMAScript 規格的主要更新內容。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 第 1 章到第 3 章: 描述了規格文件本身,而非語言

第 1 章用一句話描述了該規格的描述范圍。6CT28資訊網——每日最新資訊28at.com

第 2 章描述了基于規格的"實現"的一致性要求:6CT28資訊網——每日最新資訊28at.com

"實現"必須支持規格中描述的所有類型、值、對象、屬性、函數以及程序的語法和語義6CT28資訊網——每日最新資訊28at.com

"實現"必須按照 Unicode 標準和 ISO/IEC 10646 的最新版本處理文本輸入6CT28資訊網——每日最新資訊28at.com

"實現"如果提供了應用程序編程接口(API),那么該 API 需要適應不同的人文語言和國家差異,且必須實現最新版本的 ECMA-402 所定義的與本規范相兼容的接口6CT28資訊網——每日最新資訊28at.com

"實現"可以支持該規格中沒有提及的類型、值、對象、屬性、函數、正則表達式語法以及其他編程寫法6CT28資訊網——每日最新資訊28at.com

"實現"不能實現該規格中禁止的寫法6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 第 3 章描述了該規格的一些參考資料:
  • ISO/IEC 10646
  • ECMA-402
  • EMCA-404 JSON 數據交換格式規范
  • 第 4 章: 對這門語言總體設計的描述。
  • 第 5 章到第 8 章: 語言宏觀層面的描述。
  • 第 6 章介紹數據類型。
  • 第 7 章介紹語言內部用到的抽象操作。
  • 第 8 章介紹代碼如何運行。
  • 第 9 章到第 27 章: 介紹具體的語法。

6CT28資訊網——每日最新資訊28at.com

一般而言,除非寫編譯器,開發者無需閱讀 ECMAScript 的規格,規格的內容非常多,如無必要也無需通讀。只是在遇到一些奇怪的問題時,閱讀官方規格,是最穩妥的辦法。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

通過閱讀規格解決一些問題6CT28資訊網——每日最新資訊28at.com

(以ECMAScript 11.0為例)6CT28資訊網——每日最新資訊28at.com

  • 識別關鍵詞和保留字,并高亮

6CT28資訊網——每日最新資訊28at.com

Babel 工具集中的 babel-highlight,可以實現在終端對代碼塊中的目標字符單元顯示不同的顏色。這里需要識別不同字符單元的類型,如關鍵字、保留字、標識符、數字、字符串等。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

標識符、數字、字符串都很好理解和識別,但哪些字符應該被識別為關鍵字、保留字,而不是標識符呢?6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

此時可以閱讀 ECMAScript 規格了,ECMAScript 11.0 規格的 11.6.2 節介紹了關鍵詞和保留字列表。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

關鍵詞(keywords)關鍵詞首先是標識符,同時有語義,包括 if、while、async、await...,個別關鍵詞是可以用作變量名的。6CT28資訊網——每日最新資訊28at.com

保留字(reserved word)保留字首先是標識符,但不能用作變量名。部分關鍵詞是保留字,但部分不是: if、while是保留字;await只有在 async方法和模塊中才是保留字;async不是保留字,它可以作為普通的變量名使用。6CT28資訊網——每日最新資訊28at.com

保留字列表6CT28資訊網——每日最新資訊28at.com

awaitbreakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimportininstanceofnewnullreturnsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

讀完上述規格,也就知道哪些字符單元是需要識別為保留字與關鍵詞,并高亮的了。6CT28資訊網——每日最新資訊28at.com

  • 識別全局對象,并高亮

6CT28資訊網——每日最新資訊28at.com

繼續使用 babel-highlight 實現代碼塊中的全局對象高亮,那么,我們需要知道哪些是規格中描述的全局變量。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

規格的 18 章介紹了全局對象,通過該章的描述,可以知道: 6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

全局屬性全局屬性有: globalThis、Infinity、NaN、undefined。6CT28資訊網——每日最新資訊28at.com

全局方法6CT28資訊網——每日最新資訊28at.com

全局方法有: eval(x)、isFinite、isNaN、parseFloat、parseInt、decodeURIComponent、encodeURIComponent 等。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 全局構造函數

全局的構造函數有: 6CT28資訊網——每日最新資訊28at.com

ArrayArrayBufferBigIntBigInt64ArrayBigUnit64ArrayBooleanDataViewDateErrorEvalErrorFloat32ArrayFloat64ArrayFunctionInt8ArrayInt16ArrayInt32ArrayMapNumberObjectPromiseProxyRangeErrorReferenceErrorRegExpSetSharedArrayBufferStringSymbolSyntaxErrorTypeErrorUint8ArrayUint8ClampedArrayUint16ArrayUint32ArrayURIErrorWeakMapWeakSet

其他的全局屬性Atomics、JSON、Math、Reflect。很顯然,當字符單元的名稱是上述名稱中的一員時,我們可以對其進行高亮處理了(若上下文中無重新定義的同名變量)。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • 自定義 Error

6CT28資訊網——每日最新資訊28at.com

babel-loader 自身維護了私有的 LoaderError 對象,該對象繼承自原生 Error 類,并且訂制了部分實例屬性。代碼如下: 6CT28資訊網——每日最新資訊28at.com

class LoaderError extends Error {    constructor(err) {        super();        const { name, message, codeFrame, hideStack } = format(err);        this.name = "BabelLoaderError";        this.message = ${name ? ${name}: ` : ""}${message}/n/n${codeFrame}/n`;        this.hideStack = hideStack;        Error.captureStackTrace(this, this.constructor);    }}

可以看到,babel-loader 自定義了錯誤實例的 name、message、hideStack 屬性,那么,問題是,原生的 Error 類有哪些屬性和方法,哪些是開發者可以自定義的呢?6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

規格的 19.5 章節,詳細介紹了 Error 的各類規范:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

Error 作為函數被調用時(Error(...)),表現和 new Error(...) 一致,均會創建并返回 Error 的新實例6CT28資訊網——每日最新資訊28at.com

Error 可以被繼承,比如通過 extends 的方式,子類必須提供 constructor 方法,且該方法內必須提供 super() 調用6CT28資訊網——每日最新資訊28at.com

Error 構造函數必須有 prototype 屬性6CT28資訊網——每日最新資訊28at.com

Error.prototype 屬性需有以下屬性:6CT28資訊網——每日最新資訊28at.com

Error.prototype.constructor: 指向構造函數6CT28資訊網——每日最新資訊28at.com

Error.prototype.message: 描述錯誤信息,默認是空字符串6CT28資訊網——每日最新資訊28at.com

Error.prototype.name: 描述錯誤名稱,默認值是 Error6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

從 LoaderError 的源碼可以看到,LoaderError 做了以下幾件事情:6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

  • LoaderError 繼承自 Error
  • 實例自定義了 name、message 屬性,明確 babel-loader 的信息
  • 實例自定義的 hideStack 屬性是非標準屬性,用于 babel-loader 內部

6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

web標準

6CT28資訊網——每日最新資訊28at.com

是在解決 API Polyfil 的時候,Babel 配合使用的 core-js 除了提供 ECMAScript 標準下的 JavaScript API 實現,也提供了 DOM/URL 等實現。而 DOM/URL 所屬的 web 標準,由 W3C/WHATWG 制定。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

經過多年發展,WHATWG 和 W3C 目前是合作關系,其中,WHATWG 維護 HTML 和 DOM 標準,W3C 使用 WHATWG 存儲庫中的 HTML 和 DOM 標準描述,W3C 在 HTML 部分的工作集中在 XHTML/XML 上。6CT28資訊網——每日最新資訊28at.com

圖片圖片6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

四、總結

本文介紹了 Babel 的概述/微內核架構/ECMAScript標準化方面的設計思想和部分實現原理。6CT28資訊網——每日最新資訊28at.com

6CT28資訊網——每日最新資訊28at.com

上述內容其實在很早之前就已經成型了,筆者也查看了Babel最近的迭代內容,發現并沒有太大的變化。至于代碼轉譯領域,目前是Babel還是其他工具哪個更有優勢,不在本文的討論范圍內。除了比較社區哪些工具更好而言,“Babel的設計思路、其與標準規范是怎么配合的”等也是很值得學習的地方,也是這篇文章的產生背景。6CT28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-112790-0.html深入理解 Babel - 微內核架構與 ECMAScript 標準化

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: DevOps流程最全詳解(7大流程步驟圖解)

下一篇: 記一次線程池使用不當觸發死鎖導致RocketMQ消費停滯

標簽:
  • 熱門焦點
  • 印度登月最關鍵一步!月船三號今晚進入環月軌道

    8月5日消息,據印度官方消息,月船三號將于北京時間今晚21時30分左右開始近月制動進入環月軌道。這是該探測器能夠成功的最關鍵步驟之一,如果成功將開始圍
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統提供非預期的輸入并監視異常結果來發現軟件漏洞的方法。可以用來發現應用程序、操作系統和網絡協議等中的漏洞或
  • 自律,給不了Keep自由!

    來源 | 互聯網品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時不好說,但大概率不能給Keep自由。近日,全球最大的在線健身平臺Keep正式登陸港交所,努力
  • 當家的盒馬,加速謀生

    來源 | 價值星球Planet作者 | 歸去來自己&ldquo;當家&rdquo;的盒馬,開始加速謀生了。據盒馬官微消息,盒馬計劃今年開放生鮮供應鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經與
  • 重估百度丨大模型,能撐起百度的“今天”嗎?

    自象限原創 作者|程心 羅輯2023年之前,對于自己的&ldquo;今天&rdquo;,百度也很迷茫。&ldquo;新業務到 2022 年底還是 0,希望 2023 年出來一個 1。&rdquo;這是2022年底,李彥宏
  • 小米汽車電池信息疑似曝光:容量101kWh,支持800V高壓快充

    7月14日消息,今日一名博主在社交媒體發布了一張疑似小米汽車電池信息的照片,顯示該電池包正是寧德時代麒麟電池,容量為101kWh,電壓為726.7V,可以預測小
  • 2納米決戰2025

    集微網報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
  • 三星折疊屏手機去年銷售近1000萬臺 今年目標定為1500萬

    7月29日消息,三星率先發力可折疊手機市場,在全球市場已經取得了非常亮眼的成績,接下來會進一步鞏固和擴大這一優勢。三星在推出Galaxy Z Flip5和Galax
  • iQOO Neo8系列今日官宣:首發天璣9200+ 全球安卓最強芯!

    在昨日舉行的的聯發科新一代旗艦芯片天璣9200+的發布會上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品將全球首發搭載這款當前性能最強大的移動平臺
Top 主站蜘蛛池模板: 通山县| 阿城市| 武胜县| 靖西县| 麻城市| 柳江县| 南召县| 万荣县| 托克托县| 新巴尔虎左旗| 普兰店市| 凭祥市| 广丰县| 遵义县| 云霄县| 平江县| 班玛县| 古交市| 微山县| 郴州市| 永泰县| 平江县| 当阳市| 江永县| 阜宁县| 九台市| 磴口县| 嘉义市| 关岭| 澎湖县| 盐源县| 梓潼县| 德化县| 射洪县| 游戏| 湘潭市| 绿春县| 邵武市| 遵义县| 五家渠市| 湘潭县|