上一篇: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都将被初始化。
 
 

Theia架构的更多相关文章

  1. 使用Theia——构建你自己的IDE

    上一篇:Theia架构 构建你自己的IDE 本指南将教你如何构建你自己的Theia应用. 必要条件 你需要安装node 10版本(译者:事实上最新的node稳定版即可): curl -o- https ...

  2. Theia——云端和桌面版的IDE

    Theia是一个利用最新的web技术开发的支持云端和桌面运行的类似IDE的产品,它是一个可扩展的平台,并且全面支持多语言. 目标 建立一个可搭建类似IDE产品的平台 为终端用户提供完整的多语言IDE( ...

  3. 使用Theia——创建扩展包

    上一篇:使用Theia——构建你自己的IDE 创建Theia扩展包 本例中,我们将添加一个菜单项“Say hello”用来显示一个通知“Hello world!”.本文将指导你完成所有必要的步骤. T ...

  4. 使用Theia——创建插件

    上一篇:使用Theia——创建扩展包 创建Theia插件 下面我们来看看如何创建Theia插件.作为示例,我们将注册一个Hello World命令,该命令显示一个“Hello World”通知.本文将 ...

  5. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  6. node服务的监控预警系统架构

    需求背景 目前node端的服务逐渐成熟,在不少公司内部也开始承担业务处理或者视图渲染工作.不同于个人开发的简单服务器,企业级的node服务要求更为苛刻: 高稳定性.高可靠性.鲁棒性以及直观的监控和报警 ...

  7. 如何一步一步用DDD设计一个电商网站(二)—— 项目架构

    阅读目录 前言 六边形架构 终于开始建项目了 DDD中的3个臭皮匠 CQRS(Command Query Responsibility Segregation) 结语 一.前言 上一篇我们讲了DDD的 ...

  8. 浅谈 jQuery 核心架构设计

    jQuery对于大家而言并不陌生,因此关于它是什么以及它的作用,在这里我就不多言了,而本篇文章的目的是想通过对源码简单的分析来讨论 jQuery 的核心架构设计,以及jQuery 是如何利用javas ...

  9. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

随机推荐

  1. HDFS 通信接口

  2. 初识 Knative: 跨平台的 Serverless 编排框架

    Knative 是什么 Knative 是 Google 在 2018 的 Google Cloud Next 大会上发布的一款基于 Kubernetes 的 Serverless 框架.Knativ ...

  3. 怎么清除火狐浏览器的cookie?

    火狐浏览器清除Cookie方法/步骤 1.打开火狐浏览器.并在火狐浏览器工具栏找到并单击“工具”下的“选项”. 2.在打开的“火狐浏览器选项”程序窗口中,找到工具栏中的“隐私”并单击,在隐私选项下找到 ...

  4. uni-app获取dom元素到顶部的距离以及操作dom元素的一些样式

    一. 1.首先有一个元素 <view class="activity" ref="btn"></view> 2.确认指针指向 this. ...

  5. autocomplete="off" inpu属性

    input 的属性autocomplete 默认为on 其含义代表是否让浏览器自动记录之前输入的值 很多时候,需要对客户的资料进行保密,防止浏览器软件或者恶意插件获取到 可以在input中加入auto ...

  6. Ext--Layout(布局)

    EXT中的布局,常用的有border.column.fit.form.tabel这几种. Fit布局,子元素将自动填满整个父容器(对元素设置宽度无效),如果容器组件中有多个子元素,则只会显示第一个子元 ...

  7. Vue打包后放到服务器出现Loading chunk {n} failed 错误

    导航栏点击切换时 会出现Loading chunk {n} failed  ,刷新之后便不会出现.而且n在最新的build的文件中,n没有存在 偶然一次发现,项目更新迭代开发时上传测试环境后就会出现, ...

  8. Python--day62--Django安装,配置,web请求流程,views.py总结

    1,安装Django 2,创建Django项目: 3,配置Django项目 1.settinngs.py文件 1.templates文件夹的位置 2.静态文件 1,STATIC_URL   ----- ...

  9. Python--day24--多继承

    如果本生没有func方法的话就调用距离自己最近的基类的方法 钻石继承: 查找方法的顺序:如下例的找func方法(广度优先) 例1: 例2: 漏斗继承: 小乌龟继承问题:(最顶端的节点F是最后查找的) ...

  10. Vue 父组件与子组件的传值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...