zoukankan      html  css  js  c++  java
  • 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都将被初始化。
     
     
  • 相关阅读:
    poj 2488 DFS
    畅通工程 并查集模版
    KMP 模板
    poj 1426 DFS
    poj 2528 线段数
    poj 3468 线段数 修改区间(点)
    CVPR2012文章阅读(2)A Unified Approach to Salient Object Detection via Low Rank Matrix Recovery
    如何制定目标
    Saliency Map 最新综述
    计算机视觉模式识别重要会议杂志
  • 原文地址:https://www.cnblogs.com/jaxu/p/12131803.html
Copyright © 2011-2022 走看看