创建 Theia 插件
让我们创建我们的第一个 Theia 插件。例如,我们将注册一个显示通知“Hello world!”的命令 Hello World。本文将指导您完成所有必要的步骤。
Theia架构
插件与扩展
Theia 是一个可扩展的 IDE。您可能已经听说过扩展是一种自定义 IDE 的方式。插件是最近添加到 Theia 中的一种新的可扩展性模型。以下是插件与扩展之间的主要区别。
插件
优点:
- 代码隔离:作为独立进程运行的插件代码,不能阻塞Theia核心进程。
- 可以在运行时加载。无需重新编译 Theia 的完整 IDE。
- 减少编译时间
- 自成一体,一个插件可以打包成一个文件直接加载。无需从 npmjs 等中获取依赖项。
- 简单的 API
- 无需学习 inversify 或任何框架。
- 单一入口点,通过代码自动完成,就能查看到可能的调用(后半截不会翻译,原文为:single entry point, with code completion to see possible calls with associated JsDoc.)。
- 由于 API 向后兼容,因此可以轻松地从一个 theia 版本升级到另一个版本。
缺点:
- 需要坚持这个预定义的 API。如果没有通过 API 提供贡献点,则无法调整某些内容。请注意,可以扩展当前 API 以支持更多内容;-)
设计
Theia 应用程序由一个核心组成,该核心提供一组小部件、命令、处理程序等。Theia 定义了一个运行时 API,允许插件自定义 IDE,从而为应用提供各种功能。
在 Theia 中,插件可以通过名为 theia 的对象访问 API,该对象在所有插件中都可用。有关 API 的更多详细信息在这里:https://github.com/eclipse-theia/theia/blob/master/packages/plugin/README.md。
插件有两种性质:
后端插件:如果你熟悉 VS Code 扩展,他们非常接近。插件的代码在服务器端的自己的进程中运行。API 将在用户的浏览器/UI 上发送一些操作并被调用。所有回调都在服务器端的专用进程上执行。
前端插件:在这种情况下,回调在 UI/浏览器 上的工作线程中执行。这些插件只能使用"browser compliant" 模块。例如,打开或写入文件是不可能的,因为插件的所有代码都在浏览器端运行。但是如果你真的想在客户端做一些事情,避免网络操作,前端插件就会很有用。
先决条件
有一个正在运行的 Theia 实例 (v0.3.12+) 。获取 Theia 的方法可以从 https://github.com/eclipse-theia/theia#getting-started 获得。
项目布局
我们将创建一个新项目,为此我们将创建一个名为 theia-hello-world-plugin 的文件夹,其中包含项目的源代码。
这个新文件夹可以在任何目录中创建,它独立于 Theia 源代码。
为了简化项目配置,可以安装Yeoman 代码生成器(https://www.npmjs.com/package/@theia/generator-plugin),来为项目搭建初始框架。
可以使用以下命令安装和执行生成器。请注意,可以从正在运行的 Theia 实例中的新终端输入这些命令,也可以自己打开独立的终端应用执行。
npm install -g yo @theia/generator-plugin mkdir theia-hello-world-plugin cd theia-hello-world-plugin yo @theia/plugin
在前面的命令中:
npm install -g yo @theia/generator-plugin 命令全局安装 Theia 生成器。
yo @theia/plugin 正在调用 yeoman 生成器,用模板生成Theia 的插件。
这是生成器运行的动画截图。
为每个问题选择默认值。
这一步完成后,在 theia-hello-world-plugin 文件夹中会生成一个已经使用相关源代码构建的插件。
实现插件
现在让我们看看生成的代码。
{ "name": "theia-hello-world-plugin", "publisher": "theia", "keywords": [ "theia-plugin" ], "version": "0.0.1", "files": [ "src" ], "devDependencies": { "@theia/plugin": "latest", <-- 1. Theia API dependency "rimraf": "^2.6.2", "typescript": "^2.9.2" }, "scripts": { "prepare": "yarn run clean && yarn run build", "clean": "rimraf lib", "build": "tsc" }, "engines": { "theiaPlugin": "latest" <-- 2. this plug-in requires Theia runtime }, "theiaPlugin": { "backend": "lib/theia-hello-world-plugin-backend-plugin.js" 3. <-- entrypoint } }
这个 package.json 文件中有三个重要的部分
首先,在 devDependencies 中,存在对 @theia/plugin 的依赖。 该包将在插件代码中用于调用 Theia API(如添加新命令和显示新信息消息)。
其次,引擎部分包含 theiaPlugin。 它允许将此节点包标记为可在特定版本的 Theia 之上运行。
第三,theiaPlugin 部分包含插件的入口点。 对于后端插件,它是backend键,其值为插件的 javascript 路径的路径。
让我们看一下已经生成的单个源代码文件。 这个文件的路径是 src/theia-hello-world-plugin-backend-plugin.ts。 它包含 TypeScript 代码。
import * as theia from '@theia/plugin'; export function start() { const informationMessageTestCommand = { id: 'hello-world-example-generated', label: "Hello World" }; theia.commands.registerCommand(informationMessageTestCommand, (...args: any[]) => { theia.window.showInformationMessage('Hello World!'); }); } export function stop() { }
如您所见,只需几行代码即可注册命令并显示通知消息。
第一个重要的行是 API 的导入。 import * as theia from '@theia/plugin'; 使得theia 对象可以使用 Theia 插件的所有 API。
在代码中,有两个方法分别是start()和stop()
start() 方法在加载插件时被调用。 在此方法中,有一个动作:注册 hello world 命令和一个回调:将 Hello World 显示为信息消息。 命令对象有一个 ID 和一个标签,它们将显示在命令面板中。
有一个空的 stop() 方法可用于在插件停止时执行某些操作。 此方法是可选的,如果为空则可以删除。
执行插件
现在我们想看看插件的实际效果。 为此,Theia 中有一种称为hosted mode的模式。 使用这种模式时,我们可以在一个 Theia 实例中开发插件,然后在另一个 Theia 实例中部署插件。 因此,生成插件并对其进行测试非常容易。
首先,以web方式运行一个theia实例,可参考:https://www.cnblogs.com/theia-ide/p/16493715.html 。(注意:如果没有使用web模式,直接使用Blueprint作为host的话,运行后会提示出错:error Couldn't find a package.json file in "/home/" ,这个提示的路径并不是我上面选择的路径,看起来是theia的bug。)
然后,打开 command palette(例如按 F1 键)并搜索Hosted mode:Select Path,并选择此命令。
在弹出窗口中选择插件所在的文件夹(包含 package.json 文件)。
再次打开 command palette(例如按 F1 键)并搜索Hosted mode:Start Instance,并选择此命令:
它将在端口 3030 上生成一个新的 theia 实例。将打开一个新选项卡,并且您有一个以开发模式运行的新实例(在状态栏中,您可以看到)
在 Development Host 实例中,打开命令面板(F1 键),然后搜索 Hello World 命令。
选择它,您将在屏幕上看到通知 Hello World。
对于host模式的理解,其实就是我们可以用theia来开发插件,并且直接运行启动一个新的theia实例。两个theia的实例,一个宿主,用于开发,一个子实例(上例是监听3030端口),用于测试插件。
开发插件
如前所述,Theia API 是通过 TypeScript 提供的,那么开发时就有代码补全和 JsDoc 可用。
更新插件
假设您要将信息消息从 Hello World 更改为 Hello Theia。 让我们进入托管插件:运行实例(状态栏),编辑 TypeScript 文件 src/theia-hello-world-plugin-backend-plugin.ts 并执行以下更改:
替换: theia.window.showInformationMessage('Hello World!');
为:theia.window.showInformationMessage('Hello Theia!');
从插件的根文件夹运行命令 yarn build,以便重新编译源代码。 然后您只需刷新development mode实例的选项卡,插件将再次重新加载。
注意:您也可以使用监视模式。
插件API
浏览插件的 typedoc(https://eclipse-theia.github.io/theia/docs/next/modules/plugin.html)
VS 代码实现
Theia 正在提供 VS Code API。 检查以下链接以获取当前进展,比较 Theia 与 VS Code API:(https://eclipse-theia.github.io/vscode-theia-comparator/status.html)