ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开发一个自己的VSCode插件:从extension.ts到vsce发布,接入TaoToken统一Key

开发一个自己的VSCode插件:从extension.ts到vsce发布,接入TaoToken统一Key 1. 从零写一个 VSCode 插件为什么我建议顺手把模型调用也接进去VSCode 插件开发这件事说难不难说简单也容易踩坑。它本质上是往编辑器里塞一段 Node.js 代码通过package.json声明「我能干什么」再通过extension.ts里的activate函数告诉 VSCode「什么时候把我叫起来」。你不需要懂 Electron 底层也不用改 VSCode 源码只要会写 TypeScript就能做出一个能选中代码、右键转换、快捷键触发的实用工具。但真正让插件「有灵魂」的是它能调用外部能力。比如你写一个命名转换插件选中user_name想转成userName本地正则当然能做可如果你想让它理解语义、按团队规范重命名、甚至生成一段注释那就得调用大模型。问题来了每接一个模型就配一套 Key、改一次环境变量插件里散落一堆密钥既难维护又不安全。这篇就按「从 extension.ts 到 vsce 发布」的完整链路走一遍并且演示怎么在插件里通过统一 Key / API 通道调用模型。你跟着做能拿到一个可 F5 调试、可vsce package打包、可发布到市场的插件骨架。适合已经会一点 TypeScript、想把自己重复劳动工具化的开发者。下面所有配置我都实测跑过命令可以直接复制。2. 前置准备环境、脚手架与 TaoToken 统一 Key2.1 先把 Node 和脚手架装好插件开发依赖 Node.js 和 Git建议 Node 18 以上。装完执行npm install -g yo generator-code vscode/vscegenerator-code是官方脚手架vscode/vsce是后面打包发布用的命令行工具。装好后运行yo code选择New Extension (TypeScript)按提示填插件名比如name-transform。脚手架会生成一整套目录核心就两个文件package.json和src/extension.ts。2.2 为什么用统一 Key 而不是每个模型一套插件里调用模型最怕两件事一是密钥硬编码进代码打包发布后等于公开二是换模型要改代码。统一 Key 的思路是插件只认一个 API 地址和一个 Key具体路由到哪个模型由服务端决定。这样插件代码干净密钥放配置里换模型不动插件。TaoToken 就提供这种统一通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。你需要在控制台创建一个 Key后面插件通过Authorization: Bearer 你的Key调用。Key 的创建入口在控制台的 API Keys 页面接入细节可以对照官方文档模型对话能力可以在模型对话页先试跑通再写进插件。注意Key 不要写进extension.ts也不要提交到 Git。正确做法是让用户在 VSCode 设置里填插件通过vscode.workspace.getConfiguration读取。3. 可复制的 package.json 与 extension.ts 骨架3.1 package.json声明命令、菜单、快捷键和配置项package.json是插件的「说明书」VSCode 靠它知道你的插件提供哪些命令、在哪儿显示、有哪些设置。下面这份可以直接改名字用{ name: name-transform, displayName: Name Transform, description: 选中代码一键转换命名风格并可通过统一 Key 调用模型生成规范命名, version: 0.0.1, engines: { vscode: ^1.85.0 }, categories: [Other], activationEvents: [], main: ./out/extension.js, contributes: { commands: [ { command: nameTransform.toCamel, title: 转换为小驼峰 }, { command: nameTransform.toSnake, title: 转换为下划线 }, { command: nameTransform.aiRename, title: AI 智能重命名 } ], menus: { editor/context: [ { command: nameTransform.toCamel, group: navigation1 }, { command: nameTransform.toSnake, group: navigation2 }, { command: nameTransform.aiRename, group: navigation3 } ] }, keybindings: [ { command: nameTransform.toCamel, key: ctrlaltc, mac: cmdaltc, when: editorTextFocus } ], configuration: { title: Name Transform, properties: { nameTransform.apiKey: { type: string, default: , description: TaoToken 统一 Key用于 AI 重命名 }, nameTransform.apiBase: { type: string, default: https://taotoken.net/api, description: 统一 API 地址 }, nameTransform.model: { type: string, default: claude-sonnet-4-5, description: 调用的模型名称 } } } }, scripts: { vscode:prepublish: npm run compile, compile: tsc -p ./, watch: tsc -watch -p ./ }, devDependencies: { types/vscode: ^1.85.0, types/node: ^20.0.0, typescript: ^5.4.0 } }几个关键点activationEvents在新版本里可以留空VSCode 会根据contributes.commands自动推断激活时机menus.editor/context让命令出现在右键菜单keybindings绑定快捷键configuration暴露三个设置项用户可以在设置里填 Key、改地址、换模型。3.2 extension.ts激活入口与命令注册extension.ts是入口activate在插件被激活时执行deactivate在卸载时清理。下面这份骨架包含本地转换和 AI 调用两部分import * as vscode from vscode; const COMMANDS { toCamel: nameTransform.toCamel, toSnake: nameTransform.toSnake, aiRename: nameTransform.aiRename }; export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand(COMMANDS.toCamel, () transformLocal(camel)), vscode.commands.registerCommand(COMMANDS.toSnake, () transformLocal(snake)), vscode.commands.registerCommand(COMMANDS.aiRename, () aiRename()) ); } function getSelectedText(): { editor: vscode.TextEditor; text: string } | undefined { const editor vscode.window.activeTextEditor; if (!editor) return undefined; const text editor.document.getText(editor.selection); if (!text) { vscode.window.showWarningMessage(请先选中一段文本); return undefined; } return { editor, text }; } function transformLocal(style: camel | snake) { const sel getSelectedText(); if (!sel) return; const words sel.text.split(/[_\-\s]/).filter(Boolean); const result style camel ? words.map((w, i) i 0 ? w.toLowerCase() : w[0].toUpperCase() w.slice(1).toLowerCase()).join() : words.map(w w.toLowerCase()).join(_); sel.editor.edit(e e.replace(sel.editor.selection, result)); } async function aiRename() { const sel getSelectedText(); if (!sel) return; const cfg vscode.workspace.getConfiguration(nameTransform); const apiKey cfg.getstring(apiKey); const apiBase cfg.getstring(apiBase); const model cfg.getstring(model); if (!apiKey) { vscode.window.showErrorMessage(请先在设置中配置 nameTransform.apiKey); return; } const prompt 请把下面的标识符按团队规范重命名只返回新名字不要解释\n${sel.text}; try { const res await fetch(${apiBase}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey} }, body: JSON.stringify({ model, messages: [{ role: user, content: prompt }], temperature: 0.2 }) }); if (!res.ok) { throw new Error(HTTP ${res.status}: ${await res.text()}); } const data: any await res.json(); const newName data.choices?.[0]?.message?.content?.trim(); if (!newName) throw new Error(模型返回为空); sel.editor.edit(e e.replace(sel.editor.selection, newName)); vscode.window.showInformationMessage(已重命名为 ${newName}); } catch (err: any) { vscode.window.showErrorMessage(AI 重命名失败${err.message}); } } export function deactivate() {}这里用 Node 18 自带的fetch不用额外装 axios。aiRename从配置读 Key 和地址拼一个标准的 chat completions 请求把选中文本作为 prompt 发出去拿到结果后替换选区。整个流程没有硬编码密钥用户换模型只改设置。4. 本地 F5 调试与 vsce package 验证4.1 F5 启动扩展开发宿主先开一个终端跑编译监听npm run watch然后在 VSCode 左侧点「运行和调试」图标按 F5会弹出一个新窗口标题带「扩展开发宿主」。这个新窗口里你的插件是生效的。打开任意文件选中一段user_name按CtrlAltC应该变成userName右键菜单里也能看到三个命令。注意调试前一定要先跑npm run watch否则改了extension.ts不重新编译调试窗口里命令不生效这是新手最常见的坑。4.2 配置 Key 并验证 AI 调用在调试窗口里按Ctrl,打开设置搜索nameTransform把apiKey填成你在控制台创建的 KeyapiBase保持https://taotoken.net/apimodel填你要用的模型名。然后选中一段命名混乱的代码右键选「AI 智能重命名」如果配置正确选区会被替换成模型返回的新名字右下角弹出提示。如果这一步想先单独验证 Key 和模型是否通可以先用模型对话页发一条消息确认通道正常再回到插件里调。长期做编码类插件、需要频繁调用模型的可以了解 Coding Plan它更适合持续性的编码场景。4.3 vsce package 打包验证功能没问题后先编译再打包npm run compile vsce package成功的话会在根目录生成name-transform-0.0.1.vsix。这个文件可以直接在 VSCode 里「从 VSIX 安装」验证也可以上传到市场。打包前记得检查.vscodeignore把src、node_modules里不必要的东西排除否则包会很大。如果vsce package报缺少repository字段在package.json里补一个repository地址即可。5. 本篇常见错误排查5.1 命令不生效、右键菜单没有八成是没跑npm run watch或者package.json里contributes.commands的command值和extension.ts里registerCommand的字符串不一致。两者必须完全对应大小写都不能错。改完package.json要重启调试窗口因为它只在激活时读一次。5.2 AI 调用返回 401 或 404401 一般是 Key 没填、填错或者Authorization头格式不对正确格式是Bearer Key中间一个空格。404 多半是apiBase拼错了注意不要重复拼/v1代码里已经带了/v1/chat/completions所以apiBase只写到https://taotoken.net/api。如果返回模型不存在检查model字段是不是当前通道支持的模型名。5.3 打包报错或安装后不工作vsce package常见报错是Missing publisher在package.json里加publisher: 你的发布者ID。安装后不工作先看main字段指向的./out/extension.js是否真的存在也就是有没有先npm run compile。另外engines.vscode版本别写太高否则低版本 VSCode 装不上。6. 把 Key 管好把插件发出去走到这里你已经有了一个能调试、能打包、能调用模型的插件。最后强调两件事一是 Key 永远走设置项不要写死二是发布前用vsce package生成的 vsix 在干净环境里再装一次确认没有依赖本地路径。发布到市场需要微软账号和发布者 IDvsce publish前先vsce login填个人访问令牌。如果你只是想团队内部用直接把 vsix 发给同事安装就够了不必走市场审核。插件里调用模型的 Key 管理、接入文档和模型列表都可以在 https://taotoken.net/api 对应的控制台和文档里找到先把通道跑通再把它封装成你顺手的小工具这才是插件开发最舒服的节奏。
返回列表