Task Objectives
- This Skill is used for: creating custom Webview interfaces and implementing features deeply integrated with VSCode
- Capabilities include: Webview Panel, message passing, lifecycle management, local resource loading, CSP security policy
- Trigger conditions: when the user needs to create a custom UI interface or implement complex interactive features
Prerequisites
- Environment requirements: completed the vscode-extension-basics-skill learning
- Prerequisite knowledge: HTML/CSS/JavaScript fundamentals
Operation Steps
Standard Process
1. Create a Webview Panel
const panel = vscode.window.createWebviewPanel(
'catCoding', // viewType 标识符
'Cat Coding', // 面板标题
vscode.ViewColumn.One, // 显示位置
{
enableScripts: true,
localResourceRoots: [vscode.Uri.joinPath(context.extensionUri, 'media')]
}
);
panel.webview.html = getWebviewContent();
2. Set the Webview HTML content
function getWebviewContent() {
return `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; img-src https:; script-src 'self';">
<title>My Webview</title>
</head>
<body>
<h1>Hello from Webview</h1>
<div id="content"></div>
</body>
</html>`;
}
3. Send messages from the extension to the Webview
// 扩展端发送
panel.webview.postMessage({ command: 'refactor', text: 'Reduce lines' });
// Webview 端接收
window.addEventListener('message', event => {
const message = event.data;
if (message.command === 'refactor') {
console.log(message.text);
}
});
4. Send messages from the Webview to the extension
// Webview 端发送
const vscode = acquireVsCodeApi();
vscode.postMessage({ command: 'alert', text: 'Bug found!' });
// 扩展端接收
panel.webview.onDidReceiveMessage(message => {
switch (message.command) {
case 'alert':
vscode.window.showErrorMessage(message.text);
break;
}
}, undefined, context.subscriptions);
5. Manage the Webview lifecycle
panel.onDidDispose(() => {
// 清理资源
panel = undefined;
}, undefined, context.subscriptions);
panel.onDidChangeViewState(e => {
if (e.webviewPanel.visible) {
// 恢复状态
}
});
Optional Branches
When local resources need to be loaded
const localPath = vscode.Uri.joinPath(context.extensionUri, 'media', 'cat.gif');
const imageSrc = panel.webview.asWebviewUri(localPath);
When state needs to be persisted
// 在 webview 中保存状态
const vscode = acquireVsCodeApi();
vscode.setState({ count: 10 });
// 恢复状态
const previousState = vscode.getState();
Resource Index
Domain References
-
- When to read: when you need to understand the basic concepts of Webview
- Content: Panel creation, HTML setup, lifecycle
-
references/webview-messaging.md
- When to read: when you need to implement two-way message passing
- Content: postMessage, onDidReceiveMessage, message format
-
references/webview-security.md
- When to read: when you need to ensure Webview security
- Content: Content Security Policy, local resource restrictions, input validation
Notes
Security Best Practices
- Enable Content Security Policy
- Use localResourceRoots to restrict resource access
- Validate and sanitize all user input
Performance Considerations
- Use retainContextWhenHidden with caution (high memory overhead)
- Prefer getState/setState for state persistence
Theme Adaptation
- Use CSS variables to respond to VSCode theme changes
- Support vscode-light, vscode-dark, vscode-high-contrast