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 http://inversify.io/ 来连接不同的组件.
DI 在创建时注入组件 (作为构造函数的参数), 从而将组件从依赖项中彻底解耦出来. DI 容器根据你在启动时通过所谓的容器模块提供的配置项来进行创建.
例如, Navigator 小部件需要访问 FileSystem 用来在树形结构中显示文件夹和文件, 但是 FileSystem 接口的实现对 Navigator 来说并不重要, 它可以大胆地假设与 FileSystem 接口一致的对象已经准备好并可以使用了. 在 Theia 中, FileSystem 的实现仅仅是一个发送 JSON-RPC 消息到后端的代理, 它需要一个特殊的配置和处理程序. Navigator 不需要关心这些细节, 因为它将获取一个被注入的 FileSystem 的实例.
此外, 这种结构的解耦和使用, 允许扩展包在需要时能提供非常具体的功能实现, 例如这里提到的 FileSystem, 而不需要接触到 FileSystem 接口的任何实现.
DI 在 Theia 中是一个非常重要的部分, 因此, 我们强烈建议先学习 Inversify.JS http://inversify.io/ 的基础知识.
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 都将被初始化.
来源: https://www.cnblogs.com/jaxu/p/12131803.html