| name | vscode-refactor-and-maintenance |
| description | Guidance for refactoring and maintaining VS Code extensions safely across source, contribution metadata, localization, tests, and documentation. |
Skill: Refactoring and Maintenance
Overview
Maintaining and refactoring a VS Code extension requires special care because changes often
span multiple files (package.json, TypeScript source, locale files, tests, and documentation).
This guide provides patterns for safe, incremental changes.
Rename a Command
When renaming a command ID (e.g., ext.oldCommand → ext.newCommand):
-
package.json
contributes.commands[].command
- All
menus.*[].command references
- All
keybindings[].command references
activationEvents (if listed explicitly)
-
src/extension.ts (and any module that calls the command)
vscode.commands.registerCommand('ext.newCommand', ...)
vscode.commands.executeCommand('ext.newCommand', ...)
-
src/test/
vscode.commands.getCommands(true) assertions
- Direct
executeCommand calls
-
README.md — any documentation of the command
-
CHANGELOG.md — note the rename as a breaking change if published
Add a New Configuration Key
- Add to
contributes.configuration.properties in package.json (with %key% placeholder).
- Add the English string to
package.nls.json.
- Add translated strings to all locale files.
- Read the value with
vscode.workspace.getConfiguration('ext').get<Type>('keyName').
- React to changes with
vscode.workspace.onDidChangeConfiguration.
- Add to
README.md configuration table.
- Add to
CHANGELOG.md.
Add a New Language Feature (Provider)
- Create
src/<featureName>Provider.ts implementing the relevant VS Code interface.
- Add
activationEvents entry if needed (usually onLanguage:<id> is already present).
- Register in
activate() with context.subscriptions.push(vscode.languages.register*(...)).
- Add tests in
src/test/.
- Update
README.md features list.
- Add
CHANGELOG.md entry.
Deprecate and Remove a Feature
Safe Deprecation Process
-
Deprecate (current release):
- Mark the setting/command as deprecated in
package.json using deprecationMessage.
- Show a migration notice to users if they use the deprecated feature.
- Keep the feature working.
-
Remove (next major release):
- Remove from
package.json, source, locale files, tests, and README.
- Document the removal in
CHANGELOG.md under the major version.
"ext.oldSetting": {
"type": "string",
"deprecationMessage": "Use 'ext.newSetting' instead. This setting will be removed in v2.0.",
"scope": "resource"
}
Upgrade engines.vscode
When bumping the minimum VS Code version:
- Update
engines.vscode in package.json.
- Update
@types/vscode in devDependencies to match.
- Remove any compatibility shims for APIs now available in the new minimum.
- Update CI workflows to test against the new minimum version.
- Note in
CHANGELOG.md.
Dependency Updates
npm outdated
npm install <package>@latest --save-dev
npm run compile
npm run lint
npm run test
- Keep
@types/vscode version aligned with engines.vscode (^1.x.0 where x matches).
- For security fixes in transitive dependencies, use
overrides in package.json.
- Review
package-lock.json diff carefully before committing dependency updates.
Code Health Patterns
Extracting Reusable Logic
export class FxmlDefinitionProvider implements vscode.DefinitionProvider {
provideDefinition(doc, pos, token) {
}
}
export function findDefinitionTarget(content: string, offset: number): DefinitionTarget | undefined {
}
export class FxmlDefinitionProvider implements vscode.DefinitionProvider {
provideDefinition(doc, pos, token) {
const offset = doc.offsetAt(pos);
const target = findDefinitionTarget(doc.getText(), offset);
if (!target) { return undefined; }
return new vscode.Location(vscode.Uri.file(target.filePath), new vscode.Position(target.line, 0));
}
}
Avoiding God Classes
Keep provider files focused. If a file exceeds ~200 lines, consider splitting:
src/
fxmlParser.ts Pure XML/FXML parsing (no vscode imports)
fxmlDefinitionProvider.ts Thin VS Code adapter
fxmlHoverProvider.ts Thin VS Code adapter
Consistent Error Surfaces
function showExtError(message: string, error?: unknown): void {
const detail = error instanceof Error ? `: ${error.message}` : '';
vscode.window.showErrorMessage(`JavaFX Support: ${message}${detail}`);
}
Refactoring Checklist
Before submitting a refactoring PR:
Upgrade Path: esbuild
When upgrading esbuild, verify:
npm install esbuild@latest --save-dev
npm run package
ls -lh dist/extension.js
Test the packaged extension end-to-end after an esbuild major version upgrade.
References