Vue.js 官方 IDE/TS 支持工具 Volar:新的開(kāi)始
Volar 是 Vue.js 官方的 VSCode 擴(kuò)展。當(dāng)官方推薦 Vetur 時(shí),Volar 還是一個(gè)個(gè)人項(xiàng)目,隨著時(shí)間的推移,由于改進(jìn)的性能和體系結(jié)構(gòu)而被采納為新的官方擴(kuò)展。作為一個(gè)旨在改善開(kāi)發(fā)體驗(yàn)的項(xiàng)目,用了兩年多的時(shí)間才達(dá)到了 1.0 版本,并且一直在不斷改進(jìn)穩(wěn)定性。但還有許多工作要做,2023 年有更令人興奮的計(jì)劃!
Volar.js:嵌入式語(yǔ)言工具框架
盡管最初是為 Vue 單文件組件的特定需求而設(shè)計(jì)的,但 Volar 的代碼庫(kù)包含許多不特定于 Vue 的部分,例如:
- 嵌入式編程語(yǔ)言的處理;
- Vue 語(yǔ)言服務(wù)器實(shí)際上是一個(gè)成熟的 TypeScript 語(yǔ)言服務(wù)器;
- 處理與 LSP / Web / 嵌入式語(yǔ)言服務(wù)等交互的代碼。
注:語(yǔ)言服務(wù)器并不是一個(gè)真的服務(wù)器,而是把語(yǔ)言相關(guān)的特性和功能從 IDE 中解耦出來(lái),作為一個(gè)獨(dú)立的程序單獨(dú)運(yùn)行,提供了例如引用查詢等功能的具體實(shí)現(xiàn)。
現(xiàn)在已經(jīng)將這些通用部分提取到一組與框架無(wú)關(guān)的工具中。這些工具現(xiàn)在作為一個(gè)新的獨(dú)立項(xiàng)目進(jìn)行維護(hù):Volar.js[1]。
Volar.js 的架構(gòu)支持任何涉及嵌入式語(yǔ)言的文件格式——不僅是 Vue,還包括 Astro、Svelte,甚至 Angular。它還能夠?qū)崿F(xiàn)常規(guī)的單語(yǔ)言 LSP servers,例如 TypeScript、CSS 和 HTML。
Volar.js 的另一個(gè)主要關(guān)注點(diǎn)是性能。它旨在最大限度地減少實(shí)現(xiàn)原生嵌入式語(yǔ)言服務(wù)性能的開(kāi)銷。有很多問(wèn)題和優(yōu)化機(jī)會(huì),只有在擁有大量用戶的情況下才能發(fā)現(xiàn),而 Volar.js 是根據(jù)從數(shù)百萬(wàn)次下載中積累的經(jīng)驗(yàn)進(jìn)行優(yōu)化的。
例如,字節(jié)跳動(dòng)的 Lynx 團(tuán)隊(duì)是 Volar.js 的早期采用者,一個(gè)開(kāi)發(fā)人員用兩周的時(shí)間交付了一整套支持其內(nèi)部框架的語(yǔ)言工具。如果它是從頭開(kāi)始構(gòu)建的,即使是一個(gè)團(tuán)隊(duì)也需要幾個(gè)月的時(shí)間。
舊的 Volar 現(xiàn)在是 vuejs/language-tools
提取核心后,原始 Volar 擴(kuò)展和 vue-tsc 的代碼庫(kù)已移至 vuejs/language-tools[2] 存儲(chǔ)庫(kù)。這個(gè)存儲(chǔ)庫(kù)現(xiàn)在依賴于 Volar.js 并包含對(duì) Vue 特定支持的代碼。
除此之外,還將把一些 npm 包從 @volar 的 npm 組織轉(zhuǎn)移到 @vue。不過(guò),這些變化不應(yīng)該影響用戶。
團(tuán)隊(duì)與組織
?Vite[3] 從 Vue 生態(tài)系統(tǒng)中脫穎而出,并最終成長(zhǎng)為自己的社區(qū),連接整個(gè) Web 開(kāi)發(fā)生態(tài)系統(tǒng)的用戶,Volar.js 也希望走同樣的路。
Volar 作者 Johnson Chu 與 Astro 核心團(tuán)隊(duì)成員 Erika 建立了 Volar.js 核心團(tuán)隊(duì),致力于改善開(kāi)發(fā)者體驗(yàn)。團(tuán)隊(duì)將共同努力,為所有 Web 開(kāi)發(fā)者改進(jìn) DX,而不僅僅是 Vue 和 Astro。
他們創(chuàng)建了 volarjs 組織來(lái)維護(hù)框架和相關(guān)的存儲(chǔ)庫(kù):
- volar.js:框架的核心
- plugins[4]: 可以在 volar.config.js 或框架的 plugins 中使用
- volarjs.github.io[5]:官方網(wǎng)站
- language-tools-starter[6]:開(kāi)始使用 Volar.js 構(gòu)建語(yǔ)言服務(wù)器模板
- ecosystem-ci[7]:用于運(yùn)行 volar 生態(tài)系統(tǒng)項(xiàng)目的集成測(cè)試
- pug-language-tools[8]:基于 language-tools-starter 的 Pug 工具
- angular-language-tools[9]:基于 language-tools-starter 的 Angular 示例
- svelte-language-tools[10]:基于 language-tools-starter 的 Svelte 示例
下一步
這只是一個(gè)開(kāi)始,目前還沒(méi)有明確的長(zhǎng)期路線圖,但這里有一些計(jì)劃在接下來(lái)探索和努力的主要方向。
Monaco 支持
Monaco 對(duì) Vue 的支持目前由 monaco-volar 實(shí)現(xiàn),Volar 團(tuán)隊(duì)計(jì)劃在框架中支持它,因此所有基于 Volar.js 的語(yǔ)言服務(wù)器都可以輕松使用它。
支持 VSCode 以外的 IDE
除了 VSCode 之外,許多貢獻(xiàn)者還為 Volar 的 Vim、Sublime、Atom、Emacs、Nova、Lapce 等其他 IDE 實(shí)現(xiàn)了語(yǔ)言客戶端。擁有一整套的 IDE 支持可能有很大的參考價(jià)值,因?yàn)楹苌儆腥四軌蚓ㄋ羞@些 IDE。
Volar 團(tuán)隊(duì)將尋找方法來(lái)利用這些貢獻(xiàn)者的努力,以減少框架使用者在 VSCode 之外實(shí)現(xiàn)語(yǔ)言客戶端的工作量。
除此之外,雖然 IntelliJ 沒(méi)有一流的 LSP 支持,Volar 團(tuán)隊(duì)將研究是否可以將其與框架集成。
基于 Bun 的語(yǔ)言服務(wù)器
理論上,Volar 的性能只能無(wú)限接近,但不會(huì)快于 vanilla TS 語(yǔ)言服務(wù)器。但是,如果 Volar 語(yǔ)言服務(wù)器可以通過(guò)在 Bun 中運(yùn)行而獲得性能提升,它可能會(huì)改變游戲規(guī)則。
以前 Bun 運(yùn)行時(shí)還不兼容基于 Node.js 的 LSP 服務(wù)器。Volar 團(tuán)隊(duì)會(huì)持續(xù)關(guān)注相關(guān)問(wèn)題,待問(wèn)題解決后進(jìn)行重試。同樣,所有基于 Volar.js 的語(yǔ)言服務(wù)器都將能夠直接從中受益。
單體服務(wù)器
想象一個(gè)場(chǎng)景,每種語(yǔ)言都需要支持一些 TypeScript 特性,那么每種語(yǔ)言的語(yǔ)言服務(wù)器都會(huì)運(yùn)行自己昂貴的 TypeScript 語(yǔ)言服務(wù)實(shí)例,這讓情況變得變得糟糕,因?yàn)閮?nèi)存和 CPU 使用率都會(huì)成倍增加,而這種情況如今已經(jīng)發(fā)生了。
如果這些語(yǔ)言服務(wù)器中的一些是基于 Volar.js 的,可能有一些方法讓他們決定只激活一個(gè)語(yǔ)言服務(wù)器,然后將其余語(yǔ)言服務(wù)器的功能共享給激活的服務(wù)器,這樣最終只需要在一個(gè)語(yǔ)言服務(wù)器實(shí)例而不是多個(gè)語(yǔ)言服務(wù)器中運(yùn)行 TypeScript 語(yǔ)言服務(wù)。
這也可以解決 TypeScript 插件無(wú)法支持的一些用例。
基于 Volar.js 架構(gòu),已經(jīng)非常接近這個(gè)目標(biāo),Volar 團(tuán)隊(duì)將為 Vue 和 Astro 語(yǔ)言服務(wù)器探索這個(gè)特性。
Rules API(內(nèi)置 Linter)
在 ESLint 和 Prettier 一起使用時(shí)可能會(huì)出現(xiàn)沖突,而過(guò)去基于 Plugin API 的嘗試并沒(méi)有很好地避免這個(gè)問(wèn)題。
Rules API 是避免不同 linting 工具之間沖突的另一種嘗試,同時(shí)也確保性能和特性與 IDE 完美集成。
對(duì)于元框架,它們需要為 ESLint 和 Prettier 實(shí)現(xiàn)自己的解析器,但是有了 Rules API,它們甚至不需要這樣做,因?yàn)榭梢灾赜?Volar 語(yǔ)言服務(wù)器的解析器。
因此,如果編寫(xiě)了一個(gè) TS 規(guī)則,它將直接通過(guò) Rules API 用于 Vue 的 ??<script>?
? 和模板中的 TypeScript 代碼,而不需要額外的解析器。
這并不意味著需要重寫(xiě)所有規(guī)則;Rules API 只是一個(gè) API,而不是一個(gè)單獨(dú)的 linter,因此仍然可以重用 ESLint、TSLint 甚至 Rome 中的一些規(guī)則。
Scripts API
對(duì)于 Vue,有 Vue-tsc 來(lái)檢查TS代碼,Volar 團(tuán)隊(duì)也想在 CI 中同時(shí)檢查 CSS 和 Vue Template 代碼。
Scripts API 旨在公開(kāi)語(yǔ)言服務(wù)器的格式化和 linting 功能,以便它們可以在腳本中使用,允許開(kāi)發(fā)者在 CI 或 git 預(yù)提交 Hooks 中使用它并獲得與在 IDE 中相同的結(jié)果。
相關(guān)鏈接
[1]Volar.js: https://volarjs.github.io/
[2]vuejs/language-tools: https://github.com/vuejs/language-tools
[3]Vite: https://vitejs.dev/
[4]plugins: https://github.com/volarjs/plugins
[5]volarjs.github.io: https://volarjs.github.io/
[6]language-tools-starter: https://github.com/volarjs/language-tools-starter
[7]ecosystem-ci: https://github.com/volarjs/ecosystem-ci
[8]pug-language-tools: https://github.com/volarjs/pug-language-tools
[9]angular-language-tools: https://github.com/volarjs/angular-language-tools
[10]svelte-language-tools: https://github.com/volarjs/svelte-language-tools