Categories
程式開發

RSLint:使用Rust開發的JS Linter,可以解析錯誤代碼


Riccardo D’Ambrosio最近發布了RSLint,一個完全用Rust開發的JavaScript linter。 RSLint力求盡可能快、可定制和易於使用。 RSLint仍處於開發的早期階段,主要特色是與Visual Studio Code的集成。

RSLint的作者是這樣描述他的動機的:

這是一個成熟的JavaScript linter,只是用Rust從頭開始開發。我覺得現有的linter功能太有限,速度太慢,於是決定嘗試自己開發一個,並帶有一些自己的想法:

速度:文件加載、文件檢查和規則運行都是並行的;
rustc風格且友好的錯誤信息(包括標籤、註釋);
錯誤恢復:不管多離譜的源代碼可以檢查;
……
更強大的指令。

與其他linter一樣,RSLint努力幫助開發人員實施良好的實踐,並標記編程錯誤、bug、風格錯誤和可疑的代碼。 linter通常在代碼編輯器中用於在編輯時提供實時反饋。使用了大量lint規則的大型代碼庫的用戶可以從更快的實時反饋中獲得開發速度方面的好處。

類似地,當lint規則提示錯誤時,特別是當規則很複雜或引用了其他幾個語法實體時,友好的解釋性錯誤消息可以幫助開發人員增長經驗。

D’Ambrosio強調了RSLint的錯誤恢復能力,據稱已知的linter不具備這個能力:

錯誤恢復是指解析器能夠接受不正確的源代碼,並且仍然能夠解析出基本正確的AST(抽象語法樹)。大多數linter根本不會這麼做,例如,espree和swc_ecmascript(分別是ESLintdeno_lint的解析器)不會嘗試進行錯誤恢復。當解析器遇到錯誤時,它們返回一個Err結果並停止解析,不生成AST……這意味著linter不可能檢查錯誤的代碼,如果能在IDE中實現這個功能,將是很驚人的。

RSLint可以解析這樣的代碼:

if true {
  /* */
} else {
  /* */
}

然後檢查它:

error[SyntaxError]: Expected token `L_PAREN` but instead found `TRUE_KW`
  ┌─ testsmain.js:1:4
  │
1 │ if true {
  │    ^^^^ Unexpected
error[SyntaxError]: Expected token `R_PAREN` but instead found `L_CURLY`
  ┌─ testsmain.js:1:9
  │
1 │ if true {
  │         ^ Unexpected
error[no-constant-condition]: Unexpected constant condition
  ┌─ testsmain.js:1:4
  │  
1 │   if true {
  │      ^^^^ this condition is always truthy...
2 │     /* */
3 │   } else {
  │ ┌────────'
4 │ │   /* */
5 │ │ }
  │ └─' ...which makes this unreachable

D’Ambrosio回顧了該項目的初期想法:

但是請注意,rslint_parser仍處於早期開發階段,並且錯誤恢復有時會有很多bug,但是在將來會變得更好。

RSLint速度的提升不僅是因為使用Rust開發(編譯成機器碼),也因為它使用了並行執行和特定的數據結構(不是傳統的AST)。 RSLint使用了為Rust分析器項目開發的羅文庫。 rowan生成的語法樹是不可變的,而不是克隆成本很高的可變AST。

RSLint提供了一些指令,在檢查代碼時可以忽略一些文件,或者在某些情況下(rsLint-ignore)忽略特定的lint規則。 RSLint目前實現了大約25條規則(例如,沒有異步的承諾執行者沒有等待循環或者無重複鍵),未來還將計劃實現更多規則。開發人員可以編寫自定義規則。不過,文檔中提到,自定義規則必須用Rust宏來編寫——這可能給JavaScript社區貢獻內容造成了障礙。

RSLint是用其他語言開發可編譯為原生代碼的JavaScript工具這一新興趨勢的一部分。 InfoQ之前曾報導過用Go語言開發的JavaScript打包器esbuild。 swc是一個基於Rust的JavaScript/TypeScript編譯器。縮短JavaScript工具的反饋週期、利用開發者機器強大的多核功能以及對原始性能的追求推動了這一趨勢。

然而,使用compile-to-native編程語言來編寫代碼並不是實現高吞吐量的唯一方法。通過減少自動化任務的作用範圍,也可以提升工具的速度。在去年的一些基準測試中,JavaScript/TypeScript編譯器Sucrase擊敗了基於Rust的swc編譯器。然而,Sucrase只針對開發構建,並做了一些限制性的假設(例如,不支持Node 6或Internet Explorer)。

JavaScript社區的一些成員在Reddit上表達了對RSLint的樂觀態度。一個用戶提到:

這太棒了!雖然還處於早期階段,但它很出色,我們期待看到這個項目更多的進展!

另一篇文章列舉了要讓社區採用需要滿足的一些特性:

看起來不錯。我希望能加快代碼檢查的速度。為了能夠在工作中使用,它要非常成熟而且功能完善,並在一定程度上保證項目的維護。

RSLint目前正處於開發的早期階段。 RSLint路線圖包括基準測試、作用域分析、自動修復、JSX和TypeScript支持、JavaScript插件,等等。已知的問題文檔可以在網上找到。

RSLint採用了MIT開源許可。開發者可以通過該項目的GitHub存儲庫參與貢獻或拉取請求。

原文鏈接

RSLint,用Rust寫的一種新的,快速的JavaScript Linter