【前端必知】膠水(框架) Stencil.js

  • 2019 年 10 月 7 日
  • 筆記

去年的同一時間,我寫了那篇《前端下半場:構建跨框架的 UI 庫》推薦了 Stencil.js,當時是在項目的試驗期。而 Stencil.js 已經在今年(2019 )的 6 月份,推出了 1.0 正式版,這意味着你已經可以開始採用這個~~框架~~(編譯器)了——當然了,我不對我的這句話『負責』,你自己的鍋自己背。

故事是這麼開始的。

上周我在為 @花仲馬 ~~複製~~ (開發)一個內容主題生成器 ( https://content.phodal.com )(受限於其中數據的版權問題,暫時不敢開源——我都是直接複製別的網站的),便開始在尋找一個能用得上的前端框架。畢竟:

  • React 用膩了
  • Angular 用膩了
  • Vue 要出 3.0 了
  • jQuery 可能會被笑話
  • 原生 JavaScript 我不會了

所以,我開始絞盡腦汁找一個新的框架,直到我從 Web Components 框架里又找到了 Stencil.js。

過去,我曾經使用過 Ionic 開發了超過兩位數的應用,除了 stars 數上千的 Growth,還有一個交易額 xxxxx 千億的商業應用。所以,既然是 Ionic Framework 團隊開發的框架,那我還是有點信心 ~~擔心~~ 的。

為什麼是 Stencil.js

Ctrl + C/V 一下官方的介紹:Stencil 是一個生成 Web Component 的編譯器(更具體地說,Custom Elements)。Stencil 將最流行框架的最佳概念,結合到一個簡單的構建時工具中。

它提供了以下的特性。

  • Virtual DOM
  • Async rendering
  • Reactive data-binding
  • TypeScript
  • JSX

為什麼說它結合了最流行框架的最佳概念——它的代碼看上去就像 Angular + React 的混合體:使用了 裝飾器 來聲明類型,還有類似於 Angular 風格的 Component 聲明方式,以及還有 React 的 TSX,還有 Vue 融合了多個框架的思想和能力……。

@Component({   tag: 'my-component',   styleUrl: 'my-component.css',   shadow: true  })  export class MyComponent {   @Prop() first: string;     private getText(): string {   return this.first;   }     render() {   return <div>Hello, World! I'm {this.getText()}</div>;   }  }

So,Stencil.js 便是面向未來的集大成者——你們都抄不過我的。

由於使用 Stencil 開發的組件只是 Web Components,所以這些組件可以運行在所有的主流框架(AVR)中,也可以獨立地運行。這一特質使它可以成為新的前端容器框架——畢竟 Web Components 是一個新的前端容器。

用途一:開發前端應用

好吧,沒啥說的,大家都懂。

不過呢,Stencil.js 用來開發前端應用的另外一個優勢是,已經有一個成熟的組件庫:Ionic 系列的組件庫。而 Ionic 系列的組件,已經在大量的應用驗證過了。

除此,還與有內建了 Service Workers 生成工具。

順帶誇獎一下 Ionic 團隊,這一步步下的棋非常棒。先是開發了用於 Angular.js 和 Angular 的 Ionic,然後開發了 Ionic Native,並且讓 Ionic 可以支持不同的框架,現在又有了 Stencil.js。

用途二:連接混合應用

儘管 Flutter、React Native 已經很流行了,但是對於沒有 Native 能力的團隊來說,混合應用仍然是一個非常友好的選擇。

標題的說法可能不太準確,不過呢,Stencil.js 是 Ionic 框架背後的組件庫的支撐框架,它變成了 Ionic 這個混合應用框架的核心之一。

用途三:連接其它前端框架

嗯,Web Components 的一大特質,就是讓你編寫的應用可以嵌入其它框架中。

用途四:構建跨框架的 UI 庫 / 設計系統

由於 Stencil.js 是一個基於 Web Components 設計的框架,因此由它創建的組件庫,可以輕鬆地在可以引入 Web Component 的瀏覽器和框架上運行。

Stencil.js 存在的另一大特質是 按需加載。基於 Stencil.js 構建的組件庫,呈現的結構是:單一組件以單一 chunk/entry 的形式存在。

如下是在 Stencil.js 中引入 Ionic 組件庫時,生成的組件與 *.entry.js 的綁定關係:

[[1, "ion-avatar"]]], [{   "ios": "p-lyuug53j",   "md": "p-hixhmhon"  }, [[1, "ion-badge", {"color": [1]}]]], [{   "ios": "p-q6fmpdfd",   "md": "p-daqtamux"  }, [[0, "ion-card-content"]]], [{   "ios": "p-xn1drh7m",   "md": "p-b9b9dqwt"  }

以這裡的代碼為例,如果我們用了 ion-avatar,而且對應的系統是 iOS,那麼就會加載 p-lyuug53j.entry.js,如果對應系統是 Android(md,Material Design),那麼就會加載 p-hixhmhon.entry.js

從這等意義上來說,Stencil.js 真的是一個工具鏈,哈哈。由於遺憾的是當前生成的組件目錄結構比較亂——如果你有 100 個組件,那麼至少會生成 100 個 entry.js 文件。不過,可能是我沒有找到配置的地方。

用途五:微前端應用

結合按需加載跨框架的模式,使用 Stencil.js 開發的組件或者是功能模板,就可以解決部分微前端應用之間的依賴重複問題。也因此 Stencil.js 特別適合用於開發微前端框架模式中的微件化架構。

結論:膠水框架

Web Components 大法雖好,但是你還是需要一個快速開發 Web Components 的框架/工具。