解析:Flow 前沿語(yǔ)法格式化與版本兼容全指南)
語(yǔ)言運(yùn)行時(shí)編譯器移動(dòng)開(kāi)發(fā)【免費(fèi)下載鏈接】hermesA JavaScript engine optimized for running React Native.項(xiàng)目地址https://gitcode.com/gh_mirrors/hermes/hermes點(diǎn)擊查看免費(fèi)下載導(dǎo)讀本文以 Hermes 倉(cāng)庫(kù)內(nèi) tools/hermes-parser/js/prettier-plugin-hermes-parser/CHANGELOG.md 為主線系統(tǒng)講解prettier-plugin-hermes-parser當(dāng)前倉(cāng)庫(kù)版本 0.37.0的設(shè)計(jì)定位、安裝配置、底層打印原理以及它隨版本迭代逐步支持 React 組件/ Hook 聲明、Flow 新型 variance、keyof、match 模式、Records、opaque type 上下界等前沿語(yǔ)法的完整過(guò)程。讀完本文你將掌握該插件的接入方式、版本選擇依據(jù)并能從源碼與測(cè)試層面理解它如何讓 Prettier 持續(xù)兼容 Hermes 解析器產(chǎn)出的最新 ESTree 結(jié)構(gòu)。一、插件定位讓 Prettier 認(rèn)識(shí) Hermes 的 ASTprettier-plugin-hermes-parser是 Hermes 生態(tài)中連接「解析」與「格式化」的橋梁。Hermes 的 JavaScript 解析器由 C 實(shí)現(xiàn)并編譯為 WASM能完整解析 Flow、JSX 以及大量尚未進(jìn)入 Prettier 官方插件的實(shí)驗(yàn)性語(yǔ)法。Prettier 官方自帶 Babel 等解析器插件但無(wú)法第一時(shí)間覆蓋 Hermes 解析器支持的這些「超集」語(yǔ)法節(jié)點(diǎn)該插件的職責(zé)就是把 Hermes 解析器產(chǎn)出的 AST以estree-hermes格式標(biāo)識(shí)接入 Prettier 的打印管線從而讓這些新語(yǔ)法也能獲得一致的格式化輸出。需要特別說(shuō)明定位倉(cāng)庫(kù) README.md 明確寫(xiě)道——「Unless you want to be on the bleeding edge, you should use the officialprettier/plugin-hermesinstead」。也就是說(shuō)追求穩(wěn)定環(huán)境的普通用戶應(yīng)使用官方發(fā)布的prettier/plugin-hermes而本插件是 Hermes 倉(cāng)庫(kù)內(nèi)維護(hù)的「前沿bleeding edge」版本用于更快跟進(jìn) Hermes 解析器新增的語(yǔ)法在 0.31.1 版本中插件正是在prettier/plugin-hermes基礎(chǔ)上重建Rebuild based onprettier/plugin-hermes. There should be no formatting differences, but it will be less buggy由此繼承了其打印邏輯同時(shí)以獨(dú)立版本線繼續(xù)演進(jìn)。從 package.json 的元數(shù)據(jù)package.json可以看到包名prettier-plugin-hermes-parser版本 0.37.0MIT 許可入口通過(guò)exports字段暴露./index.mjsESM 模塊peerDependencies聲明prettier: ^3.0.0——插件僅支持 Prettier v3這與 0.31.0 版本移除 Prettier v2 支持的決策一致見(jiàn) tools/hermes-parser/js/CHANGELOG.md 0.31.0 條目。二、安裝與配置將 hermes 設(shè)為解析器2.1 基礎(chǔ)配置插件的使用方式非常直接安裝插件后在 Prettier 配置中把它加入plugins列表并對(duì)需要走 Hermes 解析器的文件通過(guò)overrides指定parser: hermes。倉(cāng)庫(kù) README 給出了完整的 .prettierrc 示例{ plugins: [prettier-plugin-hermes-parser], overrides: [ { files: [*.js, *.jsx, *.flow], options: { parser: hermes } } ] }其中overrides的files可擴(kuò)展至你項(xiàng)目中所有使用 Flow/JSX 的文件類型parser: hermes是插件向 Prettier 注冊(cè)的解析器名。之所以用overrides而非全局parser是為了讓.js/.jsx/.flow之外的文件繼續(xù)走 Prettier 默認(rèn)解析器。2.2 在測(cè)試中的實(shí)際調(diào)用方式倉(cāng)庫(kù)的單元測(cè)試展示了編程式調(diào)用方式可視為配置的「代碼形態(tài)」。以 prettier-plugin-hermes-parser-test.js 為例function getOptions() { return { ...prettierConfig, parser: hermes, requirePragma: false, plugins: [require.resolve(../index.mjs)], }; } const output await prettier.format(code, getOptions());要點(diǎn)包括parser: hermes與 CLI/配置文件中的寫(xiě)法完全一致plugins直接引用本地index.mjs的解析路徑requirePragma: false表示不需要prettier類 pragma 注釋也會(huì)格式化。測(cè)試還額外驗(yàn)證了格式化的穩(wěn)定性idempotency——對(duì)輸出結(jié)果二次格式化必須與首次結(jié)果逐字節(jié)一致這是 Prettier 插件質(zhì)量的關(guān)鍵指標(biāo)。三、入口實(shí)現(xiàn)index.mjs 與 avoidAstMutation理解插件能力邊界最好的切入點(diǎn)是它的入口文件 index.mjs。整個(gè)文件非常精簡(jiǎn)import hermesPlugin from ./index.generated.mjs; const HERMES_AST_FORMAT estree-hermes; const hermesPrinter hermesPlugin.printers[HERMES_AST_FORMAT]; const printers { ...hermesPlugin.printers, [HERMES_AST_FORMAT]: { ...hermesPrinter, experimentalFeatures: { ...hermesPrinter.experimentalFeatures, avoidAstMutation: true, }, features: { ...hermesPrinter.features, experimental_avoidAstMutation: true, }, }, }; export const languages hermesPlugin.languages; export const options hermesPlugin.options; export const parsers hermesPlugin.parsers; export {printers};從源碼結(jié)構(gòu)可以提煉出三點(diǎn)實(shí)現(xiàn)事實(shí)核心實(shí)現(xiàn)來(lái)自生成文件真正的解析器與打印器邏輯位于index.generated.mjs由scripts/build-prettier.sh從 Prettier fork 構(gòu)建產(chǎn)出見(jiàn)下文「貢獻(xiàn)與構(gòu)建」一節(jié)入口文件只是在其上做輕量包裝。estree-hermes打印格式插件注冊(cè)的 AST 格式標(biāo)識(shí)為estree-hermesPrettier 根據(jù)該標(biāo)識(shí)找到對(duì)應(yīng)的 printer 來(lái)序列化 Hermes 解析器輸出的節(jié)點(diǎn)。avoidAstMutation避免 AST 變異這是本插件相對(duì) Prettier 默認(rèn)行為的重要差異——它顯式開(kāi)啟了實(shí)驗(yàn)性特性experimental_avoidAstMutation即打印過(guò)程中不修改傳入的 AST。這對(duì)hermes-transform、flow-api-translator等依賴 AST 多次復(fù)用的工具鏈尤為關(guān)鍵保證打印不會(huì)破壞原始節(jié)點(diǎn)結(jié)構(gòu)相關(guān)背景見(jiàn) tools/hermes-parser/js/CHANGELOG.md 0.15.0 中print緩存鍵唯一性的修復(fù)以及 0.13.0 中「Printer 始終使用本插件以支持最新 Flow 語(yǔ)法」的決策。四、版本演進(jìn)全景0.31.1 → 0.37.0 的功能時(shí)間線CHANGELOG 將 0.31.1 之前的歷史指向 tools/hermes-parser/js/CHANGELOG.mdhermes-parser 系列的主 changelog因此本文聚焦 0.31.1 之后獨(dú)立維護(hù)的條目。以下按功能類別梳理4.1 對(duì) Prettier 版本的兼容與同步選型必讀0.37.0修復(fù)與 Prettier 3.7 的兼容性問(wèn)題Fix compatibility with Prettier 3.7。這是當(dāng)前最新版本如果你的工程升級(jí)到了 Prettier 3.7 及以上應(yīng)使用該版本。0.33.2將內(nèi)置基礎(chǔ) Prettier 版本回退到 3.6.2但保留其他變更Reverts base Prettier version back to 3.6.2, but keeps other changes。這提醒我們插件內(nèi)部「基于某個(gè) Prettier 版本 fork」與「對(duì)宿主 Prettier 版本的兼容」是兩條獨(dú)立的維度基礎(chǔ)版本的升降不影響插件在宿主環(huán)境中的工作。0.33.1包含直至 Prettier 3.7.4 的變更Includes changes up to Prettier 3.7.4。0.31.1基于prettier/plugin-hermes重建格式輸出不變但更少 bug。這些條目的實(shí)踐含義是插件版本與宿主 Prettier 版本需要匹配。若宿主 Prettier 較新≥3.7應(yīng)優(yōu)先使用 0.37.0若被 0.37.0 的兼容修復(fù)影響可結(jié)合 0.33.x 的兼容策略評(píng)估回退路徑。4.2 新語(yǔ)法格式化支持核心能力這是插件的核心競(jìng)爭(zhēng)力——讓 Prettier 能夠打印 Hermes 解析器支持的各類 Flow 實(shí)驗(yàn)語(yǔ)法React 組件與 Hook 聲明0.36.1支持async component和async hook聲明的格式化。對(duì)應(yīng)解析器側(cè)在 hermes-parser 0.34.0 就加入了async hook/async component語(yǔ)法支持0.36.1 修復(fù)了async component函數(shù)體內(nèi)await不被識(shí)別的問(wèn)題隨后插件跟進(jìn)打印支持。Flow variance 新語(yǔ)法0.36.0、0.35.0支持新的 Flow variance 語(yǔ)法并將readonly作為等價(jià)于協(xié)變/只讀的 variance 注解加以支持可作用于對(duì)象類型屬性、索引器、類屬性乃至元組標(biāo)記元素。hermes-estree 側(cè)在 0.36.0 為 variance 類型新增了writeonly、in、out0.35.0 新增readonly插件隨之同步。keyof運(yùn)算符0.34.0支持 Flow 新的keyof運(yùn)算符用于替代$Keys。match 實(shí)例模式與 Flow Records0.33.1支持 Flow match 實(shí)例模式match語(yǔ)句/表達(dá)式與 Records記錄字面量{}語(yǔ)法。opaque type 上下界0.32.0支持同時(shí)帶下界與上界的 opaque type即super與extends語(yǔ)法對(duì)應(yīng)解析器 0.30.0 的解析能力。上述每一項(xiàng)都有對(duì)應(yīng)的專項(xiàng)測(cè)試文件佐證例如 component-declaration-test.js組件聲明、readonly-variance-test.jsreadonly variance、keyof-test.jskeyof、match-test.js、record-test.js、opaque-type-test.js以及 const 類型參數(shù)const-type-param-test.js與declare component/declare hookdeclare-component-test.js、declare-hook-test.js等。4.3 Bug 修復(fù)穩(wěn)定性保障0.34.1修復(fù)自動(dòng)格式化器意外刪除空格、導(dǎo)致 Prettier 補(bǔ)出多余空行的問(wèn)題a white space was accidentally removed by autoformatter causing prettier to add unnecessary new lines。這一條說(shuō)明插件同時(shí)維護(hù)自己的生成代碼風(fēng)格生成過(guò)程中的空白處理也是質(zhì)量保障的一部分。4.4 其他語(yǔ)法細(xì)節(jié)0.36.0支持DeclareVariable聲明的數(shù)組形式SupportDeclareVariabledeclarations array對(duì)應(yīng) Flow 中declare var聲明數(shù)組的打印。五、格式化效果示例從測(cè)試快照看插件行為專項(xiàng)測(cè)試中的 inline snapshot 直接展示了插件的真實(shí)輸出是理解其格式化行為的最佳素材。以下從 component-declaration-test.js 選取典型場(chǎng)景組件聲明含導(dǎo)出、泛型約束、可選參數(shù)、默認(rèn)值component MyComponent() {} component MyComponent() renders SomeComponent {} export component MyComponent() {} component MyComponentT() {} component MyComponent(bar: string) {} component MyComponent(bar?: string) {} component MyComponent(bar: string ) {}超長(zhǎng)泛型約束與長(zhǎng)參數(shù)列表自動(dòng)換行體現(xiàn) Prettier 折行策略與 Flow 尾逗號(hào)約定component MyComponent T: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, () {} component MyComponent( bar: string, baz: $ReadOnly{k: string}, realllllllllllllllllllyLong: string, ) {}rest 參數(shù)、注釋保留塊注釋、行尾注釋、前置注釋均被穩(wěn)定保留并正確對(duì)齊component MyComponent(...restProps: $ReadOnly{k: string}) {} component MyComponent( /** * Commet block */ bar: string, // Trailing comment // preceding comment data-baz as baz: $ReadOnly{k: string}, ) {}JSX 穩(wěn)定性prettier-plugin-hermes-parser-test.js測(cè)試驗(yàn)證了 JSX 變量聲明「一次格式化后再次格式化結(jié)果完全一致」并確保嵌套 JSX 中不會(huì)在開(kāi)標(biāo)簽后/閉標(biāo)簽前出現(xiàn)多余空行function Foo() { return ( View style{styles.root} View style{styles.content} TextHello/Text Button onClick{handleClick} / /View Separator / /View ); }內(nèi)嵌標(biāo)簽?zāi)0錱raphql / css與 prettier-ignore 注釋也在同一測(cè)試中驗(yàn)證可正常工作說(shuō)明插件保留了 Prettier 的完整嵌入式格式化能力const styles { content: css column-gap: 8px; display: grid; grid-template-columns: 1fr 3fr; , };六、在 Hermes 工具鏈中的位置為 transform 與 translator 提供打印能力本插件并不僅服務(wù)于命令行格式化它還是 Hermes 代碼變換工具鏈的「打印后端」。從 tools/hermes-parser/js/CHANGELOG.md 可以還原這條依賴鏈0.13.0hermes-transform與flow-api-translator的 Printer「始終使用prettier-plugin-hermes-parser以確保支持最新 Flow 語(yǔ)法」——即 AST 變換/翻譯后的代碼統(tǒng)一交給本插件序列化0.15.0hermes-transform增加對(duì)本插件的peerDependency并保證print緩存鍵在存在多實(shí)例時(shí)唯一0.32.0hermes-transform在安裝了本插件時(shí)使用它來(lái)打印變換后的代碼0.37.0最新hermes-transform改為使用 Prettier 內(nèi)置的 Flow 與 TypeScript 插件打印不再條件加載本插件——這是對(duì)當(dāng)前主 changelog 中該工具鏈策略的一次重要調(diào)整說(shuō)明本插件的職責(zé)正逐步回歸「面向使用者的獨(dú)立格式化插件」角色。因此如果你在研究hermes-transformAST 變換后重寫(xiě)源碼或flow-api-translatorFlow 轉(zhuǎn) TypeScript 定義本插件的歷史版本行為與之深度耦合理解這份 CHANGELOG 有助于判斷打印行為差異的來(lái)源。七、貢獻(xiàn)與構(gòu)建基于 Prettier fork 的二次開(kāi)發(fā)倉(cāng)庫(kù)內(nèi) CONTRIBUTION.md 描述了插件本質(zhì)上是一份「修改版 Prettier v3」的構(gòu)建流程對(duì)想深入貢獻(xiàn)的開(kāi)發(fā)者很有價(jià)值在hermes-parser/js下運(yùn)行./scripts/build-prettier.sh執(zhí)行 yarn 構(gòu)建腳本對(duì)位于hermes-parser/js/prettier-hermes-flow-fork的 Prettier fork 倉(cāng)庫(kù)做修改修改完成后運(yùn)行yarn build-prettier重新構(gòu)建完成后在 fork 倉(cāng)庫(kù)內(nèi)提交并可將相關(guān)改動(dòng)向上游提交 PR。手動(dòng)流程則是檢出 Prettier 的 flow fork執(zhí)行yarn build --packageprettier/plugin-hermes將構(gòu)建產(chǎn)物dist/plugin-hermes及全部 JS 文件拷貝到本目錄。這也解釋了入口文件為何是index.mjs引用index.generated.mjs——后者即構(gòu)建生成的、體積較大的完整插件實(shí)現(xiàn)。八、總結(jié)與版本選擇建議prettier-plugin-hermes-parser的演進(jìn)史是 Hermes 解析器語(yǔ)法擴(kuò)展的縮影每當(dāng) hermes-parser 新增語(yǔ)法解析能力插件在下一版本即跟進(jìn)打印支持同時(shí)持續(xù)同步 Prettier 上游并修復(fù)空白、換行等細(xì)節(jié)問(wèn)題。選擇建議如下穩(wěn)定場(chǎng)景優(yōu)先使用官方prettier/plugin-hermes見(jiàn) README.md前沿場(chǎng)景需要格式化component/hook聲明、Flow 新 variance、keyof、match 模式、Records、opaque type 上下界等實(shí)驗(yàn)語(yǔ)法時(shí)使用本插件版本匹配宿主 Prettier ≥ 3.7 時(shí)使用 0.37.0更早版本可參考 0.33.x 的兼容與回退策略peerDependency 約束為 Prettier ^3.0.0不支持 v2驗(yàn)證手段所有格式化行為均可通過(guò)倉(cāng)庫(kù)內(nèi)tests目錄下的專項(xiàng)測(cè)試含穩(wěn)定性與快照斷言復(fù)核便于在接入前評(píng)估對(duì)自身代碼庫(kù)的影響。贊分享語(yǔ)言運(yùn)行時(shí)編譯器移動(dòng)開(kāi)發(fā)【免費(fèi)下載鏈接】hermesA JavaScript engine optimized for running React Native.項(xiàng)目地址https://gitcode.com/gh_mirrors/hermes/hermes點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Vector NATS Sink 詳解配置、認(rèn)證策略與 JetStream 發(fā)布實(shí)戰(zhàn)Vector NATS Sink 詳解配置、認(rèn)證策略與 JetStream 發(fā)布實(shí)戰(zhàn) Vector 的 nats sink 用于將觀測(cè)數(shù)據(jù)日志事件發(fā)布到語(yǔ)言運(yùn)行時(shí)編譯器移動(dòng)開(kāi)發(fā)使用 prettier/plugin-hermes 為 Prettier 接入 Hermes 解析器使用 prettier/plugin hermes 為 Prettier 接入 Hermes 解析器 本篇技術(shù)指南圍繞 Prettier 官方倉(cāng)庫(kù)中的 pr開(kāi)發(fā)工具格式化CLITypeSpec Prettier 插件typespec/prettier-plugin-typespec 的架構(gòu)、使用與版本演進(jìn)全解析TypeSpec Prettier 插件 typespec/prettier plugin typespec 的架構(gòu)、使用與版本演進(jìn)全解析 導(dǎo)讀 type編程語(yǔ)言編譯器后端創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考