depends on https://github.com/codeflash-ai/codeflash/pull/688, https://github.com/codeflash-ai/codeflash-internal/pull/1767 --------- Signed-off-by: ali <mohammed18200118@gmail.com> Co-authored-by: Sarthak Agarwal <sarthak.saga@gmail.com>
817 lines
21 KiB
Markdown
817 lines
21 KiB
Markdown
# Complete VSCode Extension Development Guide: Codeflash
|
|
|
|
## Table of Contents
|
|
|
|
1. [Extension Architecture Overview](#extension-architecture-overview)
|
|
2. [Project Structure & Files](#project-structure--files)
|
|
3. [Core Concepts & Technologies](#core-concepts--technologies)
|
|
4. [Detailed Component Analysis](#detailed-component-analysis)
|
|
5. [VSCode Extension APIs Used](#vscode-extension-apis-used)
|
|
6. [Decision Making Process](#decision-making-process)
|
|
7. [Build System & Tooling](#build-system--tooling)
|
|
8. [Extension Lifecycle](#extension-lifecycle)
|
|
|
|
---
|
|
|
|
## Extension Architecture Overview
|
|
|
|
### High-Level Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ VSCode Extension Host │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Extension.ts (Main Entry Point) │
|
|
│ ├── Registers Providers & Commands │
|
|
│ ├── Manages Service Lifecycle │
|
|
│ └── Handles Extension Activation/Deactivation │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Providers (UI Components) │
|
|
│ ├── SidebarProvider (Webview) │
|
|
│ └── CodeLensProvider (Inline Buttons) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Services (Business Logic) │
|
|
│ ├── LSP Service (Language Server Communication) │
|
|
│ ├── Analysis Service (Code Analysis) │
|
|
│ ├── Optimization Service (Code Optimization) │
|
|
│ ├── Diff Service (Diff View Management) │
|
|
│ └── Python Service (Environment Detection) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Utils & Constants │
|
|
│ ├── Logger (Centralized Logging) │
|
|
│ ├── Error Handling │
|
|
│ └── Path Utilities │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Why This Architecture?
|
|
|
|
- **Separation of Concerns**: UI (Providers) separated from business logic (Services)
|
|
- **Testability**: Each service can be tested independently
|
|
- **Maintainability**: Clear boundaries between components
|
|
- **Scalability**: Easy to add new providers or services
|
|
|
|
---
|
|
|
|
## Project Structure & Files
|
|
|
|
### Core Files Analysis
|
|
|
|
#### `package.json` - Extension Manifest
|
|
|
|
```json
|
|
{
|
|
"name": "codeflash",
|
|
"displayName": "Codeflash",
|
|
"description": "Optimize Your Code - Automatically",
|
|
"main": "./dist/extension.js",
|
|
"engines": { "vscode": "^1.98.0" }
|
|
}
|
|
```
|
|
|
|
**Key Decisions:**
|
|
|
|
- **`main`**: Points to compiled JavaScript, not TypeScript source
|
|
- **`engines.vscode`**: Minimum VSCode version required
|
|
- **`activationEvents: []`**: Empty array means activate on any event (modern approach)
|
|
|
|
#### `contributes` Section - VSCode Integration Points
|
|
|
|
```json
|
|
"contributes": {
|
|
"viewsContainers": { /* Custom sidebar container */ },
|
|
"views": { /* Sidebar webview */ },
|
|
"commands": { /* Extension commands */ },
|
|
"menus": { /* Command palette & context menus */ },
|
|
"keybindings": { /* Keyboard shortcuts */ }
|
|
}
|
|
```
|
|
|
|
**Why Each Contribution:**
|
|
|
|
- **viewsContainers**: Creates our own sidebar section (not mixed with Explorer/Git)
|
|
- **commands**: Defines callable actions from command palette
|
|
- **menus**: Controls where commands appear (command palette, context menus)
|
|
- **keybindings**: Provides keyboard shortcuts for power users
|
|
|
|
### TypeScript Configuration
|
|
|
|
#### `tsconfig.json` - Compilation Settings
|
|
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"target": "ES2020",
|
|
"module": "commonjs",
|
|
"lib": ["ES2020"],
|
|
"strict": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Decisions:**
|
|
|
|
- **ES2020**: Modern JavaScript features while maintaining compatibility
|
|
- **commonjs**: Required for Node.js/VSCode extension environment
|
|
- **strict: true**: Enables all TypeScript strict type checking
|
|
|
|
---
|
|
|
|
## Core Concepts & Technologies
|
|
|
|
### 1. Language Server Protocol (LSP)
|
|
|
|
**What is LSP?**
|
|
Language Server Protocol is a standardized way for editors to communicate with language analysis tools.
|
|
|
|
**Implementation in Codeflash:**
|
|
|
|
```typescript
|
|
// src/services/lspService.ts
|
|
export class LspService {
|
|
async startClient(pythonPath: string): Promise<LanguageClient> {
|
|
const client = new LanguageClient(
|
|
LSP_CLIENT_ID,
|
|
LSP_CLIENT_NAME,
|
|
serverOptions,
|
|
clientOptions,
|
|
);
|
|
await client.start();
|
|
return client;
|
|
}
|
|
}
|
|
```
|
|
|
|
**Why LSP?**
|
|
|
|
- **Standardized**: Works with any LSP-compliant language server
|
|
- **Performant**: Separate process handles heavy analysis
|
|
- **Extensible**: Can add new LSP commands easily
|
|
|
|
### 2. Webview API
|
|
|
|
**What are Webviews?**
|
|
Webviews let you display custom HTML/CSS/JavaScript UI within VSCode.
|
|
|
|
**Implementation:**
|
|
|
|
```typescript
|
|
// src/providers/SidebarProvider.ts
|
|
export class SidebarProvider implements vscode.WebviewViewProvider {
|
|
resolveWebviewView(webviewView: vscode.WebviewView) {
|
|
webviewView.webview.html = generateWebviewHtml(/* ... */);
|
|
webviewView.webview.onDidReceiveMessage(this.handleWebviewMessage);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Security Considerations:**
|
|
|
|
- **Content Security Policy**: Prevents XSS attacks
|
|
- **localResourceRoots**: Limits file access
|
|
- **enableScripts**: Explicitly enables JavaScript
|
|
|
|
### 3. CodeLens API
|
|
|
|
**What is CodeLens?**
|
|
CodeLens provides inline actionable information in the editor.
|
|
|
|
**Implementation:**
|
|
|
|
```typescript
|
|
// src/providers/CodeLensProvider.ts
|
|
export class CodeflashCodeLensProvider implements vscode.CodeLensProvider {
|
|
async provideCodeLenses(
|
|
document: vscode.TextDocument,
|
|
): Promise<vscode.CodeLens[]> {
|
|
// Analyze document and return CodeLens items
|
|
return codeLenses;
|
|
}
|
|
}
|
|
```
|
|
|
|
**Why CodeLens?**
|
|
|
|
- **Contextual**: Appears exactly where it's relevant
|
|
- **Non-intrusive**: Doesn't modify the actual code
|
|
- **Discoverable**: Users see optimization opportunities immediately
|
|
|
|
---
|
|
|
|
## Detailed Component Analysis
|
|
|
|
### Extension Entry Point (`src/extension.ts`)
|
|
|
|
#### Activation Function
|
|
|
|
```typescript
|
|
export async function activate(
|
|
context: vscode.ExtensionContext,
|
|
): Promise<void> {
|
|
// 1. Initialize services
|
|
const pythonService = new PythonService();
|
|
const lspService = new LspService();
|
|
|
|
// 2. Start language client
|
|
const client = await lspService.startClient(pythonPath);
|
|
|
|
// 3. Register providers
|
|
const sidebarProvider = new SidebarProvider(context.extensionUri, client);
|
|
const codeLensProvider = new CodeflashCodeLensProvider(
|
|
client,
|
|
analysisService,
|
|
);
|
|
|
|
// 4. Register with VSCode
|
|
context.subscriptions.push(
|
|
vscode.window.registerWebviewViewProvider(SIDEBAR_VIEW_ID, sidebarProvider),
|
|
vscode.languages.registerCodeLensProvider(
|
|
{ language: "python" },
|
|
codeLensProvider,
|
|
),
|
|
);
|
|
}
|
|
```
|
|
|
|
**Key Concepts:**
|
|
|
|
- **ExtensionContext**: Provides extension lifetime management
|
|
- **subscriptions**: Automatic cleanup when extension deactivates
|
|
- **Dependency Injection**: Services receive their dependencies
|
|
|
|
#### Command Registration
|
|
|
|
```typescript
|
|
const optimizeFunctionCommand = vscode.commands.registerCommand(
|
|
"codeflash.optimizeFunction",
|
|
async (uri: vscode.Uri, functionName: string) => {
|
|
await handleOptimizeFunction(uri, functionName);
|
|
},
|
|
);
|
|
```
|
|
|
|
**Command Design Patterns:**
|
|
|
|
- **Async handlers**: All operations are asynchronous
|
|
- **Typed parameters**: Commands receive strongly-typed parameters
|
|
- **Error boundaries**: Each command has error handling
|
|
|
|
### Sidebar Provider (`src/providers/SidebarProvider.ts`)
|
|
|
|
#### Webview Communication Pattern
|
|
|
|
```typescript
|
|
// Extension → Webview
|
|
this.sendMessage({
|
|
type: "updateState",
|
|
payload: { status, message, functionData },
|
|
});
|
|
|
|
// Webview → Extension
|
|
webviewView.webview.onDidReceiveMessage(async (data) => {
|
|
switch (data.type) {
|
|
case "requestAnalysis":
|
|
await this.handleRequestAnalysis();
|
|
break;
|
|
}
|
|
});
|
|
```
|
|
|
|
**Message Types:**
|
|
|
|
- **updateState**: Updates UI state (loading, success, error)
|
|
- **optimizationStarted**: Shows progress overlay
|
|
- **optimizationComplete**: Shows results
|
|
|
|
**State Management:**
|
|
|
|
- **Centralized**: All state changes go through `updateWebviewState`
|
|
- **Reactive**: UI updates automatically when state changes
|
|
- **Persistent**: State survives webview reloads
|
|
|
|
### CodeLens Provider (`src/providers/CodeLensProvider.ts`)
|
|
|
|
#### Function Detection Algorithm
|
|
|
|
```typescript
|
|
private findFunctionPosition(lines: string[], functionName: string): Position | null {
|
|
const isMethod = functionName.includes('.');
|
|
|
|
if (isMethod) {
|
|
const [className, methodName] = functionName.split('.');
|
|
// 1. Find class definition
|
|
// 2. Find method within class
|
|
} else {
|
|
// Find standalone function
|
|
}
|
|
}
|
|
```
|
|
|
|
**Why This Approach?**
|
|
|
|
- **Handles both functions and methods**: Single algorithm for all cases
|
|
- **Line-by-line parsing**: Simple and reliable
|
|
- **Position accuracy**: Returns exact character position for button placement
|
|
|
|
#### CodeLens Refresh Strategy
|
|
|
|
```typescript
|
|
// Refresh triggers
|
|
this._lspClient.onDidChangeState(() => this._onDidChangeCodeLenses.fire());
|
|
vscode.workspace.onDidSaveTextDocument(() =>
|
|
this._onDidChangeCodeLenses.fire(),
|
|
);
|
|
```
|
|
|
|
**Refresh Strategy:**
|
|
|
|
- **LSP state changes**: When language server starts/stops
|
|
- **File saves**: When user saves Python files
|
|
- **Manual refresh**: Via command palette
|
|
|
|
### Services Architecture
|
|
|
|
#### Service Communication Pattern
|
|
|
|
```typescript
|
|
// Service dependencies are injected
|
|
export class AnalysisService {
|
|
constructor(private client: LanguageClient) {}
|
|
|
|
async getOptimizableFunctions(uri: vscode.Uri) {
|
|
return await this.client.sendRequest(
|
|
LSP_COMMANDS.GET_OPTIMIZABLE_FUNCTIONS,
|
|
{
|
|
textDocument: { uri: uri.toString() },
|
|
},
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Design Principles:**
|
|
|
|
- **Single Responsibility**: Each service has one clear purpose
|
|
- **Dependency Injection**: Services receive dependencies in constructor
|
|
- **Interface Segregation**: Services expose minimal public APIs
|
|
|
|
#### Error Handling Strategy
|
|
|
|
```typescript
|
|
try {
|
|
const result = await this.optimizationService.optimizeFunction(
|
|
functionName,
|
|
uri,
|
|
);
|
|
// Handle success
|
|
} catch (error) {
|
|
this.logger.error(`Error optimizing function ${functionName}`, error);
|
|
vscode.window.showErrorMessage(`Failed to optimize ${functionName}`);
|
|
}
|
|
```
|
|
|
|
**Error Handling Layers:**
|
|
|
|
1. **Service Level**: Catch and log errors
|
|
2. **UI Level**: Show user-friendly messages
|
|
3. **Global Level**: Extension-wide error boundaries
|
|
|
|
---
|
|
|
|
## VSCode Extension APIs Used
|
|
|
|
### Core APIs
|
|
|
|
#### 1. Commands API
|
|
|
|
```typescript
|
|
// Register command
|
|
vscode.commands.registerCommand("codeflash.optimizeFunction", handler);
|
|
|
|
// Execute command
|
|
vscode.commands.executeCommand("vscode.diff", originalUri, optimizedUri, title);
|
|
```
|
|
|
|
**Use Cases:**
|
|
|
|
- **User-triggered actions**: Optimize function, refresh analysis
|
|
- **Internal operations**: Open diff view, navigate to function
|
|
|
|
#### 2. Language Features API
|
|
|
|
```typescript
|
|
// CodeLens provider
|
|
vscode.languages.registerCodeLensProvider(selector, provider);
|
|
|
|
// Document selectors
|
|
{ language: 'python', scheme: 'file' }
|
|
```
|
|
|
|
**Selector Strategy:**
|
|
|
|
- **language**: Only Python files
|
|
- **scheme**: Only file system files (not git:// or other schemes)
|
|
|
|
#### 3. Workspace API
|
|
|
|
```typescript
|
|
// File operations
|
|
vscode.workspace.openTextDocument(uri);
|
|
vscode.workspace.fs.writeFile(uri, content);
|
|
|
|
// Event listening
|
|
vscode.workspace.onDidSaveTextDocument(handler);
|
|
```
|
|
|
|
#### 4. Window API
|
|
|
|
```typescript
|
|
// User interaction
|
|
vscode.window.showInformationMessage(message, ...actions);
|
|
vscode.window.withProgress(options, handler);
|
|
|
|
// Editor operations
|
|
vscode.window.showTextDocument(document, options);
|
|
```
|
|
|
|
### Advanced APIs
|
|
|
|
#### 1. Webview API
|
|
|
|
```typescript
|
|
// Security configuration
|
|
webview.options = {
|
|
enableScripts: true,
|
|
localResourceRoots: [extensionUri, nodeModulesUri]
|
|
};
|
|
|
|
// Content Security Policy
|
|
<meta http-equiv="Content-Security-Policy" content="
|
|
default-src 'none';
|
|
script-src ${webview.cspSource} 'nonce-${nonce}';
|
|
style-src ${webview.cspSource} 'unsafe-inline';
|
|
">
|
|
```
|
|
|
|
#### 2. Language Client API (from vscode-languageclient)
|
|
|
|
```typescript
|
|
const client = new LanguageClient(id, name, serverOptions, clientOptions);
|
|
await client.start();
|
|
const result = await client.sendRequest(method, params);
|
|
```
|
|
|
|
---
|
|
|
|
## Decision Making Process
|
|
|
|
### Technology Choices
|
|
|
|
#### 1. TypeScript vs JavaScript
|
|
|
|
**Chosen: TypeScript**
|
|
|
|
**Reasons:**
|
|
|
|
- **Type Safety**: Catches errors at compile time
|
|
- **IDE Support**: Better IntelliSense and refactoring
|
|
- **Maintainability**: Self-documenting code with types
|
|
- **VSCode Standard**: Most VSCode extensions use TypeScript
|
|
|
|
#### 2. ESBuild vs Webpack
|
|
|
|
**Chosen: ESBuild**
|
|
|
|
**Reasons:**
|
|
|
|
- **Speed**: 10-100x faster than Webpack
|
|
- **Simplicity**: Minimal configuration required
|
|
- **Size**: Smaller bundle sizes
|
|
- **Modern**: Built for modern JavaScript/TypeScript
|
|
|
|
#### 3. Webview vs TreeView for Sidebar
|
|
|
|
**Chosen: Webview**
|
|
|
|
**Reasons:**
|
|
|
|
- **Flexibility**: Complete control over UI
|
|
- **Rich Interactions**: Complex UI elements (progress bars, buttons)
|
|
- **Styling**: Custom CSS for branding
|
|
- **Future-proof**: Can add any web technology
|
|
|
|
#### 4. CodeLens vs Decorations for Inline UI
|
|
|
|
**Chosen: CodeLens**
|
|
|
|
**Reasons:**
|
|
|
|
- **Clickable**: CodeLens supports commands, decorations don't
|
|
- **Standard**: Users familiar with CodeLens from other extensions
|
|
- **Semantic**: CodeLens is meant for actionable metadata
|
|
- **Positioning**: Automatically positioned above code
|
|
|
|
### Architectural Decisions
|
|
|
|
#### 1. Service-Based Architecture
|
|
|
|
**Why:**
|
|
|
|
- **Testability**: Services can be unit tested independently
|
|
- **Reusability**: Services can be used by multiple providers
|
|
- **Separation**: UI logic separated from business logic
|
|
|
|
#### 2. LSP Communication
|
|
|
|
**Why:**
|
|
|
|
- **Performance**: Heavy analysis runs in separate process
|
|
- **Language Agnostic**: Same extension could support multiple languages
|
|
- **Standardized**: Uses industry-standard protocol
|
|
|
|
#### 3. Message-Based Webview Communication
|
|
|
|
**Why:**
|
|
|
|
- **Security**: No direct object sharing between contexts
|
|
- **Reliability**: Structured communication reduces bugs
|
|
- **Debuggability**: All messages can be logged
|
|
|
|
---
|
|
|
|
## Build System & Tooling
|
|
|
|
### ESBuild Configuration (`esbuild.js`)
|
|
|
|
```javascript
|
|
const esbuild = require("esbuild");
|
|
|
|
const production = process.argv.includes("--production");
|
|
const watch = process.argv.includes("--watch");
|
|
|
|
const ctx = await esbuild.context({
|
|
entryPoints: ["src/extension.ts"],
|
|
bundle: true,
|
|
format: "cjs",
|
|
minify: production,
|
|
sourcemap: !production,
|
|
platform: "node",
|
|
outdir: "dist",
|
|
external: ["vscode"],
|
|
});
|
|
```
|
|
|
|
**Configuration Explained:**
|
|
|
|
- **bundle: true**: Combines all files into single output
|
|
- **format: 'cjs'**: CommonJS format for Node.js
|
|
- **external: ['vscode']**: VSCode API provided by host
|
|
- **platform: 'node'**: Target Node.js environment
|
|
|
|
### ESLint Configuration (`eslint.config.mjs`)
|
|
|
|
```javascript
|
|
export default [
|
|
{
|
|
files: ["src/**/*.ts"],
|
|
languageOptions: {
|
|
parser: tsParser,
|
|
parserOptions: { project: "./tsconfig.json" },
|
|
},
|
|
rules: {
|
|
"@typescript-eslint/no-unused-vars": "error",
|
|
"@typescript-eslint/no-explicit-any": "warn",
|
|
},
|
|
},
|
|
];
|
|
```
|
|
|
|
### Development Scripts
|
|
|
|
```json
|
|
{
|
|
"dev": "npm run compile && npm run watch",
|
|
"build": "npm run check-types && npm run lint && node esbuild.js",
|
|
"package": "npm run build --production"
|
|
}
|
|
```
|
|
|
|
**Script Strategy:**
|
|
|
|
- **dev**: Development with watch mode
|
|
- **build**: Full build with type checking and linting
|
|
- **package**: Production build with minification
|
|
|
|
---
|
|
|
|
## Extension Lifecycle
|
|
|
|
### 1. Activation Sequence
|
|
|
|
```
|
|
1. VSCode loads extension.js
|
|
2. activate() function called
|
|
3. Services initialized
|
|
4. LSP client started
|
|
5. Providers registered
|
|
6. Commands registered
|
|
7. Extension ready
|
|
```
|
|
|
|
### 2. Runtime Operations
|
|
|
|
```
|
|
User opens Python file
|
|
├── CodeLens provider activated
|
|
├── Analysis service queries LSP
|
|
├── CodeLens buttons appear
|
|
│
|
|
User clicks "Optimize with CF"
|
|
├── Command handler invoked
|
|
├── Optimization service called
|
|
├── Progress indicator shown
|
|
├── Diff service opens results
|
|
└── User accepts/rejects changes
|
|
```
|
|
|
|
### 3. Deactivation Sequence
|
|
|
|
```
|
|
1. deactivate() function called
|
|
2. LSP client stopped
|
|
3. Services disposed
|
|
4. Event listeners removed
|
|
5. Resources cleaned up
|
|
```
|
|
|
|
---
|
|
|
|
## Advanced Concepts
|
|
|
|
### Memory Management
|
|
|
|
```typescript
|
|
export async function deactivate(): Promise<void> {
|
|
// Dispose services in reverse order
|
|
codeLensProvider?.dispose();
|
|
diffService?.dispose();
|
|
await lspService?.stopClient();
|
|
|
|
// Clear references to prevent memory leaks
|
|
codeLensProvider = undefined;
|
|
diffService = undefined;
|
|
}
|
|
```
|
|
|
|
### Error Boundaries
|
|
|
|
```typescript
|
|
// Global error handling
|
|
process.on("uncaughtException", (error) => {
|
|
logger?.error("Uncaught exception", error);
|
|
});
|
|
|
|
// Service-level error handling
|
|
async function handleOptimizeFunction(uri: vscode.Uri, functionName: string) {
|
|
try {
|
|
// Operation
|
|
} catch (error) {
|
|
logger?.error(`Error optimizing function ${functionName}`, error);
|
|
vscode.window.showErrorMessage(`Failed to optimize ${functionName}`);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Performance Optimization
|
|
|
|
```typescript
|
|
// Debounced CodeLens refresh
|
|
private refreshDebounced = debounce(() => {
|
|
this._onDidChangeCodeLenses.fire();
|
|
}, 500);
|
|
|
|
// Lazy loading
|
|
async provideCodeLenses(document: vscode.TextDocument) {
|
|
if (this.client.state !== LanguageClientState.Running) {
|
|
return []; // Early return if not ready
|
|
}
|
|
// Expensive operations only when needed
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Testing Example
|
|
|
|
```typescript
|
|
describe("AnalysisService", () => {
|
|
let service: AnalysisService;
|
|
let mockClient: jest.Mocked<LanguageClient>;
|
|
|
|
beforeEach(() => {
|
|
mockClient = createMockLanguageClient();
|
|
service = new AnalysisService(mockClient);
|
|
});
|
|
|
|
it("should return optimizable functions", async () => {
|
|
mockClient.sendRequest.mockResolvedValue({
|
|
"file:///test.py": ["function1", "Class.method1"],
|
|
});
|
|
|
|
const result = await service.getOptimizableFunctions(testUri);
|
|
|
|
expect(result.status).toBe("success");
|
|
expect(result.functions).toHaveLength(2);
|
|
});
|
|
});
|
|
```
|
|
|
|
### Integration Testing
|
|
|
|
```typescript
|
|
describe("Extension Integration", () => {
|
|
it("should activate successfully", async () => {
|
|
const context = createMockExtensionContext();
|
|
await activate(context);
|
|
|
|
expect(context.subscriptions).toHaveLength(5);
|
|
expect(vscode.commands.registerCommand).toHaveBeenCalled();
|
|
});
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices Applied
|
|
|
|
### 1. Security
|
|
|
|
- **CSP**: Content Security Policy for webviews
|
|
- **Input validation**: All user inputs validated
|
|
- **Resource isolation**: Webview resources restricted
|
|
|
|
### 2. Performance
|
|
|
|
- **Lazy loading**: Components loaded only when needed
|
|
- **Debouncing**: Frequent operations debounced
|
|
- **Caching**: Results cached when appropriate
|
|
|
|
### 3. User Experience
|
|
|
|
- **Progressive disclosure**: Simple UI with advanced features available
|
|
- **Feedback**: Loading states and progress indicators
|
|
- **Accessibility**: Proper ARIA labels and keyboard navigation
|
|
|
|
### 4. Maintainability
|
|
|
|
- **Type safety**: Comprehensive TypeScript types
|
|
- **Documentation**: Code comments and this guide
|
|
- **Testing**: Unit and integration tests
|
|
|
|
---
|
|
|
|
## Common Patterns in VSCode Extensions
|
|
|
|
### 1. Provider Pattern
|
|
|
|
```typescript
|
|
interface MyProvider {
|
|
provideX(document: TextDocument): X[];
|
|
}
|
|
|
|
vscode.languages.registerXProvider(selector, provider);
|
|
```
|
|
|
|
### 2. Command Pattern
|
|
|
|
```typescript
|
|
const command = vscode.commands.registerCommand("extension.action", (args) => {
|
|
// Handle command
|
|
});
|
|
```
|
|
|
|
### 3. Event-Driven Architecture
|
|
|
|
```typescript
|
|
vscode.workspace.onDidChangeTextDocument((event) => {
|
|
// React to changes
|
|
});
|
|
```
|
|
|
|
### 4. Disposable Pattern
|
|
|
|
```typescript
|
|
class MyService implements vscode.Disposable {
|
|
private disposables: vscode.Disposable[] = [];
|
|
|
|
dispose() {
|
|
vscode.Disposable.from(...this.disposables).dispose();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
This guide covers the fundamental concepts and decisions behind building a professional VSCode extension. Each component serves a specific purpose and follows established patterns for maintainability and user experience.
|