Eclipse Theia 示例插件(Sample Plugins)完全指南:编写、打包与在 Theia 中验证 VS Code 扩展
Eclipse Theia 示例插件Sample Plugins完全指南编写、打包与在 Theia 中验证 VS Code 扩展【免费下载链接】theiaEclipse Theia is a cloud desktop IDE framework implemented in TypeScript.项目地址: https://gitcode.com/gh_mirrors/th/theiasample-plugins/是 Eclipse Theia 仓库中一组最小化的 VS Code 扩展集合用于在真实 Theia 例程应用browser / electron 示例中演练插件运行时plugin runtime。本文以 sample-plugins/README.md 为主干结合每个插件的package.json与extension.js源码完整讲解插件的目录结构、两种安装验证方式复制到plugins目录 / 从 Extensions 视图安装.vsix、以及各插件所演示的运行时变体CJS、浏览器限定、ESM、headless、LM 工具等。读完本文你将能够独立编写一个最小 VS Code 插件、将其打包并在 Theia 中安装、激活与验证。一、Sample Plugins 是什么按仓库文档 sample-plugins/README.md 的说明A small collection of minimal VS Code extensions used by Theia to exercise the plugin runtime.这是一批刻意保持最小的 VS Code 扩展其唯一目的就是让 Theia 的插件运行时plugin runtime有练习对象。每个插件都位于sample-namespace/命名空间下并注册一条简单的Hello from plugin-name命令其中一部分插件还专门演示特定的运行时变体browser-only、ESM 等。从目录布局看sample-plugins/sample-namespace 下目前包含 7 个插件插件目录演示重点plugin-a最经典的 CommonJS 插件模板plugin-b与 plugin-a 结构一致的第二个 CJS 插件plugin-browser仅在浏览器端browser worker运行plugin-esm以 ESMtype: module方式编写的插件plugin-esm-mjs以.mjs扩展名导出的 ESM 插件plugin-gotdheadless 插件后端无 UI 运行并使用theia/api-provider-sampleplugin-lm-tools通过vscode.lm.registerTool注册语言模型LM工具二、最小的插件长什么样以 plugin-a 为例任何一个 Hello 插件都由两个文件构成核心逻辑描述插件元数据的package.json以及实现激活逻辑的extension.js。2.1 package.json清单文件以 sample-plugins/sample-namespace/plugin-a/package.json 为例{ private: true, name: plugin-a, version: 1.75.0, main: extension.js, license: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0, publisher: sample-namespace, engines: { vscode: ^1.125.0 }, activationEvents: [ onCommand:plugin-a.hello ], scripts: { build: vsce package --no-dependencies }, contributes: { commands: [ { command: plugin-a.hello, title: Hello from plugin-a } ] } }几个关键字段的说明main插件入口文件Theia 插件宿主会加载该文件并调用其导出的activateengines.vscode声明兼容的 VS Code API 版本此处为^1.125.0Theia 的插件兼容层以此为基准activationEvents声明激活事件。这里使用onCommand:plugin-a.hello意味着只有当用户真正执行plugin-a.hello命令时插件才会被激活属于懒加载lazy activation模式contributes.commands把命令 ID 与命令面板中显示的中文/英文标题绑定起来标题正是Hello from plugin-ascripts.buildvsce package --no-dependencies用于把插件目录打成.vsix安装包--no-dependencies表示不打包 npm 依赖publishersample-namespace与目录名sample-namespace/保持一致这也是.vsix发布者标识private: true避免该包被意外发布到 npm registry。2.2 extension.js激活逻辑plugin-a/extension.js 的完整实现只有几行const vscode require(vscode); exports.activate function (context) { context.subscriptions.push(vscode.commands.registerCommand(plugin-a.hello, () { vscode.window.showInformationMessage(Hello from plugin-a!); })); }这里遵循 VS Code 扩展的标准生命周期约定activate(context)在满足activationEvents条件时被调用vscode.commands.registerCommand(plugin-a.hello, ...)注册命令回调返回值通过context.subscriptions.push(...)登记插件被禁用/卸载时 Theia 会自动执行对应的dispose()释放资源。plugin-b 与 plugin-a 结构完全一致仅命令 ID、标题与提示消息替换为plugin-b.hello/Hello from plugin-b!可作为同一目录下多个插件并存时互相印证的最小样例。三、运行时变体每个插件演示什么除了最基础的 CJS 模板sample 集合还覆盖了 Theia 插件运行时支持的多种形态。3.1 浏览器限定插件plugin-browserplugin-browser/package.json 的关键在于它没有main字段而是使用browser: ./extension.jsplugin-browser/extension.js 在激活时打印日志exports.activate function (context) { console.log([plugin-browser] activated in browser worker!); const disposable vscode.commands.registerCommand(plugin-browser.hello, function () { vscode.window.showInformationMessage(Hello from a browser-only extension!); }); context.subscriptions.push(disposable); };browser字段声明该插件的入口只面向浏览器环境运行Theia 会在前端browser worker中执行它同时导出的deactivate钩子也被显式声明此处为空实现。这类插件对应 Theia 文档中 browser-only 的插件形态适合演示前端插件不需要 Node.js 能力即可工作的场景。3.2 ESM 插件plugin-esm 与 plugin-esm-mjsplugin-esm通过type: module把整个包声明为 ESMtype: module, main: extension.js其 extension.js 使用import/export语法import * as vscode from vscode; export function activate(context) { context.subscriptions.push(vscode.commands.registerCommand(plugin-esm.hello, () { vscode.window.showInformationMessage(Hello from plugin-esm (ESM)!); })); }plugin-esm-mjs则直接以.mjs扩展名作为main入口main: extension.mjs其 extension.mjs 采用命名导入的写法import { commands, window } from vscode; export function activate(context) { context.subscriptions.push(commands.registerCommand(plugin-esm-mjs.hello, () { window.showInformationMessage(Hello from plugin-esm-mjs (.mjs)!); })); }从源码结构看这两个插件用于验证 Theia 插件宿主对 ESM 入口无论是包级type: module还是文件级.mjs的加载支持。3.3 headless 插件plugin-gotdplugin-gotdGotDGreetings of the Day演示的是headless 插件——即在后端进程无 UI 的 headless 环境中运行、不依赖任何界面组件的插件形态。其 package.json 中值得关注的是main: extension, activationEvents: [*], theiaPlugin: { headless: headless }, headless: { activationEvents: [*], contributes: {} }main: extension默认入口后端/前端共用对应的 extension.js 会读取vscode.version、vscode.env.shell并通过vscode.extensions.getExtension(unpublished.plugin-gotd)查询自身extensionKind与安装路径用于诊断插件运行环境theiaPlugin: { headless: headless }Theia 专有扩展点声明 headless 入口指向headless即headless.jsheadless.js 引用theia/api-provider-sample包通过gotd.greeting.createGreeter()创建问候器监听onGreetingKindsChanged并依次把问候类型切换为DIRECT、QUIRKY、SNARKY把问候语打印到日志中。这个插件同时演示了两点一是 Theia 对 headless 插件的支持examples/api-provider-sample 提供了对应 API 的服务端实现二是插件运行时对theia/api-provider-sample这类API 提供者包的依赖能力。3.4 LM 工具插件plugin-lm-toolsplugin-lm-tools演示的是最新形态的Language Model Tools——通过 VS Code API 把函数暴露给 AI 语言模型调用。清单部分在 package.json 的contributes.languageModelTools中声明了三个工具sample-getCurrentTime无参数返回 ISO 格式的当前时间sample-calculateSum接收numbers数组返回求和结果inputSchema定义了{type:object,properties:{numbers:{type:array,items:{type:number}},required:[numbers]}}sample-getSystemInfo无参数返回平台、Node 版本与运行时长。实现部分在 extension.js 中使用vscode.lm.registerTool(name, handler)注册并通过context.subscriptions.push(...)登记生命周期const timeTool vscode.lm.registerTool(sample-getCurrentTime, { invoke(_options, _token) { const now new Date().toISOString(); return { content: [new vscode.LanguageModelTextPart(now)] }; }, prepareInvocation(_options, _token) { return { invocationMessage: Getting current time... }; } });其中sample-calculateSum的invoke还会检查token.isCancellationRequested并逐个数字延迟 2 秒求和用于演示长耗时工具的取消cancellation机制sample-getSystemInfo则演示返回LanguageModelTextPartLanguageModelDataPart.json的混合内容。四、在 Theia 示例应用中测试示例插件sample-plugins/README.md 给出了两种安装验证路径下面逐一展开。方法 A把插件文件夹复制进已部署的 plugins 目录这是最快、最直接的验证方式不需要打包1.可选先下载 VS Code 内置扩展让示例环境更完整npm run download:plugins该命令在根目录 package.json 中定义为theia download:plugins由 dev-packages 下的 Theia CLI 实现。把插件目录整体复制到部署好的plugins目录下cp -r sample-plugins/sample-namespace/plugin-name plugins/其中plugin-name替换为目标插件名如plugin-a、plugin-browser、plugin-lm-tools。plugins目录的位置由示例应用的配置决定在 examples/browser/package.json 中可以看到theiaPluginsDir: ../../plugins即浏览器示例从仓库根目录的plugins/目录加载插件electron 示例的配置与之类似。启动示例应用例如浏览器版npm run start:browser在 examples/browser 内部start脚本实际执行的是theia start --pluginslocal-dir:../../plugins --ovsx-router-config../ovsx-router-config.json见 examples/browser/package.json即通过local-dir:前缀把../../plugins指定为本地插件目录。打开命令面板CtrlShiftP / CmdShiftP运行Hello from plugin-name。此时由于activationEvents中声明了onCommand:id插件会在命令执行时被激活右下角弹出Hello from plugin-name!通知即表示验证成功。提示此方式依赖plugins目录已被示例应用加载。若在示例应用运行时新增插件目录通常需要重启应用使其被扫描到。方法 B打包成 .vsix 并从 Extensions 视图安装这种方式更接近真实用户安装插件的路径适合验证打包产物在插件目录内执行打包cd sample-plugins/sample-namespace/plugin-name npm run build该脚本即vsce package --no-dependencies会在插件源文件旁生成plugin-name-version.vsix例如plugin-a-1.75.0.vsix。--no-dependencies表示不把 npm 依赖打进去——由于这些示例插件都只依赖vscodeAPI由 Theia 提供因此无需打包依赖。启动 Theianpm run start:browser打开 Extensions 视图左侧扩展图标。点击 Extensions 视图右上角的...菜单选择Install from VSIX...然后选中上一步生成的.vsix文件。打开命令面板运行Hello from plugin-name验证插件已生效。两种方式如何选择维度方法 A复制目录方法 B.vsix 安装是否打包否直接拷贝源码目录是需先npm run build适用场景开发迭代期快速验证验证打包产物、模拟用户安装流程产物plugins/下的插件目录plugin-name-version.vsix触发激活命令面板执行命令同上但需先经 Extensions 视图安装五、验证要点与常见排查思路命令找不到确认插件目录确实位于plugins/下或.vsix已成功安装且contributes.commands中的commandID 与activationEvents中的onCommand:ID 完全一致例如plugin-a.hello激活未触发检查activationEvents。若使用onCommand:必须真正执行该命令才会激活plugin-gotd与plugin-lm-tools分别使用*与onStartupFinished属于启动即激活的不同策略插件类型不符browser-only 插件plugin-browser应能在纯浏览器示例中运行涉及 Node 能力的插件请确认运行环境满足要求headless 插件plugin-gotd的日志输出在后台进程可从后端控制台查看[GOTD-BE]/[GOTD]前缀的日志见 headless.jsLM 工具plugin-lm-tools注册的三个工具需在具备 AI/LM 能力的 Theia 环境如 ai-chat 相关扩展中才会被调用控制台会打印[plugin-lm-tools]前缀的调用日志。六、总结sample-plugins/为 Theia 插件开发者提供了一套从零到验证的最小闭环每种插件形态CJS、browser-only、ESM/.mjs、headless、LM tools都配有可直接运行的package.json与extension.js而 sample-plugins/README.md 给出的两种安装方式覆盖了开发调试复制目录与真实分发.vsix Extensions 视图两个阶段。以此为基础你可以把任意一个 sample 插件复制出来改名改造快速搭建属于自己的 Theia 插件原型。【免费下载链接】theiaEclipse Theia is a cloud desktop IDE framework implemented in TypeScript.项目地址: https://gitcode.com/gh_mirrors/th/theia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考