VS Code: создание расширений
Расширение VS Code — Node.js модуль с TypeScript API, добавляющий в редактор команды, языковые возможности, UI-элементы или интеграцию с внешними сервисами.
Зачем нужно
Если существующие расширения не покрывают конкретную задачу — можно написать своё. Это полезно для автоматизации внутренних инструментов компании, кастомных сниппетов с логикой, интеграции с проприетарными системами или публикации open source инструмента.
Где используется
- Внутренние инструменты команды (кодогенерация, шаблоны)
- Языковая поддержка для DSL или специфических форматов
- Интеграция с системами управления задачами (Jira, Linear)
- Open source расширения для Marketplace
Быстрый старт
# Установка yeoman генератора
npm install -g yo generator-code
# Создание заготовки расширения
yo code
# Выбрать: New Extension (TypeScript)
# Название: my-extension
# Идентификатор: my-extension
Структура расширения
my-extension/
src/
extension.ts — точка входа (activate/deactivate)
package.json — манифест расширения
tsconfig.json
.vscode/
launch.json() — конфигурация отладки расширения
package.json расширения
{
"name": "my-extension",
"displayName": "My Extension",
"description": "Что делает расширение",
"version": "0.1.0",
"engines": { "vscode": "^1.85.0" },
"categories": ["Other"],
"activationEvents": ,
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "myExtension.generateComponent",
"title": "Generate React Component"
}
],
"menus": {
"explorer/context": [
{
"command": "myExtension.generateComponent",
"when": "explorerResourceIsFolder"
}
]
},
"keybindings": [
{
"command": "myExtension.generateComponent",
"key": "ctrl+shift+g"
}
]
}
}
extension.ts — основная логика
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
export function activate(context: vscode.ExtensionContext) {
console.log('Extension "my-extension" is now active');
// Регистрация команды
const command = vscode.commands.registerCommand(
'myExtension.generateComponent',
async (uri: vscode.Uri) => {
// Запрос имени у пользователя
const name = await vscode.window.showInputBox({
prompt: 'Имя компонента',
placeHolder: 'Button',
validateInput: (v) => /^[A-Z][a-zA-Z]+$/.test(v) ? null : 'PascalCase',
});
if (!name) return;
// Создаём файл компонента
const folderPath = uri.fsPath;
const filePath = path.join(folderPath, `${name}.tsx`);
const content = generateComponent(name);
fs.writeFileSync(filePath, content, 'utf8');
// Открываем созданный файл
const doc = await vscode.workspace.openTextDocument(filePath);
await vscode.window.showTextDocument(doc);
vscode.window.showInformationMessage(`Компонент ${name} создан`);
}
);
context.subscriptions.push(command);
}
function generateComponent(name: string): string {
return `import React from 'react';\n\nexport function ${name} {\n return <div>${name}</div>;\n}\n`;
}
export function deactivate() {}
Отладка расширения
F5 в папке расширения — открывает Extension Development Host
Все изменения → Ctrl+R в Extension Host для перезагрузки
Ctrl+Shift+P → выбрать свою команду для тестирования
Публикация
npm install -g @vscode/vsce
# Сборка .vsix для локальной установки
vsce package
# Публикация в Marketplace (нужен Azure DevOps Personal Access Token)
vsce publish
Частые ошибки
- Не регистрируют команду в
contributes.commandspackage.json — она не видна в UI - Не возвращают Disposable из subscriptions — утечка памяти при деактивации
activateвызывается при каждом открытии редактора — тяжёлая инициализация замедляет старт- Нет
deactivate— ресурсы не освобождаются при отключении расширения