Theia架構


上一篇:Theia——雲端和桌面版的IDE

架構概述

  本節描述了Theia的整體架構。
  Theia被設計為一個可以在本地運行的桌面應用程序,也可以在瀏覽器和遠程服務器之間工作。為了支持這兩種工作方式,Theia運行在兩個獨立的進程中,它們被稱之為前端和后端,相互之間通過WebSockets上的JSON-RPC消息或HTTP上的REST APIs來通信。對於Electron而言,前端和后端都在本地運行,而在遠程上下文中,后端運行在遠程服務器上。
  前端和后端進行都有它們各自的依賴注入(DI)容器(詳見下文),以方便開發者進行擴展。

前端

  前端部分負責客戶端的UI呈現。在瀏覽器中,它只是簡單地在渲染循環中運行。而在Electron中,它運行在Electron窗口中,這是一個包含Electron和Node.js APIs的瀏覽器窗口。因此,任何前端代碼都可以把瀏覽器而不是Node.js作為一個運行平台。
  啟動前端進程將首先加載所有擴展包的DI模塊,然后獲取一個 FrontendApplication的實例並在上面調用 start()

后端

  后端進程運行在Node.js上。我們使用express作為HTTP服務器,它可以不使用任何需要瀏覽器平台的代碼(DOM API)。
  啟動后端應用程序將首先加載所有擴展包的DI模塊,然后獲取一個 BackendApplication的實例並在上面調用 start(portNumber)
  默認情況下后端的express服務器也為前端提供代碼。

按平台進行區分

  在擴展包的根目錄下,包含如下子目錄層級,按不同的平台進行區分:
  • common目錄下包含的代碼不依賴於任何運行時。
  • browser目錄下包含的代碼需要運行在現代瀏覽器平台上(DOM API)。
  • electron-browser目錄下包含了需要DOM API及Electron渲染進程特定的APIs的前端代碼。
  • node目錄包含了需要運行在Node.js下的后端代碼。
  • node-electron目錄包含了Electron特定的后端代碼。

參見

  可以查看這篇文章了解有關Theia架構的簡要概述:

  利用JS實現多語言IDE——目標和架構(Multi_Language IDE Implemented in JS - Scope and Architecture)

擴展包

  Theia由擴展包構成。一個擴展包就是一個npm包,在這個npm包中公開了用於創建DI容器的多個DI模塊( ContainerModule)。
  通過在應用程序的 package.json中添加npm包的依賴項來使用擴展包。擴展包能夠在運行時安裝和卸載,這將觸發重新編譯和重啟。
  通過DI模塊,擴展包能提供從類型到具體實現的綁定,即提供服務和功能。

Services和Contributions

  本節我們將描述一個擴展包如何使用另一個擴展包中的服務,以及它們如何給Theia提供功能。

依賴注入(DI)

  Theia使用DI框架 Inversify.js來連接不同的組件。
  DI在創建時注入組件(作為構造函數的參數),從而將組件從依賴項中徹底解耦出來。DI容器根據你在啟動時通過所謂的容器模塊提供的配置項來進行創建。
  例如, Navigator小部件需要訪問 FileSystem用來在樹形結構中顯示文件夾和文件,但是 FileSystem接口的實現對 Navigator來說並不重要,它可以大膽地假設與 FileSystem接口一致的對象已經准備好並可以使用了。在Theia中, FileSystem的實現僅僅是一個發送JSON-RPC消息到后端的代理,它需要一個特殊的配置和處理程序。Navigator不需要關心這些細節,因為它將獲取一個被注入的 FileSystem的實例。
  此外,這種結構的解耦和使用,允許擴展包在需要時能提供非常具體的功能實現,例如這里提到的 FileSystem,而不需要接觸到 FileSystem接口的任何實現。
  DI在Theia中是一個非常重要的部分,因此,我們強烈建議先學習 Inversify.js的基礎知識。

Services

  Service只是一個提供給其它組件使用的綁定。例如,一個擴展包可以公開 SelectionService,這樣其它擴展包就可以獲得一個注入的實例並使用它。

Contribution-Points

  如果一個擴展包想要提供一個鈎子,由其它擴展包來實現其中的功能,那么它應該定義一個 contribution-point。一個 contribution-point就是一個可以被其它擴展包實現的接口。擴展包可以在需要時將它委托給其它部分。
  例如, OpenerService定義了一個contribution point,允許其它擴展包注冊 OpenHandler。你可以查看 這里的代碼。
  Theia已經提供了大量的contribution points列表,查看已存在的contribution points的一個好方法是查找 bindContributionProvider的引用。

Contribution Providers

  一個contribution provider基本上是contributions的容器,其中的contributions是綁定類型的實例。
  這是非常通用的。
  要將類型綁定到contribution provider,你可以這樣做:
(來自messageing-module.ts)
export const messagingModule = new ContainerModule(bind => {
    bind<BackendApplicationContribution>(BackendApplicationContribution).to(MessagingContribution);
    bindContributionProvider(bind, ConnectionHandler)
});
  最后一行將一個ContributionProvider綁定到一個包含所有ConnectionHandler綁定實例的對象上。
  像這樣來使用:
(來自messageing-module.ts)
constructor( @inject(ContributionProvider) @named(ConnectionHandler) protected readonly handlers: ContributionProvider<ConnectionHandler>) {
    }

  這里我們注入了一個ContributionProvider,它的name值是ConnectionHandler,這個值之前是由bindContributionProvider綁定的。

  這使得任何人都可以綁定ConnectionHandler,現在,當messageingModule啟動時,所有的ConnectionHandlers都將被初始化。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM