Babel 路線圖
本文件概述了我們團隊成員今年想進行的一些改進。
這遠非我們將為 Babel 帶來的所有新功能或重要變更的完整清單,但如果您有興趣了解專案朝向的整體方向,這是一個很好的摘要。我們可能無法實際完成每個列出的項目,或可能將其中一些項目延後到明年。其中一些項目有明確的起點和終點,而另一些項目則需要更多研究或 RFC。
如果您的公司有興趣並想直接贊助任何特定項目,請 與我們聯繫!
Babel 2021 路線圖
Babel 8
我們已經討論 Babel 8 發行版超過一年了(我們最初在約一年前排定時程)!不過,我們現在比以往任何時候都更接近發行了!
大部分的剩餘工作都在 追蹤問題 中,但仍有一些阻礙
- 我們想要放棄對 Node.js 10 的支援,它將在 2021-04-30 停止維護。
- 我們希望將 Babel 發行為純 ESM 套件。我們現在正在將我們的來源轉換為與 Node.js 的 ESM 實作相容的過程中,並在這樣做的同時,我們正在檢視如何讓目前使用 Babel 將 ESM 編譯成 CJS 的人更容易。
- 我們正在嘗試將我們的 TypeScript AST 與
typescript-eslint
專案對齊。我們的 AST 幾乎 相同,但我們需要引入一些小的重大變更才能完全對齊。 - 我們的發行基礎架構尚不支援預發行版,或使用多個「主要」分支(一個用於 Babel 8,一個用於 Babel 7)。
- 我們尚未想出 Babel 7 維護的政策。
實作新的 TC39 提案
Babel 目前可以剖析所有第 3 階段提案,我們可以轉換所有提案,但頂層 await、匯入斷言和 JSON 模組除外(這些最適合由處理相依關係圖表的打包器處理)。
我們支援所有第 2 階段提案,但下列提案除外
- 裝飾器提案的新反覆運算(我們需要實作剖析和轉換);
- 模組區塊提案的轉換(我們在 Babel 7.13.0 中實作了剖析)。
我們將實作對裝飾器的支援,並調查我們是否可以實作模組區塊的轉換,以及如何實作。
雖然我們不支援許多第 1 階段提案,但管線運算子與 to do 表達式最近有更新。由於我們已經支援這些提案,而且社群對它們感到相當興奮,因此我們將更新我們的實作。
還有其他提案(例如模式比對)我們尚未實作,因為它們的擁護者預期會對語法和語意進行重大變更。不過,我們密切追蹤它們的開發,並會在它們稍微穩定後在 Babel 中實作它們。
將 @babel/preset-env
移入 @babel/core
一個最小的 Babel 轉換設定至少需要三個套件
@babel/core
@babel/preset-env
- 一個 Babel「執行器」(
@babel/cli
、babel-loader
、@rollup/plugin-babel
等)
將 @babel/preset-env
直接移入 @babel/core
有兩個很大的優點
- 在簡單的專案中,要設定 Babel 會更容易,你只需要在
babel.config.json
中啟用compileJS: true
選項即可(未來甚至可能成為預設值——由於@babel/eslint-parser
沒有編譯來源,因此無法設為預設值) - 它會確保外掛版本與
@babel/core
版本同步,避免因套件版本不匹配/不相容而造成的大部分錯誤 - 當我們轉移到 ESM 時,將很難在
transformSync
中同步解析和載入外掛。這可以防止它成為一個問題。
已經有一個 RFC 要將穩定 ECMAScript 功能的外掛移至 @babel/core
,這是朝此方向邁出的第一步。
根據我們目前的 @babel/preset-env
架構,我們需要特別處理官方外掛,才能根據 targets
自動啟用或停用它們。然而,這有兩個缺點
- 特定外掛的相容性資料與外掛實作完全分離(它甚至不是相依性,更像是內部隱含的對等相依性:外掛 -> @babel/core -> @babel/compat-data);
- 官方外掛會從
@babel/core
獲得特殊待遇,但我們要確保第三方外掛擁有與官方外掛相同的功能。
繼續開發 babel-polyfills
專案
我們已經決定在 Babel 8 中從 @babel/preset-env
中移除較舊的 core-js@2
支援。我們也想要停止宣傳特定的第三方 polyfill,這可能會讓我們的使用者誤以為它是 Babel 本身的一部分。
這可能會以兩種不同的方式發生
- 我們只從 Babel 8 中的
@babel/preset-env
中移除core-js@3
,鼓勵使用者轉移到babel-plugin-polyfill-corejs3
(這是@babel/preset-env
從版本 7.10.0 開始在內部使用的) - 我們可以在
@babel/preset-env
中保留core-js@3
支援,但當我們移動轉換外掛程式時,不要將其轉移到@babel/core
。
無論我們採取哪條路徑,我們都希望在使用者需要在他們的設定中更新 core-js
整合時,至少提供一個替代方案。core-js
是一個非常好的 polyfill,可確保最高規格的相容性,但使用者可能更喜歡不同的權衡。
(Nicolò)正在與 @ljharb 合作,以確保 @es-shims
專案 至少支援所有 ES2015+ 功能(我們實際上以 ES5+ 為目標),以便 Babel 使用者可以自由選擇至少兩個選項。
這需要在放棄對 core-js@3
的內建支援之前 發生,這樣對 es-shims
感興趣的人就不必遷移兩次。
擴充 targets
用法以進行細緻轉換
從一開始,@babel/preset-env
就使用 targets
選項來自動啟用或停用轉換外掛。
但是,Babel 外掛與瀏覽器中實作的功能之間並非一對一的對應關係。
例如,我們有一個單一外掛用於不同的類別欄位類型(公開和私有、靜態和實例),但瀏覽器具有不同的相容性矩陣
- Firefox 73 和 Safari 14 僅支援公開實例欄位
- Firefox 75+ 支援公開實例和靜態欄位
- Chrome 79+ 支援公開和私有欄位,但並不支援某些可選鏈接表達式中的私有欄位
- Chrome 84+ 完全支援私有欄位,也支援私有方法
- Safari TP 121 完全支援私有欄位(即使使用
?.
),但並不支援私有方法
為每個功能建立一個外掛並非最佳選擇。例如,我們可以將私有方法轉換為私有欄位,然後在需要時將它們轉換為舊語法。但是,如果我們知道需要向下轉譯,我們可以直接將私有方法轉換為舊語法,而無需中間步驟,從而產生更好/最佳化的輸出。
從 Babel 7.13.0 開始,我們可以在外掛中直接讀取 targets
選項,我們可以修改外掛以自動執行特定 ECMAScript 功能的部分編譯,這將在輸出大小和執行時間效能上帶來優勢。
先前技術
此方法並非完全創新。感謝與 @_developit 合作,在 Babel 7.9.0 中,我們為 @babel/preset-env
引入了新的 bugfixes: true
選項。啟用此選項,並使用 esmodules: true
作為編譯目標時,我們只會部分編譯 部分功能。這讓我們最初想到這種可能性,但目前的部份轉換在使用較新的目標時較不實用(例如,defaults, not ie 11
)。
我們也已使用 targets
選項來決定編譯物件擴充時是否可以使用 Object.assign
。
行動重點
此目標可以拆分成兩項大型任務,可以並行進行
- 我們需要透過收集實際的 browserslist 查詢,並模擬熱門查詢(例如,
defaults
或>2%, not dead
)在未來的演進方式,來找出這些最佳化在 何處 會有幫助。 - 我們需要實際實作必要的最佳化,並確保它們仍能與其他外掛程式順利運作(因為它們會大幅增加可能的轉換組合數量)。
調查新的編譯器 假設
在 Babel 7.13.0 中,我們引入了新的頂層 assumptions
選項,以形式化 loose
模式選項的功能,並提供更細緻的控制權給我們的使用者(因為他們通常只能啟用 部分 假設,而非全部)。
不過,我們只包含了在 loose
模式編譯時我們 已經 做出的假設選項。我們現在可以調查我們的使用者可能需要哪些新的假設。
已有一些提案,例如
我們可以透過以下方式找出應該實作哪些新的假設:
- 手動檢查我們編譯至「非顯而易見」輸出的功能,這通常是由許多開發人員不關心的邊緣案例所造成。
- 向社群尋求回饋,因為開發人員可以在他們的應用程式上測試哪些假設有效,哪些無效。
全面檢修 Babel REPL
Babel REPL 是學習 Babel 如何轉譯原始碼的便利遊樂場。
目前的限制
- REPL 不支援
assumptions
組態。儘管我們在 https://babel.dev.org.tw/assumptions 上有專用的逐假設基礎迷你 REPL,但目前我們無法顯示這些assumptions
如何一起運作 - REPL 不支援外掛選項。有些外掛需要選項,例如
@babel/plugin-proposal-record-and-tuple
和@babel/plugin-proposal-decorators
https://github.com/babel/website/issues/1292、https://github.com/babel/website/issues/2224、https://github.com/babel/website/pull/1970
好的功能
- AST 瀏覽器(與現有的整合)
- stderr 搭配完整的堆疊追蹤作為錯誤記錄
- stdout 作為輸出
- 從 UI 變更 Babel 版本
至少 15% 的 babel-website 中的開放問題與 REPL 有關:https://github.com/babel/website/issues?q=is%3Aissue+is%3Aopen+label%3Arepl
教育/除錯工具
關於 REPL/ASTExplorer,我們可以透過更多工具來協助我們自己和第三方外掛的一般外掛開發。這本質上相當具有探索性:AST 本身的不同視覺化、除錯等。
亨利已經斷斷續續在進行的一些事情
- Codesandbox 用於製作一個簡單的 Babel 外掛,與 https://astexplorer.net 類似,但具有自訂設定檔。
- 視覺化 輸入至輸出的對應,以協助了解 Babel 如何轉換其程式碼。即使在文件當中,這對於讓 JavaScript 使用者熟悉新的語法或轉換的特定示範也很有用。
- 對應 輸入至輸出,就像 sourcemap 類型的結構。可以進行反向對應,找出哪個外掛導致程式碼以特定方式輸出,這有助於除錯。
對於我們正在思考的內容,一個互動範例:https://babel-explorer.netlify.app/(按住滑鼠在底部區塊!)